Стилизация checkbox и radio на CSS

Если вам требуется изменить внешний вид checkbox или radio-кнопок без использования JavaScript, то данная статья это то что вам нужно.

Итак, поехали...

Для начала стилизуем checkbox, для этого нам потребуется создать следующую HTML-разметку

Стилизуем checkbox

HTML

                <label>
<input class="checkbox" type="checkbox" name="checkbox-test">
<span class="checkbox-custom"></span>
<span class="label">Lorem ipsum dolor</span>
</label>

Вся разметка у нас состоит из трех основных элементов, а именно:

.checkbox - реальный чекбокс input[type="checkbox"]
.checkbox-custom - этот элемент я называю - кастомный чекбокс. Ему мы и будем менять внешний вид и позиционировать, как стилизованный чекбокс, ведь реальный чекбокс будет скрыт
.label - текст лейбла, который будет выводится справа от чекбокса

Все эти элементы должны быть обязательно обернуты в тег label, иначе ничего работать не будет.

Кстати, если вам требуется, чтобы по умолчанию, чекбокс был отмечен, то в нашей HTML разметке, для реального чекбокса задайте атрибут checked

CSS

Теперь добавляем CSS стили.

/* Скрываем реальный чекбокс */
.checkbox {
	display: none;
}
/* Задаем внешний вид для нашего кастомного чекбокса. Все обязательные свойства прокомментированы, остальные же свойства меняйте по вашему усмотрению */
.checkbox-custom {
	position: relative;      /* Обязательно задаем, чтобы мы могли абсолютным образом позиционировать псевдоэлемент внютри нашего кастомного чекбокса */
	width: 20px;             /* Обязательно задаем ширину */
	height: 20px;            /* Обязательно задаем высоту */
	border: 2px solid #ccc;
	border-radius: 3px;
}
/* Кастомный чекбокс и лейбл центрируем по вертикали. Если вам это не требуется, то вы можете убрать свойство vertical-align: middle из данного правила, но свойство display: inline-block обязательно должно быть */
.checkbox-custom,
.label {
	display: inline-block;
	vertical-align: middle;
}
/* Если реальный чекбокс у нас отмечен, то тогда добавляем данный признак и к нашему кастомному чекбоксу  */
.checkbox:checked + .checkbox-custom::before {
	content: "";             /* Добавляем наш псевдоэлемент */
	display: block;			 /* Делаем его блочным элементом */
	position: absolute;      /* Позиционируем его абсолютным образом */
	/* Задаем расстояние от верхней, правой, нижней и левой границы */
	top: 2px;
	right: 2px;
	bottom: 2px;
	left: 2px;
	background: #413548;     /* Добавляем фон. Если требуется, можете поставить сюда картинку в виде "галочки", которая будет символизировать, что чекбокс отмечен */
	border-radius: 2px;
}

Если вы базово знаете CSS, то разобраться в данных стилях не составит труда.

Но а для тех, кто еще только учится, я постараюсь объяснить, что именно мы делаем данным CSS кодом.

1. Мы скрываем наш реальный чекбокс. Это мы делаем из-за того, что сам по себе чекбокс нельзя кроссбраузерно стилизовать на чистом CSS. Поэтому мы применяем небольшую уловку, реальный чекбокс скрываем, а кастомный чекбокс (напомню, что это элемент с классом .checkbox-custom), стилизуем так, как нам нужно.

Ввиду того, что наш реальный и кастомный чекбоксы были обернуты в тег label, то теперь если пользователь кликнет по кастомному чекбоксу, тем самым он отметит и наш реальный чекбокс, который скрыт. Таким образом, у нас устанавливается прямая взаимосвязь между реальным и кастомным чекбоксами.

2. Задаем внешний вид для нашего кастомного чекбокса. Ко всем важным свойствам я дал комментарии в приведенном выше CSS, поэтому не буду здесь останавливаться.

3. Это пожалуй самое интересное. Я думаю вы обратили внимание на селектор .checkbox:checked + .checkbox-custom::before

Он задает следующее

Если наш реальный чекбокс отмечен (за этим следит селектор .checkbox:checked), то тогда внутрь нашего кастомного чекбокса мы добавляем псевдоэлемент (за это отвечает .checkbox-custom::before). Данный псевдоэлемент выводится, как квадратик внутри нашего кастомного чекбокса. По данному квадратику мы и можем понять, отмечен чекбокс или нет. Разумеется данный квадратик вы сможете поменять на все что угодно, например на привычную всем "галочку". В данном вопросе CSS нас ничем не ограничивает.

И также мы видим, что селекторы .checkbox:checked и .checkbox-custom::before соединены знаком "+", с его помощью мы по сути задаем отношение, что если реальный чекбокс отмечен, то только лишь в этом случае мы должны добавить псевдоэлемент внутрь кастомного чекбокса, в противном же случае ничего делать не нужно.

Стилизуем radio-кнопки

Процесс стилизации radio-кнопок, аналогичен чекбоксам.

Создаем привычную нам разметку (в данном случае отличаются только названия некоторых классов)

HTML

                <label>
<input class="radio" type="radio" name="radio-test">
<span class="radio-custom"></span>
<span class="label">Lorem ipsum dolor sit amet, consectetur</span>
</label>

CSS

Я добавил в стили указанные выше, новые селекторы, которые относятся как раз к radio-кнопкам.

.checkbox,
.radio {
	display: none;
}
.checkbox-custom,
.radio-custom {
	width: 20px;
	height: 20px;
	border: 2px solid #ccc;
	border-radius: 3px;
	position: relative;
}
.checkbox-custom,
.radio-custom,
.label {
	display: inline-block;
	vertical-align: middle;
}
.checkbox:checked + .checkbox-custom::before,
.radio:checked + .radio-custom::before {
	content: "";
	display: block;
	position: absolute;
	top: 2px;
	right: 2px;
	bottom: 2px;
	left: 2px;
	background: #413548;
	border-radius: 2px;
}
.radio-custom,
.radio:checked + .radio-custom::before {
	border-radius: 50%;
}

Теперь у нас на странице будут нормально работать, как checkbox, так и radio-кнопки.

Как видите, способ достаточно удобный, не требует использования JS и при этом нормально будет реагировать на стандартное поведение формы, например на ее сброс.

Единственный недостаток данного способа - это то, что нам приходится создавать некий пустой элемент .checkbox-custom для чекбоксов и .radio-custom для radio-кнопок. Который внутри себя не содержит никакого смысла с точки зрения HTML, ведь в разметке он валяется, как "мусорный" тег.

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

Добавить комментарий

  • СУПЕР!
    Немного настроил, просто надо выдумывать оригинальные названия классов, а то у меня с такими же характеристиками была другая пара чекбосков и радио)

    CSS:
    .radio1 {display: none}

    .radiobutton1 {
    width: 10px; /* ШИРИНА */
    height: 10px; /* ВЫСОТА */
    border: 2px solid #ccc; /* ОБВОДКА */
    border-radius: 3px;
    position: relative;
    }
    .radiobutton1,
    .label1 {
    display: inline-block;
    vertical-align: middle;
    }

    .radio1:checked + .radiobutton1::before {
    content: "";
    display: block;
    position: absolute;
    top: 2px;
    right: 2px;
    bottom: 2px;
    left: 2px;
    background: #413548;
    border-radius: 2px;
    }
    .radiobutton1,
    .radio1:checked + .radiobutton1::before {
    border-radius: 50%;
    }

    HTML:
    <label>
    <input class="radio1" type="radio" name="rad1">
    <span class="radiobutton1"></span>
    <span class="label1">Option 1</span>
    </label>

    <br>

    <label>
    <input class="radio1" type="radio" name="rad1">
    <span class="radiobutton1"></span>
    <span class="label1">Option 2</span>
    </label>

  • 23.02.2018 18:37

    Все заработало , автор красавчик

  • Метод реализации кастомного чекбокса ужасен. Помещая input внутрь label, а затем скрывая input вы делаете элемент: а) полностью недоступным для людей с ограниченными возможностями, б) элемент не доступен при переходе с клавиатуры даже, если плясать с бубном при такой разметке его никак не сделать доступным с клавиатуры.

    Плохому учите новичков 🙂

  • Прошу прощения за не внимательность, я ошибся. Спутал другое правило. Поиск выдал четыре результата и мне попался — indeterminate checkbox.

  • Без голословности: https://caniuse.com/#search=checked
    — и для ленивых искать.

  • Добрый вечер.
    В паре проектах имел глупость использовать псевдо-класс :checked. На сайте caniuse.com поддержка этого класса не оправдывает себя. iOS Safari ни одна версия его не поддерживает, и с чего вы взяли что в эти 8% (а это несколько миллионов пользователей) не входят БОЛЬШЕЕ количество посетителей сайта/покупателей ? в таком случае конверсия сайта просто вылетит в трубу.
    Я не советую использовать этот всевдо-класс ещё лет 5 минимум, поскольку никто никогда НЕ спешит переходить на новое; человеческий фактор.

    • Здравствуйте.

      Можете подробней объяснить, с чего вы взяли что псевдокласс :checked не поддерживается iOS Safari?
      Вот как раз скрин с caniuse http://joxi.ru/4Ak0wXKFywDZZr
      Там четко видно что данный псевдокласс и многие другие хорошо поддерживаются абсолютным большинством браузеров, в том числе iOS Safari.

      • 14.01.2018 19:27

        В том и дело что ответ сервиса Caniuse меня несколько удивил, поскольку я вспомнил что ранее смотрел поддержку и в htmlbook и в новом их сайте (относительно). Просто невнимательно прочёл к чему относится поддержка. Как выше написал, выдало четыре результата и первым оказался "indeterminate checkbox".

  • Два лишних тэга в разметке, не True.

  • Большое спасибо. Супер!

  • очень помогли, большое спасибо!
    простое и удобное решение, но новичку самому не догадаться

  • Спасибо, вы очень помогли! Очень красивое решение

  • Подскажите пожалуйста, а как сделать так, чтобы при нажатии на квадратик у меня не только появлялся фон или галочка, но еще и текст подсвечивался определенным цветом? Заранее спасибо!

  • хочу выложит картинки и чтоб люди смогли оставит коментарии и отзывы коментарии точно такой как этот у тебя на блоге

  • здравствуйте ,есть у тебя уроки по созданию собственного движка с нуля?я хочу создать свой блог

  • Здравствуйте. Спасибо за статью, интересует продолжение

  • 12.04.2016 13:10

    Ждем продолжения! Спасибо за статью!