dr.Brain

doctor Brain

мир глазами веб-разработчика

CSS: стилизуем радио-кнопки

как стилизовать радио-кнопки с помощью CSS

dr.Brain

время чтения 3 мин.

Photo by Daniel von Appen on Unsplash

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


Содержание


Отключаем предустановленные стили

Кажется, для того чтобы изменить внешний вид списка с радио-кнопками, наиболее логичным вариантом будет использование традиционной html-конструкции:

<input type="radio" name="demo" value="1" id="radio-1" class="form-radio">
<label for="radio-1">Пункт 1</label>
...
<input type="radio" name="demo" value="n" id="radio-n" class="form-radio">
<label for="radio-n">Пункт n</label>

где:

  1. атрибут name неизменен и определяет принадлежность элементов одному списку выбора,
  2. CSS класс .form-radio нужен для сброса предустановленных и определения собственных стилей,
  3. id и for идентичны и уникальны в каждой паре тегов input и label

Итак, переходим к магии CSS:

.form-radio {
    /* Сбрасываем предустановленные параметры */
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    
    /* Определяем собственные параметры */
    ...
}

/* Устанавливаем параметры для выбранного элемента */
.form-radio:checked {
    ...
}

/* Устанавливаем параметры при наведении */
.form-radio:hover {
    ...
}

Теперь чуть подробнее. С помощью свойства appearance: none; мы сбрасываем предустановленные стили элементов input type="radio".

CSS свойство -moz-appearance используется в Gecko (Firefox) для отображения элемента, используя базовые стили платформы на основе темы операционной системы.

Свойство -webkit-appearance используется в браузерах WebKit-based (например, Safari) и Blink-based (например, Chrome, Opera) для того же эффекта.

Затем устанавливаем собственные параметры для радио-кнопок в различных состояниях.

В чем подвох?

Дело в том, что свойство appearance: none; не работает для радио-кнопок в IE 10-11 и Edge, а в других браузерах приводит к различным эффектам, и чем старше версия браузера, тем более непредсказуемым будет результат.

Подробно можно посмотреть на сайтах caniuse и MDN.

Скрываем дефолтные радио-кнопки

Именно поэтому более разумным будет выбор другой схемы размещения HTML-элементов:

<label for="radio-1" class="form-radio-hidden">
    <input type="radio" name="demo" value="1" id="radio-1">
    <span class="radio"></span>
    <span class="text">Пункт 1</span>
</label>

...

<label for="radio-n" class="form-radio-hidden">
    <input type="radio" name="demo" value="1" id="radio-n">
    <span class="radio"></span>
    <span class="text">Пункт n</span>
</label>

<label> устанавливает связь между своим содержимым и элементом формы. Это означает, что нажатие на любой элемент, обернутый в label приведет к изменению состояния радио-кнопки. А это означает, что теперь мы можем скрыть штатные радио-кнопки и стилизовать заменяющие их элементы span class="radio".

Например:

/* Определяем размещение по горизонтали элементов обернутых в label */
.form-radio-hidden{
  display: flex;
  flex-direction: row;
  height: 28px;
  position: relative;
  align-items: center;
}

/* Скрываем штатные радио-кнопки */
.form-radio-hidden input{
  position: absolute;
  opacity: 0;
  display: block;
  height: 0;
  width: 0;
}

/* Устанавливаем параметры элементов, заменяющих штатные радио-кнопки */
.form-radio-hidden .radio{
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  display: inline-block;
  position: relative;
  height: 20px;
  width: 20px;
  border-radius: 20px;
  margin-right: 5px;
  border: 1px solid #999999;
  background-color: #ffffff;
  box-shadow: 0 0 4px 0 rgba(0,0,0,0.1);
  cursor: pointer;
  outline: none;
  box-sizing: border-box;
  transition: .5s all;
}

/* Устанавливаем параметры элементов, заменяющих штатные радио-кнопки при наведении */
.form-radio-hidden:hover .radio{
  background-color: #f9f9f9;
  box-shadow: inset 1px 2px 3px 0 rgba(0,0,0,0.1);
}

/* Устанавливаем параметры элементов, заменяющих штатные выбранные радио-кнопки */
.form-radio-hidden input:checked + .radio{
  border-color: #555;
  background-color: #f9f9f9;
  box-shadow: inset 1px 2px 3px 0 rgba(0,0,0,0.1);
  cursor: default;
}

/* Добавляем декор */
.form-radio-hidden:hover .radio::before, .form-radio-hidden input:checked + .radio::before{
  content: '';
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 8px;
  background-color: #ddd;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}
.form-radio-hidden input:checked + .radio::before{
  background-color: #555;
  box-shadow: 1px 2px 2px 0 rgba(0,0,0,0.2);
}

/* Устанавливаем параметры подписей радио-кнопок */
.form-radio-hidden input + .radio + .text{
  color: #777;
  cursor: pointer;
  font-size: 14px;
  line-height: 1.4;
  font-family: sans-serif;
  margin-right: 10px;
  align-self: center;
}

/* Устанавливаем параметры подписей выбранных радио-кнопок */
.form-radio-hidden input:checked + .radio + .text{
  color: #555;
  cursor: default;
}

Результат можно посмотреть на codepen:

Данный пример работает в IE 10-11 и Edge.


Спасибо за внимание.

Новые публикации

Далее

Категории

О нас

Frontend & Backend. Статьи, обзоры, заметки, код, уроки.