> For the complete documentation index, see [llms.txt](https://danila-korotkov.gitbook.io/front-end-patterns/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://danila-korotkov.gitbook.io/front-end-patterns/shablony/elementy-formy/radio.md).

# Radio

![Radio](/files/5LxWozeSzHtO9HDK8e1j)

## Основные данные&#x20;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

### Screenreader

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

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

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

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

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

## Код

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

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

{% tabs %}
{% tab title="Native HTML" %}

```markup
<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>
```

{% endtab %}
{% endtabs %}

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

### Custom Radio

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

* Скрываем нативную радиокнпоку;
* Добавляем иконку взамен стандартной радиокнопки
* Назначить контур фокуса пользовательскому значку

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

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

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

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

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

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

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

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

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

```html
<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:

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

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

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

```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

```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);
   }
}

```

{% hint style="info" %}
Обратите внимание, что необходимо описать все "состояния" кнопки - focus, checked и disabled.
{% endhint %}

## ARIA&#x20;

### aria-hidden

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