x
 
Алёна Бибикова
25 октября 2018
Советы почтой каждую неделю
Пожалуйста, получите наше письмо, чтобы подтвердить свой адрес:
Вы подписаны на «Советы за неделю»:

Руст, на живых советах вы рассказывали о том, как сверстать такие чекбоксы и радиокнопки без яваскрипта, но у меня не сохранилась запись. Напомните, пожалуйста.


Для начала раз­ме­тим чекбокс:

<label>
  <input type="checkbox" checked /> Чек­бокс
</label>

К сожа­ле­нию, сам чек­бокс сти­ли­зо­вать невоз­можно, поэтому мы спря­чем насто­я­щий чек­бокс, доба­вим вспо­мо­га­тель­ный span и сти­ли­зуем его. Для этого вос­поль­зу­емся псев­до­клас­сом :checked, ука­зы­ва­ю­щим на состо­я­ние чек­бокса, и селек­то­ром +, поз­во­ля­ю­щим выбрать сосед­ний элемент:

/* html */
<label>
  <input class="checkbox" type="checkbox" />
  <span class="fake-checkbox"></span> Чек­бокс
</label>
/* css */
label {
  display: block;
  cursor: pointer;
}
​
.checkbox { 
  display: none;
}
​
.fake-checkbox { 
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 2px solid #3c7e5e;
  /* Выров­няем по тек­сту */
  vertical-align: middle;
  margin-top: -2px;
  margin-right: 4px;
}
​
/* ".checkbox:checked" сра­ба­ты­вает
когда checkbox отме­чен, а 
"+ .fake-checkbox" выби­рает сле­ду­ю­щий 
эле­мент с клас­сом fake-checkbox */
.checkbox:checked + .fake-checkbox {
  background: #3c7e5e;
}

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

/* css */
​
/* ... */
​
/* Вме­сто самого эле­мента, выбе­рем 
псев­до­эле­мент с помо­щью "::before" */
.checkbox:checked + .fake-checkbox::before {
  content: "✓";
  font-size: 35px;
  color: #3c7e5e;
  /* Выров­няем галочку */
  display: block;
  margin-top: -10px;
}

Если галка в вашем шрифте не под­хо­дит, можно под­клю­чить для неё дру­гой шрифт:

/* css */
​
.checkbox:checked + .fake-checkbox::before {
  /* ... */
  font-family: Bureausans;
}

Если галка нестан­дарт­ная, можно под­ста­вить картинку:

/* css */
​
/* ... */
​
.fake-checkbox::before {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  background: url("circle.png") no-repeat center / contain;
}
​
.checkbox:checked + .fake-checkbox::before {
  background-image: url("filled-circle.png");
}

Напо­сле­док, чтобы кар­тинка не мигала при пер­вом клике, вме­сто изме­не­ния ссылки на кар­тинку будем менять види­мый элемент:

/* css */
​
/* ... */
​
.fake-checkbox {
  position: relative;
}
​
​/* Доба­вим вто­рой эле­мент и 
раз­ме­стим их друг над дру­гом */
.fake-checkbox::before,
.fake-checkbox::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: url("circle.png") no-repeat center / contain;
}
​
/* Вто­рому эле­менту поме­няем кар­тику
и спря­чем его про­зрач­но­стью */
.fake-checkbox::after {
  background-image: url("filled-circle.png");
  opacity: 0;
}
​
/* Для отме­чен­ного чек­бокса поме­няем 
про­зрач­ность эле­мен­тов на про­ти­во­по­лож­ные */
.checkbox:checked + .fake-checkbox::before {
  opacity: 0;
}
​
.checkbox:checked + .fake-checkbox::after {
  opacity: 1;
}
P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.
Вёрстка и прототипирование — дисциплина Школы дизайнеров. Набор весной. Оставьте почту, и мы напишем вам, когда откроется следующий набор.
 

Поделиться
Отправить

Комментарии

Александр Глевский
25 октября 2018

Руст,

Сафари при активации чекбокса выделяет и текст. Можно ли это победить?


25 октября 2018

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

Тем не менее можно воспользоваться user-select: none, но в этом случае вы запретите выделение полностью.

Евгений Закурдаев
25 октября 2018

Спан избыточен, псевдоэлементы могут быть у лейбла.
Ставить слэш в одиночных тегах — моветон, XHTML давно умер.

Юрий Хан
25 октября 2018

А дальше для всего вот этого надо решать кучу неинтересных задач.

* Скрытый чекбокс недоступен с клавиатуры.
* Скрытый чекбокс не читается скринридером.
* Галочка уезжает из квадрата, если пользователь запретил загрузку шрифтов и/или выставил себе отличный от дефолтного интерлиньяж.
* PNG-картинка расплывается на HiDPI-мониторе (если верстальщик не положил заранее картинку двойного размера).

Дмитрий Олляк
25 октября 2018

У предложенного решения неприятный побочный эффект — такой чекбокс недоступен с клавиатуры. Это важно не только для пользователей с ограниченными возможностями. Но и в больших формах, админках, где удобно скакать по инпутам табом. Хороший (в смысле плохой) пример — чекбоксы в админке Битрикса. Это боль.

Чтобы кастомный чекбокс был доступен с клавиатуры, надо как-то оставить штатный чекбокс в DOM и добавить стиль на кастомный чекбокс с помощью :focus. Небезупречный пример реализации: https://codepen.io/Ollyak/pen/wYRaOw

Максим Самойлов
28 октября 2018

Присоединяюсь к Юрию и Дмитрию — получившийся чекбокс недоступен с клавиатуры и для скринридеров.
Как скрыть чекбокс правильно, можно почитать в справке к ally.js Родни Рейма: https://allyjs.io/tutorials/hiding-elements.html

Макс Савченко
30 октября 2018

Чекбокс с клавиатуры будет доступен, но только не нужно его скрывать через `display:none`.
Достаточно добавить прозрачность, абсолютно спозиционировать над фэйковым боксом и отключить пользовательские события `pointer-events: none`. Только не выносите его на северный полюс как в примере у Димы ↑ — `left: -100000px`.
Это кстати ещё необходимо чтобы показывались браузерные ошибки валидации.

Евгений Закурдаев, без элемента нельзя будет стилизовать состояния инпута.


Цель рубрики — обсуждение вопросов дизайна всех видов, текста в дизайне и взаимоотношений дизайнеров с клиентами.

Мы публикуем комментарии, которые добавляют к уже сказанному новые мысли и хорошие примеры. Мы ожидаем, что такие комментарии составят около 20% от общего числа.

Решение о публикации принимается один раз; мы не имеем возможности комментировать или пересматривать свое решение, хотя оно может быть ошибочно. Уже опубликованные комментарии могут быть удалены через некоторое время, если без них обсуждение не становится менее ценным или интересным.

Вот такой веб 2.0.

Как устроена беспарольная аутентификация почтой Как вы проверяете соответствие вёрстки макету 2 Как спрятать экранную клавиатуру в Айфоне?




Недавно всплыло

Как вести себя с человеком, который Джима Кемпа не читал и вину не признаёт? 2 10 Как избежать «эффекта Тильды»? 2 3