퍼블리싱/Javascript

라디오버튼 & 체크박스 커스텀 하기

리또또 2021. 10. 6. 18:11

 

 

 

 

custom-radiobutton & checkbox

...

codepen.io

 

 

 

 

☑️ HTML

<form>
  <fieldset>
    <legend>마케팅 수신동의</legend>
    <label for="radio01">
      <input type="radio" name="radiogroup" value="yes" id="radio01" required>
      <span class="radio-custom"></span> 예
    </label>
    <label for="radio02">
      <input type="radio" name="radiogroup" value="no" id="radio02">
      <span class="radio-custom"></span>아니오
    </label>
  </fieldset>

  <fieldset id="check-options" aria-disabled="true" aria-describedby="check-cont" style="margin-top: 16px;">
    <legend id="check-cont">수신동의 채널 체크</legend>
    <label for="check-email">
      <input type="checkbox" name="checkgroup" value="email" id="check-email" disabled>
      이메일
    </label>
    <label for="check-kakaotalk">
      <input type="checkbox" name="checkgroup" value="kakaotalk" id="check-kakaotalk" disabled>
      카카오톡
    </label>
    <label for="check-sms">
      <input type="checkbox" name="checkgroup" value="sms" id="check-sms" disabled>
      문자
    </label>
    <label for="check-mail">
      <input type="checkbox" name="checkgroup" value="mail" id="check-mail" disabled>
      우편
    </label>
  </fieldset>
</form>

 

 

☑️ CSS

form {
    max-width: 400px;
    margin: 16px auto;
    padding: 32px 24px;
    border: 1px solid #ccc;
    border-radius: 6px;
  }

  fieldset {
    border: none;
    margin-bottom: 40px;
    padding: 0;
  }

  fieldset:last-child {
    margin-bottom: 0;
  }

  legend {
    font-weight: 600;
    font-size: 20px;
    margin-bottom: 0.5em;
    color: #333;
  }
  label {
    display: inline-flex;
    align-items: center;
    margin-right: 20px;
    cursor: pointer;
    font-size: 16px;
    color: #444;
    user-select: none;
  }

  /* 라디오버튼 커스텀 */
  label input[type="radio"]{
    cursor: pointer;
    display: none;
  }

  label input[type="radio"] + .radio-custom {
    position: relative;
    margin-right: 12px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 1px solid #8500b5;
    background: #fff;
  }

  label input[type="radio"]:checked + .radio-custom::before {
    position: absolute;
    display: inline-block;
    content: "";
    top: 2px;
    right: 2px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #8500b5;
  }

  /*  체크박스 커스텀  */
  input[type="checkbox"] {
    margin-right: 12px;
    width: 18px;
    height: 18px;
    cursor: pointer;
    accent-color: #8500b5;
  }

  /* 비활성화 상태 스타일 조금 더 흐리게 */
  fieldset[aria-disabled="true"] label {
    color: #999;
    cursor: not-allowed;
  }

  fieldset[aria-disabled="true"] input {
    cursor: not-allowed;
  }

 

 

☑️ JavaScript

  const consentRadios = document.querySelectorAll('input[name="radiogroup"]');  // 라디오 버튼(이름이 radiogroup인 input radio들)을 모두 선택
  const checkFieldset = document.getElementById('check-options');
  const checkCheckboxes = checkFieldset.querySelectorAll('input[type="checkbox"]');  // 필드셋 내의 모든 체크박스들을 선택합니다.

  consentRadios.forEach(radio => {
    radio.addEventListener('change', () => {  // forEach 함수를 통해 각 라디오 버튼에 대해 change 이벤트 리스너를 준다 -> 라디오 버튼 선택이 바뀔 때마다 작동
      if (radio.value === 'yes' && radio.checked) {  // "예"(value === 'yes')가 선택되고 체크되어 있으면(활성화):
        checkCheckboxes.forEach(cb => cb.disabled = false);  // 이벤트가 발생하면 선택된 라디오 버튼의 값(radio.value)과 체크 여부(radio.checked)를 확인
        checkFieldset.setAttribute('aria-disabled', 'false');  // 모든 체크박스를 disabled = false로 활성화
      } else if (radio.value === 'no' && radio.checked) { // "아니오"(value === 'no')가 선택되고 체크되어 있으면(비활성화 조건):
        checkCheckboxes.forEach(cb => {
          cb.checked = false;
          cb.disabled = true;
        });
        checkFieldset.setAttribute('aria-disabled', 'true'); // aria-disabled 속성을 "true"로 바꿔 그룹이 비활성화임을 보조기술에 알림.
      }
    });
  });
반응형