Настраиваемые radio/checkbox с идеальным выравниванием в CSS CSS radio/checkbox с идеальным выравниванием

Узнайте, как создавать настраиваемые доступные radio и checkbox в CSS, которые идеально совпадают с их метками.

Создание настраиваемых radio/checkbox - непростая задача. Они должны быть доступными, легко настраиваемыми и идеально согласованными с этикетками.

ДЕМО

HTML

Важное правило, которого я стараюсь придерживаться при создании компонентов, - начинать с простейшей структуры и добавлять дополнительные элементы (например, обертывание родителей) только в случае необходимости.

Вот все, что нам нужно для кнопок radio и checkbox:


<!-- radio button -->
<div>
  <input class="radio" type="radio" name="radio-button" id="radio-1">
  <label for="radio-1">Choice 1</label>
</div>

<!-- checkbox button -->
<div>
  <input class="checkbox" type="checkbox" id="checkbox-1">
  <label for="checkbox-1">Option 1</label>
</div>

Структура HTML идентична той, которую мы использовали бы с собственными кнопками, за исключением того, что мы добавляем класс .radio / .checkbox к вводу.

CSS

Шаг 1 - визуально скрыть нативные кнопки:


.radio,
.checkbox {
  position: absolute;
  margin: 0 !important;
  padding: 0 !important;
  opacity: 0;
  height: 0;
  width: 0;
  pointer-events: none;
}

Если вы не установите значения top / right / bottom / left для элементов абсолютной позиции, они удаляются из потока, но не перемещаются. Это важно, потому что в противном случае их положение будет непредсказуемым и может привести к прокрутке вверх страницы при нажатии кнопок.

Затем мы собираемся использовать + (соседний комбинатор-близнец) для нацеливания и стилизации меток и их псевдоэлементов ::before (настраиваемые кнопки):


.radio + label,
.checkbox + label { 
  user-select: none;
  cursor: pointer;
  line-height: 1.4;
}
.radio + label::before,
.checkbox + label::before { 
  content: '';
  display: inline-block;
  width: 18px;
  height: 18px;
  background-color: #FFF;
  border: 2px solid #DBDBDB;
  margin-right: 10px;
  transition: .2s;
}

.radio + label::before {
  border-radius: 50%; 
}

.checkbox + label::before {
  border-radius: 4px;
}

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

Мы собираемся настроить таргетинг на проверенный статус входов и применить стиль к псевдоэлементам меток:


.radio:checked + label::before,
.checkbox:checked + label::before {
  background-color: #1a73e8;
  box-shadow: none;
  border-color: #1a73e8;
  transition: transform 0.2s;
}

.radio:active + label::before,
.checkbox:active + label::before {
  transform: scale(0.8);
  transition: transform 0.2s;
}

.radio:checked:active + label::before,
.checkbox:checked:active + label::before {
  transform: none;
  transition: none;
}

.radio:checked + label::before {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cg class='nc-icon-wrapper' fill='%23ffffff'%3E%3Ccircle cx='8' cy='8' r='8' fill='%23ffffff'%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");
  background-size: 10px;
}

.checkbox:checked + label::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpolyline points='1 6.5 4 9.5 11 2.5' fill='none' stroke='%23FFFFFF' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'/%3E%3C/svg%3E");
  background-size: 10px;
}

Мы используем свойство background-image для добавления маркеров SVG (через URI данных). Преимущество этого метода заключается в том, что вы можете настроить толщину значка (stroke-width = '2') и его цвет (stroke='%23FFFFFF') в CSS.

Что у нас есть на данный момент:

Настраиваемые radio/checkbox


Выравнивание

А вот и самая сложная часть: совместить кнопки переключателей / флажков с их метками.

Сначала установите свойство display метки равным inline-flex и align-items равным flex-start:


.radio + label,
.checkbox + label { 
  display: inline-flex;
  align-items: flex-start; 
  line-height: 32px;
}

.radio + label::before,
.checkbox + label::before { 
  flex-shrink: 0; 
  margin-right: 10px; 
}

Таким образом, мы устранили проблему выравнивания по левому краю, видимую, когда метка разбивается на несколько строк, и мы выровняли кнопки и метки по вертикали вверху:

CSS radio/checkbox с идеальным выравниванием

Чтобы выровнять кнопки и метки по вертикали, нам нужно вычислить высоту метки, которая равна размеру шрифта, умноженному на высоту строки.

настройка radio и checkbox с идеальным выравниванием

Вычисленное значение font-size для метки непредсказуемо (например, мы могли бы изменить его с помощью служебных классов), но для псевдоэлемента label ::before этот font-size всегда будет равен 1em!

Зная высоту, мы можем использовать формулу для нажатия настраиваемых кнопок переключателя / флажка на очень конкретную величину, которая выравнивает их с первой строкой метки. 🤯


.radio + label::before,
.checkbox + label::before {
  position: relative;
  top: 1em;
}

Больше никаких случайных и непредсказуемых уловок с отрицательной маржой! 🎉


Доступность

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

настройка radio и checkbox

Однако не забудьте включить эффект: focus (собственные кнопки не видны):


.radio:focus + label::before,
.checkbox:focus + label::before {
  border-color: #1a73e8;
  box-shadow: 0 0 0 3px rgba(26, 115, 232, .3);
}

Просмотр окончательного результата:

Выполнено! 🎉


Top

🔖 Выбор по тегам ×

💌 Написать сообщение ×

Все поля обязательны для заполнения!