Radio

Элемент управления для хранения данных формы с одним выбором.

Radio

Основные данные

Основной ресурс откуда взята информация - https://ebay.gitbook.io/mindpatterns/input/radio

Позволяет выбрать один элемент в группе параметров. Если требуется множественный выбор, используйте вместо этого флажки или список. HTML дает нам встроенные переключатели, которые полностью доступны по умолчанию. К сожалению, внешний вид этих элементов управления часто расходится с дизайном веб-сайта или рекомендациями по брендингу. Эта проблема усугубляется тем фактом, что стиль стандартных переключателей очень сложно изменить. Этот шаблон показывает, как используя современные CSS и SVG можно создать "фасад" над встроенными переключателями, при сохранении требований доступности.

Лучшая практика

Радиокнопки должны быть сгруппированы вместе, и группа должна содержать не менее двух радиокнопок.

Каждая группа переключателей должна быть помечена. Обычно достигается с помощью тега.

Каждая отдельная радиокнопка должна быть помечена. Другие типы интерактивного элемента управления (например, текстовое поле или флажок) не должны вкладываться между переключателями.

Радиокнопки должны находиться в элементе формы, и этот элемент формы должен иметь кнопку отправки.

Переключение переключателя не должно вызывать перезагрузку страницы, всплывающее окно или любое изменение контекста до тех пор, пока соответствующая форма не будет явно отправлена пользователем.

Интерактивный дизайн

Управление клавиатурой

При переходе в группу фокус будет установлен на выбранный в данный момент переключатель.

Если ни одна кнопка в данный момент не отмечена, фокус переместится к первой или последней кнопке в зависимости от того, использовались ли TABили SHIFT + TAB для входа в группу. TABи SHIFT + TAB покинут группу радиокнопок.

СТРЕЛКА ВНИЗ будет фокусироваться и выбрать следующую кнопку в группе.

СТРЕЛКА ВВЕРХ будет фокусироваться и выбрать предыдущую кнопку в группе.

ENTER отправляет форму, к которой принадлежит радиогруппа.

Screenreader

Радио должно быть доступно с помощью программы чтения с экрана (даже если она отключена).

Радио должно быть объявлено как «Радио».

Лейбл радио должен быть объявлен.

Название радиогруппы должно быть объявлено.

Состояние радио должно быть объявлено (т.е. отмечено или не отмечено флажком).

Код

Нативные переключатели на 100% доступны по умолчанию и поддерживают такие функции, как данные формы, сброс формы и завершение формы.

Нативные переключатели HTML всегда должны быть вашей базовой отправной точкой.

<fieldset>
  <legend>Listing Format</legend> 
  <span>    
    <input id="lf_all" type="radio" name="lf" value="all" />
    <label for="lf_all">All Listings</label>
  </span>
  <span>
    <input id="lf_auction" type="radio" name="lf" value="auction" />
    <label for="lf_auction">Auction</label>
  </span>
  <span>
    <input id="lf_bin" type="radio" name="lf" value="bin" />
    <label for="lf_bin">Buy it Now</label>
  </span>
</fieldset>

Fieldset создает семантику группировки. Legend создает метку группы. Каждая пара ввода и метки дополнительно группируется внутри контейнера span. Этот контейнер span можно заменить на div для вертикального размещения переключателей.

Custom Radio

Что будем делать:

  • Скрываем нативную радиокнпоку;

  • Добавляем иконку взамен стандартной радиокнопки

  • Назначить контур фокуса пользовательскому значку

<span class="radio">
  <input class="radio__control" id="lf_all" type="radio" name="lf" value="all" />
  <!-- icon goes here -->
</span>

Скрываем нативную радиокнопку

.radio__control {
  opacity: 0;
  position: absolute;
  z-index: 1;
}

Скрываем таким образом, чтобы мы могли продолжать нажимать на него. Несмотря на то, что он невидим, это все же собственный ввод, который получает события щелчка и фокусировки. Это важно, чтобы базовый ввод поддерживал всю встроенную обработку событий и состояние. Помните, что нажатие метки переключателя также переключает отмеченное состояние.

Добавляем кастомную иконку

Нам понадобится два значка: отмеченный и снятый.

Иконки в качестве background:

<span class="radio">
  <input id="lf_all" type="radio" name="lf" value="all" />
  <span class="radio__icon"></span>
</span>

Иконки в качестве элемента:

<span class="radio">
  <input id="lf_all" type="radio" name="lf" value="all" />
  <span class="radio__icon" hidden>
    <svg aria-hidden="true" class="radio__unchecked" focusable="false">
      <use xlink:href="#icon-radio-unchecked"></use>
    </svg>
    <svg aria-hidden="true" class="radio__checked" focusable="false">
      <use xlink:href="#icon-radio-checked"></use>
    </svg>
  </span>
</span>

Эта разметка предполагает, что на странице существуют определения символов для # icon-radio-unchecked и # icon-radio-checked. Атрибут hidden гарантирует, что значок SVG не будет виден, если страница находится в состоянии, отличном от CSS; это также помогает предотвратить появление нестилизованного содержимого (FOUC). Как видите, фоновая разметка SVG более лаконична, однако у нее есть две основные проблемы, о которых следует помнить: цвет значка не может быть изменен с помощью CSS; для режима высокой контрастности Windows необходимы альтернативные варианты. С другой стороны, SVG переднего плана не имеет ни одной из этих проблем, и поэтому это наш предпочтительный подход.

Костамизируем состояние фокуса

Помните, что клавиатура всегда будет фокусироваться на реальном, собственном вводе. Однако мы не можем увидеть настоящий индикатор фокуса, потому что у элемента 0 непрозрачность. Чтобы обойти это, мы можем создать настраиваемый контур фокуса вокруг элемента SVG:

.radio__control:focus + .radio__icon {
  outline: 1px dotted #767676;
}

Пунктирная граница - хороший выбор, имитирующий границы различных браузеров (например, Firefox).

Мой вариант разметки html:

<fieldset class="radio-input">
   <legend class="radio-input__legend">Формат файла (fileType)</legend>
   <label class="radio-input__inner" for="withTotal">
      <input class="radio-input__control" id="withTotal" type="radio" name="fileType" value="withTotal" />
      <span class="radio-input__icon"></span>
      <div class="radio-input__text">С полем "Итог"</div>
   </label>
   <label class="radio-input__inner" for="withoutTotal">
      <input class="radio-input__control" id="withoutTotal" type="radio" name="fileType" value="withoutTotal" />
      <span class="radio-input__icon"></span>
      <div class="radio-input__text">Без поля "Итог"</div>
   </label>
</fieldset>

И scss

.radio-input {
   border: none;
   padding: 0;
   margin: 0;
   width: rem(250);
   &__legend {
      padding-bottom: rem(10);
   }

   &__inner {
      display: flex;
      align-items: center;
      border: rem(1) solid var(--color-primary);
      border-radius: var(--size-border-radius);
      margin-bottom: rem(5);
   }

   &__control {
      opacity: 0;
      position: absolute;
      z-index: 1;
   }
   
   &__control:focus + &__icon-wrapper > &__icon {
      outline: rem(5) solid var(--color-auqa-island);
   }

   &__control:checked + &__icon-wrapper > &__icon {
      background-color: var(--color-primary);
      border: rem(3) solid var(--color-black-haze);
   }
   
   &__control[disabled] + &__icon-wrapper > &__icon {
      outline: rem(5) solid var(--color-error);
   }

   &__icon {
      display: inline-block;
      width: rem(15);
      height: rem(15);
      outline: rem(1) solid var(--color-primary);
      border-radius: 50%;
      background-color: var(--color-black-haze);
   }
   
   &__text {
      padding-left: rem(10);
   }
}

Обратите внимание, что необходимо описать все "состояния" кнопки - focus, checked и disabled.

ARIA

aria-hidden

Удаляет презентационный элемент SVG из дерева доступности.

Last updated

Was this helpful?