체크박스 스타일 지정

<label> 내에 <input>를 중첩하거나 라벨의 for 속성을 입력의 id에 일치시켜 각 체크박스가 라벨과 연결된 의미론적이고 접근성 있는 HTML을 사용합니다.

최신 CSS는 체크박스 스타일을 지정하는 두 가지 접근 방식을 제공합니다. accent-color를 사용하여 기본 모양을 맞춤설정하거나 <input type="checkbox"> 요소에서 appearance: none를 사용하여 기본 표시를 재정의하는 것입니다.

accent-color를 사용한 네이티브 맞춤설정

기본 렌더링, 키보드 동작, 유효성 검사, 운영체제 포커스 표시기를 유지하는 간단하고 브랜드 일관성이 있는 스타일 지정에는 accent-color를 사용하세요.

.checkbox-native {
  accent-color: #1a73e8;

  /* Sizing is controlled via relative units */
  inline-size: 1.25em;
  aspect-ratio: 1;
  margin: 0;
  cursor: pointer;
}

appearance: none를 사용한 완전 맞춤 스타일 지정

디자인에서 체크박스의 모양, 크기, 상태 또는 표시기를 제어해야 하는 경우 appearance: none를 사용합니다. 이렇게 하면 네이티브 시각적 스타일이 삭제되고 <input>가 상호작용 타겟으로 남습니다.

appearance: none는 브라우저의 기본 크기를 삭제하므로 --checkbox-size 및 --checkbox-icon-size의 명시적인 상대 크기를 설정합니다. 체크박스보다 아이콘을 작게 유지하여 테두리와 시각적 패딩을 위한 공간을 확보합니다.

/* Reusable SVG assets */
:root {
  --icon-check: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'></polyline></svg>");
  --icon-dash: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='4.5' stroke-linecap='round' stroke-linejoin='round'><line x1='5' y1='12' x2='19' y2='12'></line></svg>");
}

/* Custom checkbox */
.checkbox-custom {
  --checkbox-size: 1.25em;
  --checkbox-icon-size: 0.7em;

  appearance: none;
  display: inline-grid;
  place-content: center;
  inline-size: var(--checkbox-size);
  aspect-ratio: 1;
  margin: 0;
  border: 2px solid currentColor;
  cursor: pointer;

  &::before {
    content: "";
    inline-size: var(--checkbox-icon-size);
    aspect-ratio: 1;
    background-color: currentColor;
    mask: var(--checkbox-icon) no-repeat center / contain;
    scale: 0;

    @media (prefers-reduced-motion: no-preference) {
      transition: scale 150ms ease;
    }

    @media (forced-colors: active) {
      background-color: CanvasText;
    }
  }

  &:checked {
    --checkbox-icon: var(--icon-check);
  }

  &:indeterminate {
    --checkbox-icon: var(--icon-dash);
  }

  &:is(:checked, :indeterminate)::before {
    scale: 1;
  }

  &:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
  }

  &:disabled {
    cursor: not-allowed;
    opacity: 0.5;
  }
}

불확정 상태

불확정 상태는 HTML 속성을 통해 설정할 수 없습니다. JavaScript에서 indeterminate DOM 속성을 설정하고 (checkbox.indeterminate = true) :indeterminate 가상 클래스가 :checked 및 선택 해제 상태와 시각적으로 구분되도록 합니다.

  • 네이티브 (accent-color): 요소의 accent-color를 사용하여 브라우저에서 자동으로 스타일을 지정합니다(추가 :indeterminate CSS 규칙이 필요하지 않음).
  • 커스텀 (appearance: none): 위에 표시된 대로 .checkbox-custom:indeterminate에서 --checkbox-icon를 var(--icon-dash)로 바꿉니다.
const selectAll = document.querySelector("#select-all");
selectAll.indeterminate = true;

접근성 및 상호작용

  • 권장사항: 커스텀 체크박스의 포커스 표시기 스타일을 지정할 때는 :focus 대신 :focus-visible를 사용하여 포인터 클릭 시 표시되지 않고 키보드 탐색 시 고유한 윤곽선이 표시되도록 합니다.
  • 체크박스에 outline: none를 사용하거나 포커스 표시기를 숨기지 마세요.
  • 권장사항: 체크박스 또는 이를 래핑하는 <label>가 최소 44px x 44px의 대화형 터치 타겟을 제공하도록 하고 시각적 체크박스 크기는 상대 단위로 유지합니다.

    label {
      display: inline-flex;
      align-items: center;
      gap: 0.65rem;
      min-block-size: 44px;
      cursor: pointer;
    }
    
  • 권장사항: 불투명도를 낮추고 cursor: not-allowed를 설정하여 비활성 상태를 명확하게 전달하는 :disabled 스타일 변형을 제공합니다.

accent-color 사용 시 주의해야 할 문제

accent-color의 브라우저 렌더링은 다양합니다. 체크박스 표시 및 라디오 버튼 점과 같이 일반적으로 강조 색상 배경 위에 그려지는 표시기의 경우 브라우저에서 다른 처리를 적용할 수 있습니다.

  • Chromium과 Firefox는 일반적으로 대비되는 표시기 색상을 선택합니다.
  • Safari는 밝은 모드에서 흰색 표시기를 유지하거나 어두운 모드에서 검은색 표시기를 유지하면서 그 뒤의 강조 색상을 수정할 수 있습니다. 이 조정이 제공된 모든 색상에 충분한 대비를 제공하지는 않으므로 Safari에서 밝은 색 구성표와 어두운 색 구성표를 모두 포함하여 중요한 조합을 테스트하세요. Safari가 가장 대비가 좋은 표시기 색상을 자동으로 선택한다고 가정하지 마세요.

대체 전략

accent-color의 대체 및 브라우저 지원

accent-color 속성은 점진적 개선입니다. 이 속성을 지원하지 않는 브라우저는 이를 무시하고 기본 UI 색상을 사용합니다.

CSS 마스크