Стилизация флажков

Используйте семантический, доступный HTML-код, в котором каждый флажок связан со своим ярлыком, либо путем вложения <input> внутри <label>, либо путем сопоставления атрибута for ярлыка с атрибутом id ввода.

Современный CSS предлагает два подхода к стилизации флажков: настроить внешний вид с помощью accent-color или переопределить представление по умолчанию с помощью appearance: none в элементе <input type="checkbox">.

Настройка нативных объявлений с помощью 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> в качестве интерактивной цели.

Задайте явные относительные размеры для --checkbox-size и --checkbox-icon-size, поскольку appearance: none удаляет размеры браузера по умолчанию. Значок должен быть меньше флажка, чтобы оставалось место для рамки и отступов.

/* 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-атрибута. Установите свойство DOM indeterminate в JavaScript (checkbox.indeterminate = true) и убедитесь, что псевдокласс :indeterminate визуально отличается от состояний :checked и "не выбрано".

  • Нативный (accent-color). Браузер автоматически применяет стиль, используя элемент accent-color (дополнительное правило CSS :indeterminate не требуется).
  • Собственный (appearance: none): замените --checkbox-icon на var(--icon-dash) в .checkbox-custom:indeterminate, как показано выше.
const selectAll = document.querySelector("#select-all");
selectAll.indeterminate = true;

Специальные возможности и взаимодействие

  • РЕКОМЕНДУЕТСЯ использовать :focus-visible вместо :focus для стилизации индикаторов фокуса на настраиваемых флажках, чтобы при навигации с помощью клавиатуры появлялся четкий контур, который не будет отображаться при кликах указателем.
  • НЕ ИСПОЛЬЗУЙТЕ outline: none и не скрывайте индикаторы фокуса на флажках.
  • РЕКОМЕНДУЕТСЯ убедиться, что флажок или его контейнер <label> имеет интерактивную область нажатия размером не менее 44px x 44px, а размер визуального флажка задан в относительных единицах:

    label {
      display: inline-flex;
      align-items: center;
      gap: 0.65rem;
      min-block-size: 44px;
      cursor: pointer;
    }
    
  • РЕКОМЕНДУЕТСЯ использовать вариант стиля :disabled, который снижает непрозрачность и задает cursor: not-allowed, чтобы четко передать неактивное состояние.

Проблемы, о которых следует знать при использовании accent-color

Отрисовка accent-color в браузере может различаться. Для индикаторов, которые обычно отображаются на фоне цвета акцента, например флажков и переключателей, браузеры могут применять разные варианты оформления:

  • Chromium и Firefox обычно выбирают контрастный цвет индикатора.
  • В Safari индикатор может оставаться белым в светлом режиме и черным в темном, а цвет акцента за ним будет меняться. Такая корректировка не всегда обеспечивает достаточный контраст для каждого предоставленного цвета, поэтому протестируйте важные комбинации в Safari, включая светлые и темные цветовые схемы. Не рассчитывайте на то, что Safari автоматически выберет цвет индикатора, обеспечивающий наилучший контраст.

Резервные стратегии

Резервные варианты и поддержка свойства accent-color в браузерах

Свойство accent-color – это прогрессивное улучшение. Браузеры, которые не поддерживают это свойство, будут игнорировать его и использовать цвета интерфейса по умолчанию.

Маски CSS