Простая кастомизация Checkbox и Radio

Вместо вступления

Всем доброго времени суток!

К сожалению, одного только CSS частенько не достаточно, чтобы с легкостью оформить тот или иной элемент формы. Наверное поэтому многие используют штуки вроде Uniform для своих форм. Лично я всегда стараюсь сократить количество Javascript, используемого в подобных целях, поэтому хочу рассказать о совершенно нативном HTML+CSS методе кастомизации радио-кнопок и чекбоксов.

Уверен, что на большая часть специалистов на Хабре, применяют схожие методы, для тех же, кто использует js-библиотеки, вроде Uniform, надеюсь будет полезной эта статья.

Поехали!

Итак, сразу поставим цель: оформить чекбоксы и радио-кнопки, чтобы внешне они были похожи на js-магию Uniform, но сделать это максимально простым, нативным по отношению в HTML и CSS способом, а также избежать применения лишних тегов, сохраняя семантику. Как-то так.

Основная идея строится на нативном «умении» HTML тега label устанавливать связь с определенным элементом формы. Собственно и все, дальше только код.

Разметка

Код
<ul>  
  <li>
  <input id="cfirst" type="checkbox" name="first" checked hidden />
  <label for="cfirst">Checked checkbox</label>
  </li>
  <li>
  <input id="csecond" type="checkbox" name="second" hidden />
  <label for="csecond">Unchecked checkbox</label>
  </li>
  <li>
  <input id="cthird" type="checkbox" name="third" hidden disabled />
  <label for="cthird">Disabled checkbox</label>
  </li>
  <li>
  <input id="clast" type="checkbox" name="last" checked hidden disabled />
  <label for="clast">Disabled checked checkbox</label>
  </li>
</ul>
<ul>  
  <li>
  <input id="rfirst" type="radio" name="radio" checked hidden />
  <label for="rfirst">Checked radio</label>
  </li>
  <li>
  <input id="rsecond" type="radio" name="radio" hidden />
  <label for="rsecond">Unchecked radio</label>
  </li>
  <li>
  <input id="rthird" type="radio" name="radio" hidden disabled />
  <label for="rthird">Disabled radio</label>
  </li>
</ul>


Совершенно нативная разметка. Использование label вместе с input прям как из учебников. Важным моментом является только то, что нужно указывать id для каждого input и for для label, чтобы связать их.

Думаю все заметили использование атрибута hidden, который скрывает сами input элементы, однако благодаря связи с label, мы все еще может манипулировать ими. В результате мы получаем что-то вроде:



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

Оформление

Код
input[type="checkbox"],
input[type="radio"] {
  display:none;  
}
input[type="checkbox"] + label,  
input[type="radio"] + label {
  font: 18px bold;
  color: #444;
  cursor: pointer;
}
input[type="checkbox"] + label::before,
input[type="radio"] + label::before {
  content: "";
  display: inline-block;
  height: 18px;
  width: 18px;
  margin: 0 5px 0 0;
  background-image: url(uniformjs.com/images/sprite.png);
  background-repeat: no-repeat;
}
input[type="checkbox"] + label::before {
  background-position: -38px -260px;  
}
input[type="radio"] + label::before {
  background-position: 0px -279px;
}
input[type="checkbox"]:checked + label::before {
  background-position: -114px -260px;
}
input[type="radio"]:checked + label::before {
  background-position: -108px -279px;
}
input[type="checkbox"]:disabled + label::before {
  background-position: -152px -260px;
}
input[type="checkbox"]:checked:disabled + label::before {
  background-position: -171px -260px;
}
input[type="radio"]:disabled + label::before {
  background-position: -144px -279px;
}
input[type="radio"]:checked:disabled + label::before {
  background-position: -162px -279px;
}​


Тут все так же максимально просто. Используем псевдо-элемент before для того, чтобы показывать наши «виртуальные контролы» и пользователь не заметил подмены. Части спрайта, меняем в зависимости от состояния input'а.

В результате получаем что-то вроде:



Выгода использования подобного подхода по сравнению с тем же Uniform очевидна. Никаких javascript для оформления, никаких лишних тегов, более простая, правильная и семантичная разметка. Такой же способ можно использовать для придания данным элементам более причудливых форм. К примеру, без проблем можно заделать чекбоксы в стиле iPhone не применяя при этом javascript.

Надеюсь для статья будет полезна начинающим верстальщикам и остановит их о использования js-костылей для подобных целей. Спасибо за внимание!

UPD: Как было отмечено данный способ вероятно не будет работать в браузере Safari под платформу iOS из-за досадной ошибки в поддержке html спецификации (ссылка).

  • FalleN

  • 2787

  • 1

  • 200
Теги: CSS, checkbox, Radio

Ссылки на статью:

Похожие статьи: