От автора: в наши дни вполне возможно создавать собственные чек-боксы, переключатели и радио-кнопки, сохраняя при этом семантичность и доступность. Нам даже не нужна ни одна строка JavaScript или дополнительные элементы HTML! На самом деле в последнее время это стало проще, чем когда либо. Давайте рассмотрим, как это делается.
Вот, что мы получим в конечном итоге:
Все, конечно, стало проще!
Причина заключается в том, что мы можем, наконец, стилизовать псевдо-элементы ::before и ::after для самого тега input. Это означает, что мы можем стилизовать input, и нам не понадобятся дополнительные элементы. Раньше нам приходилось применять div или span, чтобы реализовать индивидуальный дизайн.

Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнееДавайте посмотрим на HTML
Здесь нет ничего особенного. Мы можем стилизовать элемент ввода, используя такой простой HTML:
1 2 3 4 5 6 7 8 |
<!-- Checkbox --> <input type="checkbox"> <!-- Radio --> <input type="radio"> <!-- Switch --> <input type="checkbox" class="switch"> |
Вот и все, что касается HTML, но, конечно, рекомендуется задавать атрибуты name и id, а также соответствующий элемент label:
1 2 3 4 5 6 7 8 9 10 11 |
<!-- Checkbox --> <input type="checkbox" name="c1" id="c1"> <label for="c1">Checkbox</label> <!-- Radio --> <input type="radio" name="r1" id="r1"> <label for="r1">Radio</label> <!-- Switch --> <input type="checkbox" class="switch" name="s1" id="s1"> <label for="s1">Switch</label> |
Начальные стили
Прежде всего, мы проверяем поддержку appearance: none;, в том числе и через вендорные префиксы. Свойство appearance является ключевым, так как оно предназначено для удаления стиля браузера по умолчанию. Если свойство не поддерживается, стили не будут применены, и будут отображаться стили элементов ввода по умолчанию. Это хороший пример прогрессивного улучшения.
1 2 3 4 5 6 7 |
@supports(-webkit-appearance: none) or (-moz-appearance: none) { input[type='checkbox'], input[type='radio'] { -webkit-appearance: none; -moz-appearance: none; } } |
На сегодняшний день appearance — это рабочий проект, но вот как выглядит поддержка. Данные о поддержке браузерами взяты с Caniuse, где вы можете найти более подробную информацию. Число указывает, что браузер поддерживает функцию в этой версии и выше.
Как и в случае ссылок, мы должны рассматривать различные интерактивные состояния элементов формы. Мы учтем это при стилизации:
:checked
:hover
:focus
:disabled
Например, вот как мы можем стилизовать наш переключатель и учесть состояние :checked:

Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнее
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/* The toggle container */ .switch { width: 38px; border-radius: 11px; } /* The toggle knob */ .switch::after { left: 2px; top: 2px; border-radius: 50%; width: 15px; height: 15px; background: var(--ab, var(--border)); transform: translateX(var(--x, 0)); } /* Change color and position when checked */ .switch:checked { --ab: var(--active-inner); --x: 17px; } /* Drop the opacity of the toggle knob when the input is disabled */ .switch:disabled:not(:checked)::after { opacity: .6; } |
Мы используем элемент input как контейнер. Тумблер внутри элемента ввода создается с помощью псевдо-элемента ::after. Опять же, больше не нужна для этого дополнительная разметка!
Если вы откроете стили в демонстрационной версии, то увидите, что мы определяем некоторые пользовательские свойства CSS, потому что это стало удобным способом управления повторно используемыми значениями в таблице стилей:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@supports(-webkit-appearance: none) or (-moz-appearance: none) { input[type='checkbox'], input[type='radio'] { --active: #275EFE; --active-inner: #fff; --focus: 2px rgba(39, 94, 254, .25); --border: #BBC1E1; --border-hover: #275EFE; --background: #fff; --disabled: #F6F8FF; --disabled-inner: #E1E6F9; } } |
Но есть и другая причина, по которой мы используем пользовательские свойства — они хорошо работают для обновления значений в зависимости от состояния элемента! Мы не будем вдаваться в подробности, но вот пример того, как можно использовать пользовательские свойства для разных состояний.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/* Default */ input[type='checkbox'], input[type='radio'] { --active: #275EFE; --border: #BBC1E1; border: 1px solid var(--bc, var(--border)); } /* Override defaults */ input[type='checkbox']:checked, input[type='radio']:checked { --b: var(--active); --bc: var(--active); } /* Apply another border color on hover if not checked & not disabled */ input[type='checkbox']:not(:checked):not(:disabled):hover, input[type='radio']:not(:checked):not(:disabled):hover { --bc: var(--border-hover); } |
Для доступности мы должны добавить собственный стиль фокуса. Мы удаляем обводку по умолчанию, потому что она не может быть закруглена, как и остальные вещи, которые мы стилизуем. Но с помощью радиуса границы вместе с тенью мы можем создать стиль, который работает как обводка.
1 2 3 4 5 6 7 8 9 10 11 |
input[type='checkbox'], input[type='radio'] { --focus: 2px rgba(39, 94, 254, .25); outline: none; transition: box-shadow .2s; } input[type='checkbox']:focus, input[type='radio']:focus { box-shadow: 0 0 0 var(--focus); } |
Также возможно выровнять и стилизовать элемент label, который в HTML следует непосредственно за элементом input:
1 2 |
<input type="checkbox" name="c1" id="c1"> <label for="c1">Checkbox</label> |
1 2 3 4 5 6 7 8 9 10 11 |
input[type='checkbox'] + label, input[type='radio'] + label { display: inline-block; vertical-align: top; /* Additional styling */ } input[type='checkbox']:disabled + label, input[type='radio']:disabled + label { cursor: not-allowed; } |
Надеюсь, вы оценили, как хорошо в наши дни создавать собственные стили элементов форм. Благодаря псевдо-элементам для этого теперь требуется меньше разметки. Это требует менее сложного переключения стилей, благодаря пользовательским свойствам. И это чертовски хорошо поддерживается браузерами, благодаря @supports.
В целом, это гораздо более приятный опыт разработки, чем мы имели в прошлом!
Автор: Aaron Iker
Источник: //css-tricks.com
Редакция: Команда webformyself.

Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Узнать подробнее