webew
Войти » Регистрация
 
HTML
CSS

Псевдо-checkbox на чистом CSS без фоновых изображений

24 июня 2017, 16:41

Как сделать красивый стилизованный чекбокс и при этом не написать ни строчки javascript и не искать иконки.

Вот как выглядит код стилизованного чекбокса:

<label>
    <input type="checkbox">
    <span class="pseudocheckbox">а это - стилизованный</span>
</label>
input[type=checkbox] { display: none; }

.pseudocheckbox::before {  
    content: "\00A0";
    display: inline-block;
    box-sizing: border-box;
    width: 20px;
    height: 20px;
    background-color: white;
    border: 2px solid #B0B0B0;
    border-radius: 2px;
    margin-right: 6px;
    vertical-align: baseline;
   
    text-align: center;
    font-family: Arial, sans-serif;
    font-size: 16px;
    line-height: 16px;
    font-weight: bold;
    color: #808080;
}

input[type=checkbox]:checked + .pseudocheckbox::before { content: "\2713"; }

Разберем этот код подробно.

Задействуем <label>

Для начала нужно скрыть сам чекбокс:

input[type=checkbox] { display: none; }

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

<label>
    <input type="checkbox">
    <span class="pseudocheckbox">а это - стилизованный</span>
</label>

Мы, однако, не только поместили текст внутрь <label>, но и обернули его в <span>. Для чего же это нужно?

Селектор соседа и псевдокласс :checked

В CSS есть селектор соседа. Он позволяет применить стили к указанному элементу только в том случае, если прямо перед ним есть некоторый другой элемент. Записывается он с помощью символа + и выглядит, например, вот так:

input[type=checkbox] + span { (правила) }

Вышеуказанная запись означает: применить правила ко всем <span>, перед которыми есть <input type="checkbox">.

С помощью подобного выражения можно провернуть одну хитрость: ограничить предшествующие элементы только теми чекбоксами, которые «включены». Это нам позволит сделать псевдокласс :checked:

input[type=checkbox]:checked + span { (правила) }

Такая запись позволяет визуально выделить конкретно те <span>, которые следуют за включенными чекбоксами. Эффект от такого выделения иллюстрирует простейший пример:

<label>
    <input type="checkbox">
    <span>щелкни по мне</span>
</label>
input[type=checkbox]:checked + span { font-weight: bold; }

Вот как получится:

(Заметим, что <span> вместе с <input type=checkbox> находится внутри <label>, поэтому клик по нему приводит к изменению состояния <input>.)

Селектор в исходном примере выглядит немного по-другому: не
input[type=checkbox]:checked + span, а
input[type=checkbox]:checked + .pseudocheckbox. По такому селектору браузер быстрее найдет нужный элемент: ему легче искать среди элементов класса pseudocheckbox, чем среди всех <span>. Так что класс добавлен для повышения производительности и никакой другой смысловой нагрузки не несет.

Стилизуем ::before

Вернемся к нашей задаче. Нам требуется не выделять сам <span>, а добиться, чтобы слева от него появилось нечто похожее на переключатель. Для этого нам поможет псевдоэлемент ::before.

::before — это способ дописать что-то в элемент непосредственно перед его содержимым средствами CSS.

<div>раз</div>
<div>два</div>
div::before { content: "Это ::before "; }
раз
два

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

.pseudocheckbox::before {  
    content: "\00A0";
    display: inline-block;
    box-sizing: border-box;
    width: 20px;
    height: 20px;
    background-color: white;
    border: 2px solid #B0B0B0;
    border-radius: 2px;
    margin-right: 6px;
    vertical-align: baseline;
   
    text-align: center;
    font-family: Arial, sans-serif;
    font-size: 16px;
    line-height: 16px;
    font-weight: bold;
    color: #808080;
}

content — свойство, необходимое псевдоэлементу, чтобы он проявился. Достаточно даже пустой строки. Но мы используем неразрывный пробел (об этом будет рассказано ниже). Его шестнадцатеричный код — 00A0:

content: "\00A0";

Нужно задать нашему «квадратику» ширину и высоту. Чтобы они подействовали, необходимо также указать display: inline-block; (по умолчанию и ::beforeinline):

display: inline-block;
width: 20px;
height: 20px;

Удобней, чтобы ширина и высота рассчитывались с учетом толщины границ:

box-sizing: border-box;

Которые тут же и укажем вместе с закруглениями для красоты:

border: 2px solid #B0B0B0;
border-radius: 2px;

И добавим небольшой отступ от текста:

margin-right: 6px;

Следует также обратить внимание на выравнивание самого «квадратика» относительно соседнего текста. Одним из подходящих вариантов является выравнивание по базовой линии текста:

vertical-align: baseline;

В случае самого «квадратика» текстом является неразрывный пробел. Если бы текста внутри не было (content: ""), такое выравнивание не подействовало бы. Вот почему в content именно неразрывный пробел, а не пустая строка: выглядят они одинаково, а действуют в данном случае по-разному.

Остальные свойства относятся к переключателю в состоянии «включено».

Состояние «включено» и Unicode-символ «галочка»

Отмеченный переключатель, очевидно, имеет некоторые отличия. Для нас это не проблема, потому что с помощью соседнего селектора можно обращаться не только к самому элементу, но и к его ::before:

input[type=checkbox]:checked + .pseudocheckbox::before { ... }

Отмеченный переключатель обычно имеет внутри «галочку». Здесь нам на помощь приходит разнообразие символов Unicode, которое выходят далеко за пределы собственно букв и цифр. Есть среди этого многообразия и несколько значков для «галочки». Код значка мы запишем в свойство content:

input[type=checkbox]:checked + .pseudocheckbox::before { content: "\2714"; }

В результате «галочка» будет вписана во все «квадратики» рядом с отмеченными чекбоксами, чего мы и добивалсь. Однако, не стоит забывать, что технически такая «галочка» — это обычный текстовый символ, который самостоятельно может и не выглядеть ровно так, как надо, и ему нужно ему в этом немного помочь.

Центрируем по горизонтали:

text-align: center;

В разных шрифтах символ «галочки» может выглядеть немного по-разному, поэтому для ясности выбираем какой-то один и указываем его явно. Также подбираем размер:

    font-family: Arial, sans-serif;
font-size: 16px;

Кроме размера нужно добиться необходимого положения символа внутри квадратика по вертикальной оси. Лучше всего это делать с помощью line-height:

line-height: 16px;

line-height нужно подбирать индивидуально для каждого сочетания размера и семейства шрифта.

При выравнивании по базовой линии текста (vertical-align: baseline) именно значение line-height определеяет, где, собственно, будет нижняя граница текста у «квадратика». Если эти значения у отмеченного и неотмеченного будут отличаться, то они окажутся выровненными по-разному (так может получиться, например, если явно указать line-height только у отмеченного). Поэтому line-height лучше указывать в общем блоке стилей для ::before.

line-height обычно подбирают вместе с font-size, поэтому его удобно иметь в блоке стилей рядом. font-size, в свою очередь, может подбираться вместе с другими параметрами текста. Так что все их удобней перенести в общий блок для ::before, хотя, на первый взгляд, правила стилизации текста там выглядит нелогично, т.к. самого текста нет (content: "").

Напоследок добавим жирность и укажем цвет:

font-weight: bold;
color: #808080;

© Все права на данную статью принадлежат порталу webew.ru. Перепечатка в интернет-изданиях разрешается только с указанием автора и прямой ссылки на оригинальную статью. Перепечатка в печатных изданиях допускается только с разрешения редакции.
Добавить комментарий
© 2008—2017 webew.ru, связаться: x собака webew.ru
Сайт использует Flede и соответствует стандартам WAI-WCAG 1.0 на уровне A.
Rambler's Top100

Реклама: