Stylizowanie pól wyboru

Używaj semantycznego, dostępnego kodu HTML z każdym polem wyboru powiązanym z etykietą, umieszczając element <input> wewnątrz elementu <label> lub dopasowując atrybut for etykiety do atrybutu id pola wejściowego.

Nowoczesny CSS udostępnia 2 sposoby stylizowania pól wyboru: dostosowanie wyglądu natywnego za pomocą accent-color lub zastąpienie domyślnej prezentacji za pomocą appearance: none w elemencie <input type="checkbox">.

Dostosowywanie natywne za pomocą accent-color

Aby uzyskać prosty, spójny z marką styl, który zachowuje renderowanie natywne, działanie klawiatury, sprawdzanie poprawności i wskaźniki zaznaczenia systemu operacyjnego, użyj accent-color.

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

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

W pełni niestandardowy styl dzięki appearance: none

Używaj appearance: none, gdy projekt wymaga kontroli nad kształtem, rozmiarem, stanami lub wskaźnikami pola wyboru. Spowoduje to usunięcie stylu wizualnego reklamy natywnej, ale <input> pozostanie celem interaktywnym.

Ustaw jawne rozmiary względne dla --checkbox-size i --checkbox-icon-size, ponieważ appearance: none usuwa domyślne wymiary przeglądarki. Ikona powinna być mniejsza niż pole wyboru, aby zapewnić miejsce na obramowanie i odstępy.

/* 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;
  }
}

Stan nieokreślony

Stanu nieokreślonego nie można ustawić za pomocą atrybutu HTML. Ustaw właściwość DOM indeterminate w języku JavaScript (checkbox.indeterminate = true) i upewnij się, że pseudoklasa :indeterminate wizualnie różni się od stanu :checked i stanu niezaznaczonego:

  • Natywny (accent-color): automatycznie stylizowany przez przeglądarkę za pomocą elementu accent-color (nie jest wymagana dodatkowa reguła CSS :indeterminate).
  • Niestandardowy (appearance: none): zamień --checkbox-icon na var(--icon-dash) w .checkbox-custom:indeterminate, jak pokazano powyżej.
const selectAll = document.querySelector("#select-all");
selectAll.indeterminate = true;

Ułatwienia dostępu i interakcja

  • UŻYWAJ :focus-visible zamiast :focus do stylizowania wskaźników zaznaczenia w niestandardowych polach wyboru, aby podczas nawigacji za pomocą klawiatury pojawiało się wyraźne obramowanie, które nie będzie widoczne po kliknięciu wskaźnikiem.
  • NIE używaj outline: none ani nie ukrywaj wskaźników zaznaczenia w polach wyboru.
  • ZADBAJ o to, aby pole wyboru lub jego element opakowujący <label> zapewniały interaktywny obszar kliknięcia o rozmiarze co najmniej 44px x 44px, a jednocześnie zachowaj rozmiar pola wyboru w jednostkach względnych:

    label {
      display: inline-flex;
      align-items: center;
      gap: 0.65rem;
      min-block-size: 44px;
      cursor: pointer;
    }
    
  • ZALECANE: podaj wariant stylu :disabled, który zmniejsza krycie i ustawia cursor: not-allowed, aby wyraźnie przekazać stan nieaktywny.

Problemy, o których warto pamiętać podczas używania właściwości accent-color

Renderowanie accent-color w przeglądarce może się różnić. W przypadku wskaźników, które są zwykle wyświetlane na tle w kolorze uzupełniającym, takich jak znaczniki pól wyboru i kropki przycisków opcji, przeglądarki mogą stosować różne rozwiązania:

  • Chromium i Firefox zwykle wybierają kontrastowy kolor wskaźnika.
  • Safari może zachować biały wskaźnik w trybie jasnym lub czarny wskaźnik w trybie ciemnym, zmieniając kolor uzupełniający za nim. Ta korekta nie zawsze zapewnia wystarczający kontrast dla każdego podanego koloru, dlatego przetestuj ważne kombinacje w Safari, w tym zarówno jasne, jak i ciemne schematy kolorów. Nie zakładaj, że Safari automatycznie wybierze kolor wskaźnika, który zapewnia najlepszy kontrast.

Strategie zastępcze

Kreacje zastępcze i obsługa koloru uzupełniającego w przeglądarkach

Właściwość accent-color jest progresywnym ulepszaniem. Przeglądarki, które nie obsługują tej właściwości, zignorują ją i użyją domyślnych kolorów interfejsu.

Maski CSS