Стилизация чекбоксов и радиокнопок на чистом CSS с фолбеком для старых браузеров
Для того, чтобы оформить чекбоксы и радиокнопки, как того требует дизайн, сегодня не обязательно использовать JavaScript-решения (типа моего плагина jQuery Form Styler), т.к. для этого можно задействовать только CSS, причем с обратной совместимостью для старых браузеров (т.е. не в ущерб юзабилити), которые не поддерживают современные CSS-правила.
Другими словами – в современных браузерах чекбоксы и радиокнопки будут выглядеть красиво, в соответствии с задуманным дизайном, а в старых (это относится к Internet Explorer версии 8 и ниже) они останутся с оформлением “по умолчанию”, характерным для каждой конкретной операционной системы.
Кроме того, сохраняется возможность HTML5-валидации стилизуемых элементов (чего может не быть при использовании JavaScript-плагинов). В современных браузерах ее поддержка – уже давно норма.
Важные особенности
Чтобы всё получилось, важно учитывать следующее:
-
Кроме, собственно, самого тега элемента, который мы хотим красиво оформить (
<input type="checkbox">
или<input type="radio">
), понадобится тег<label>
, благодаря которому переключать элемент можно, кликая на текст, а не только на сам элемент. - Тег
<input>
должен находиться до тега<label>
(в этом случае состояние элемента формы переключается с помощью атрибутаfor
), либо он должен находиться внутри тега<label>
(в этом случае атрибутfor
не нужен, но понадобится тег-обертка для текста).
“Фокус” заключается в использовании псевдоселекторов :checked
и :not
. При этом сам чекбокс или радиокнопка делаются невидимыми, а их эмуляция осуществляется с помощью псевдоэлементов :before
и :after
для тега <label>
или вышеупомянутого тега-обертки.
Стилизация для современных браузеров
Рассмотрим оба вариант расположения стилизуемого элемента формы. Какой из них наиболее удобен – решать вам. Суть от этого не меняется.
Теги чекбокса и радиокнопки находятся перед тегом <label>
В HTML-коде это выглядит следующим образом:
<input type="checkbox" class="checkbox" id="checkbox" />
<label for="checkbox">Я переключаю чекбокс</label>
<input type="radio" class="radio" id="radio" />
<label for="radio">А я переключаю радиокнопку</label>
Еще раз хочу заострить ваше внимание – тег <input>
обязательно должен быть расположен перед тегом <label>
. Если вы поменяете их местами, ничего работать не будет.
CSS-код для чекбокса будет таким:
.checkbox {
position: absolute;
z-index: -1;
opacity: 0;
margin: 10px 0 0 20px;
}
.checkbox + label {
position: relative;
padding: 0 0 0 60px;
cursor: pointer;
}
.checkbox + label:before {
content: '';
position: absolute;
top: -4px;
left: 0;
width: 50px;
height: 26px;
border-radius: 13px;
background: #CDD1DA;
box-shadow: inset 0 2px 3px rgba(0,0,0,.2);
transition: .2s;
}
.checkbox + label:after {
content: '';
position: absolute;
top: -2px;
left: 2px;
width: 22px;
height: 22px;
border-radius: 10px;
background: #FFF;
box-shadow: 0 2px 5px rgba(0,0,0,.3);
transition: .2s;
}
.checkbox:checked + label:before {
background: #9FD468;
}
.checkbox:checked + label:after {
left: 26px;
}
.checkbox:focus + label:before {
box-shadow: inset 0 2px 3px rgba(0,0,0,.2), 0 0 0 3px rgba(255,255,0,.7);
}
CSS-код для радиокнопки будет таким:
.radio {
position: absolute;
z-index: -1;
opacity: 0;
margin: 10px 0 0 7px;
}
.radio + label {
position: relative;
padding: 0 0 0 35px;
cursor: pointer;
}
.radio + label:before {
content: '';
position: absolute;
top: -3px;
left: 0;
width: 22px;
height: 22px;
border: 1px solid #CDD1DA;
border-radius: 50%;
background: #FFF;
}
.radio + label:after {
content: '';
position: absolute;
top: 1px;
left: 4px;
width: 16px;
height: 16px;
border-radius: 50%;
background: #9FD468;
box-shadow: inset 0 1px 1px rgba(0,0,0,.5);
opacity: 0;
transition: .2s;
}
.radio:checked + label:after {
opacity: 1;
}
.radio:focus + label:before {
box-shadow: 0 0 0 3px rgba(255,255,0,.7);
}
С помощью свойств position
, z-index
и opacity
для классов .checkbox
и .radio
мы визуально прячем оригинальные элементы, при этом они остаются на том же самом месте, где будут стилизованные элементы. А с помощью margin
немного смещаем их, чтобы сообщение валидации HTML5 смотрелось гармонично. В зависимости от дизайна чекбокса и радиокнопки этот отступ можно подогнать.
Теги чекбокса и радиокнопки находятся внутри тега <label>
HTML-код в данном случае будет следующим:
<label class="checkbox">
<input type="checkbox" />
<div class="checkbox__text">Я переключаю чекбокс</div>
</label>
<label class="radio">
<input type="radio" />
<div class="radio__text">А я переключаю радиокнопку</div>
</label>
По аналогии с предыдущим вариантом – тег <input>
обязательно должен быть расположен перед тегами с классом .checkbox__text
и .radio__text
.
CSS-код для чекбокса будет таким:
.checkbox input {
position: absolute;
z-index: -1;
opacity: 0;
margin: 10px 0 0 20px;
}
.checkbox__text {
position: relative;
padding: 0 0 0 60px;
cursor: pointer;
}
.checkbox__text:before {
content: '';
position: absolute;
top: -4px;
left: 0;
width: 50px;
height: 26px;
border-radius: 13px;
background: #CDD1DA;
box-shadow: inset 0 2px 3px rgba(0,0,0,.2);
transition: .2s;
}
.checkbox__text:after {
content: '';
position: absolute;
top: -2px;
left: 2px;
width: 22px;
height: 22px;
border-radius: 10px;
background: #FFF;
box-shadow: 0 2px 5px rgba(0,0,0,.3);
transition: .2s;
}
.checkbox input:checked + .checkbox__text:before {
background: #9FD468;
}
.checkbox input:checked + .checkbox__text:after {
left: 26px;
}
.checkbox input:focus + .checkbox__text:before {
box-shadow: inset 0 2px 3px rgba(0,0,0,.2), 0 0 0 3px rgba(255,255,0,.7);
}
CSS-код для радиокнопки будет таким:
.radio input {
position: absolute;
z-index: -1;
opacity: 0;
margin: 10px 0 0 7px;
}
.radio__text {
position: relative;
padding: 0 0 0 35px;
cursor: pointer;
}
.radio__text:before {
content: '';
position: absolute;
top: -3px;
left: 0;
width: 22px;
height: 22px;
border: 1px solid #CDD1DA;
border-radius: 50%;
background: #FFF;
}
.radio__text:after {
content: '';
position: absolute;
top: 1px;
left: 4px;
width: 16px;
height: 16px;
border-radius: 50%;
background: #9FD468;
box-shadow: inset 0 1px 1px rgba(0,0,0,.5);
opacity: 0;
transition: .2s;
}
.radio input:checked + .radio__text:after {
opacity: 1;
}
.radio input:focus + .radio__text:before {
box-shadow: 0 0 0 3px rgba(255,255,0,.7);
}
Стили здесь те же самые, что и в предыдущем способе, только они применяются для других селекторов.
Стилизация с учетом старых браузеров
CSS-код для чекбокса. В комментариях к коду я добавил пояснения касательно браузеров:
/* Cначала обозначаем стили для IE8 и более старых версий
т.е. здесь мы немного облагораживаем стандартный чекбокс. */
.checkbox {
vertical-align: top;
width: 17px;
height: 17px;
margin: 0 3px 0 0;
}
/* Это для всех браузеров, кроме совсем старых, которые не поддерживают
селекторы с плюсом. Показываем, что label кликабелен. */
.checkbox + label {
cursor: pointer;
}
/* Далее идет оформление чекбокса в современных браузерах, а также IE9 и выше.
Благодаря тому, что старые браузеры не поддерживают селекторы :not и :checked,
в них все нижеследующие стили не сработают. В данном случае checked указывается
без двоеточия впереди, почему-то это срабатывает именно так. */
.checkbox:not(checked) {
position: absolute;
z-index: -1;
opacity: 0;
margin: 10px 0 0 20px;
}
.checkbox:not(checked) + label {
position: relative;
padding: 0 0 0 60px;
}
.checkbox:not(checked) + label:before {
content: '';
position: absolute;
top: -4px;
left: 0;
width: 50px;
height: 26px;
border-radius: 13px;
background: #CDD1DA;
box-shadow: inset 0 2px 3px rgba(0,0,0,.2);
transition: .2s;
}
.checkbox:not(checked) + label:after {
content: '';
position: absolute;
top: -2px;
left: 2px;
width: 22px;
height: 22px;
border-radius: 10px;
background: #FFF;
box-shadow: 0 2px 5px rgba(0,0,0,.3);
transition: .2s;
}
.checkbox:checked + label:before {
background: #9FD468;
}
.checkbox:checked + label:after {
left: 26px;
}
.checkbox:focus + label:before {
box-shadow: inset 0 2px 3px rgba(0,0,0,.2), 0 0 0 3px rgba(255,255,0,.7);
}
CSS-код для радиокнопки:
.radio {
vertical-align: top;
width: 17px;
height: 17px;
margin: 0 3px 0 0;
}
.radio + label {
cursor: pointer;
}
.radio:not(checked) {
position: absolute;
z-index: -1;
opacity: 0;
margin: 10px 0 0 7px;
}
.radio:not(checked) + label {
position: relative;
padding: 0 0 0 35px;
}
.radio:not(checked) + label:before {
content: '';
position: absolute;
top: -3px;
left: 0;
width: 22px;
height: 22px;
border: 1px solid #CDD1DA;
border-radius: 50%;
background: #FFF;
}
.radio:not(checked) + label:after {
content: '';
position: absolute;
top: 1px;
left: 4px;
width: 16px;
height: 16px;
border-radius: 50%;
background: #9FD468;
box-shadow: inset 0 1px 1px rgba(0,0,0,.5);
opacity: 0;
transition: .2s;
}
.radio:checked + label:after {
opacity: 1;
}
.radio:focus + label:before {
box-shadow: 0 0 0 3px rgba(255,255,0,.7);
}
Примеры
- Теги
<input type="checkbox">
и<input type="radio">
находятся перед тегом<label>
- Теги
<input type="checkbox">
и<input type="radio">
находятся внутри тега<label>
- Стилизация с учетом старых браузеров
Вот таким несложным образом это и делается. Благодаря данному способу, оформить чекбоксы и радиокнопки с помощью CSS можно так, как вам будет угодно.
Комментарии (105)
С тенями вообще смотрится супер круто! Респектую
Потрясающее решение!
Просто лучшее, что я искал, вот правда. Огромное спасибо за два таких примера. То что нужно
Спасибо большое автору!
Сильно помог)
Хотелось бы продолжения подобной серии статей, к примеру, по input type range с решениями на js для отображения value
Как у чекбокса изменить расстояние смещения маркера?
Если я правильно понял, о чем речь, то у
.checkbox + label:after
свойствоleft
.Огромное спасибо за эти примеры, всё подключил – всё работает с первого раза !!! Как до делаю проект надо будет ссылку на Ваш сайт разместить … !!!
Лучшее решение и объяснение что нашел в ru и com! Спасибо. Теперь стал понимать как это устроено, вместо того, чтобы просто скопипастить.
Спасибо, очень качественно
Я для себя такой вариант сделал использовав данную статью:
День добрый!
Столкнулся со следующей проблемой… В RSForm конструкция вывода и чекбоксов и радиобоксов следующая:
Как в таком случае их стилизовать? Помогите, пожалуйста!
В данном случае через CSS никак.
Жаль! Но все равно спасибо!
Благорадю за красивое и простое решение!
Скажите, а можно сделать так, чтобы текст был перед самим переключателем? Т.к. так, как это выглядит на современных смартфонах.
У
label
поменяйте внутренний отступ с левого на правый и для::before
и::after
позиционирование с левого на правое.Я делал без ::after и ::before, все работает!
Просто лучшее, что я искал, вот правда. Огромное спасибо за два таких примера. То что нужно
Спасибо. Выручили.Все получилось.
Шикарное решение) Автор молодец)
Потрясающе выглядит! Отличная статья, сохранил к себе как мануал.
Спасибо, позновательно
А с каких пор свитч стал чекбоксом?
Благодарю автора за эту статью!
3 дня над задачей сидела! моё спасение!