Стилизация чекбоксов

Я уже рассматривал верстку форм на примере формы обратной связи. Однако некоторые моменты были все же упущены или рассмотрены не до конца. Так что продолжаем подробно вникать в данную тему.

На этот раз рассмотрим стилизацию чекбоксов. Чекбокс, он же флажок, заслуживает отдельной статьи из-за сложностей с оформлением. Конечно в Сети есть множество решений с использованием разнообразных jQuery-плагинов, но все же не всегда целесообразно подключать лишний файл-скрипт, когда можно сделать все обычным CSS и совсем небольшим вкраплением JS или jQuery.

Содержание статьи

  1. Разметка
  2. CSS + jQuery

Разметка

Как и положено, начнем с разметки. Что представляет из себя чекбокс? Это поле <input> для установки галочки напротив какого-либо пункта, оно может быть активно либо неактивно:

<input type="checkbox" name="checkbox-1" value="Я - чекбокс!"> <span>Чекбокс</span>
Чекбокс

Увы, данный элемент не получится стилизовать: нельзя изменить фон, цвет и т.д. Решение — обернуть поле контейнером, убрать прозрачность opacity до нуля (функциональность сохранится), а стили задавать контейнеру. Контейнер мы будем добавлять скриптами jQuery. Почему — узнаете чуть позже.

Сейчас у нас всего лишь один чекбокс, в формах это бывает достаточно редко. Давайте добавим еще несколько, сделаем к примеру выбор нескольких товаров в форме и кнопку «Отправить». Также обернем все наши элементы тегом <label> с атрибутом for, значение которого равно id дочернего поля, чтобы впоследствии при клике на соседний элемент с текстом поле тоже становилась активным или неактивным. Польза от этого очевидна:

Еще я использую <div class="divider"> в качестве разделителей строк. Вот такая разметка получилась у меня в итоге:

<form action="#" id="user-form" class="user-form">
  <fieldset>
    <legend>Выбор товара</legend>
    <div class="divider">
      <label for="check-1">
        <input type="checkbox" id="check-1" class="element-checkbox" name="check-1" value="Портфель"><
        <span>Портфель</span>
      </label>
    </div>
    <div class="divider">
      <label for="check-2">
        <input type="checkbox" id="check-2" class="element-checkbox" name="check-2" value="Чемодан">
        <span>Чемодан</span>
      </label>
    </div>
    <div class="divider">
      <label for="check-3">
        <input type="checkbox" id="check-3" class="element-checkbox" name="check-3" value="Саквояж">
        <span>Саквояж</span>
      </label>
    </div>
    <input type="submit" id="submit-form" class="submit-btn" value="Отправить">
  </fieldset>
</form>

CSS + jQuery

Итак, теперь наша главная задача — скрыть чекбоксы применением opacity, добавить скриптами обертку .wrap-checkbox и применить на нее оформительские стили — добавить фон, изменить размеры и т.д., причем на два состояния — активное и неактивное.

Разберемся со скрытием стандартных полей. Можно конечно просто скрыть элементы, прописав opacity в файле стилей, однако так мы делать не будем, а воспользуемся скриптами. Почему?

  1. Первое и самое главное — в случае выключенного JavaScript у браузера, которым мы будем делать активным или неактивным наш псевдочекбокс <span>, поле станет недоступным — обертка не будет работать, а поле останется прозрачным. В случае же добавления opacity скриптом мы такой проблемы не получим — если JS будет выключен, то будет доступен стандартный чекбокс. Необходимо заботиться о пользователе с выключенным JS
  2. Второе — не нужно будет дополнительно прописывать фильтр opacity для Internet Explorer из-за непонимания этим браузером css-свойства opacity (характерно для IE<9). jQuery сам добавит его автоматически

Как видите — одни плюсы, поэтому смело пишем код:

// прозрачность для всех полей-чекбоксов на странице
$('input[type=checkbox]').css({'opacity': 0});

А теперь обернем поле:

// добавили обертку для элементов
$('input[type=checkbox]').css({'opacity': 0}).wrap('<span class="wrap-checkbox"></span>');

Опять же, добавляем обертку скриптами затем, чтобы при выключенном JS были доступны стандартные чекбоксы.

Отлично, поля стали невидимыми, можно приступать к оформлению обертки. На просторах Сети я нашел вот такой простенький вариант дизайна чекбокса:

checkbox
Стильный чекбокс — готовый спрайт

Такие изображения естественно лучше всего сделать спрайтом. Теперь применим стили и зададим стили для нашей обертки .wrap-checkbox, предусматривая два варианта — неактивное и активное поле (пропишем стили для класса .active):

.wrap-checkbox {
  background: url(images/checkbox.png) no-repeat 0 0;
  display: block;
  float: left;
  height: 26px;
  width: 26px;
}
.wrap-checkbox.active {
  background: url(images/checkbox.png) no-repeat -26px 0; /* изменяем background-position при активном чекбоксе */
}

Теперь добавим еще немного jQuery — при на клике на элемент-обертку будем переключать у него класс .active:

$('.wrap-checkbox').click(function() {
  $(this).toggleClass('active'); /* переключатель класса .active */
})

Отлично, вообщем-то теперь все готово, остальные стили чисто оформительские и к нашей задачи прямого отношения не имеют. Единственное, что еще хотелось бы отметить — запрет выделения при клике на тег <label>. При множественных кликах текст будет выделяться, я отменил это поведение для улучшения юзабилити формы:

label {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
}

Для запрета выделения в Internet Explorer ниже девятой версии необходимо добавить атрибут unselectable со значением on:

<!-- запретили выделение в IE<9 -->
<span unselectable="on">Здесь невыделяемый текст</span>

Итоги

Как видите, немного труда и мы получили отличный работающий чекбокс, который можно смело применять в ваших формах. Единственный недостаток, на который я пока не нашел решения — это невозможность выделять пункты табами, т.к. псевдокласс :focus работает с ограниченным числом элементов (<a>, <input>, <select> и <textarea>).

Проверено

  • Internet Explorer 7+
  • Opera
  • Firefox
  • Google Chrome
  • Safari

Рейтинг статьи

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

Комментарии читателей

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

  2. Андрей:

    Не могли бы вы сделать нечто подобное для элементов форм select и file

    • Здравствуйте, Андрей!
      Я про вас не забыл, но пока не хватает времени допилить скрипт и статью. Вообще для стилизации селектов существует множество jQ плагинов, если интересно: http://habrahabr.ru/company/aiken/blog/114927/.
      Также простое решение на чистом JS можно найти в учебнике Ильи Кантора: http://learn.javascript.ru/play/tutorial/widgets/customselect/index.html. Если кратко, суть в том, что <select> и <option> подменяются контейнером со вложенным списком — и на JS мы делаем имитацию поведения стандартного селекта.

      • Все таки для стилизации радикнопок и чекбоксов лучше юзать css3 (так как это по современному) и не надо думать над атрибутом checked

        селекты вобще лучше не юзать.. я использую dl и скрытый инпут это намного проще да и оформляется просто, в js всего лишь два клика описываешь и селект работает

        • Привет! Кто заглянул)
          Да, да, не спорю, писал давненько и надо все выбросить и переписать под нынешние реалии.
          Когда сам возобновишь статьи писать?)

  3. Спасибо за статью оказалась очень полезной.

  4. Артем:

    Ужаснейший чекбокс.
    Т.к не реагирует на checked=»checked».
    Т.е если вы хотите изначальне сделать флажок зажатым, с помощью этого скрипта у вас не чего не получиться.

    • Да, согласен, недоработка, но это несложно поправить — нужно добавить проверку на наличие активных флажков и присвоить соответствующим элементам класс .active

  5. Такой Чекбокс действительно хорошо бы подошел к моему блогу. А видео об айчтиэмель 5 подняло настроение. Наверно переводчиком переводили.

  6. Круто! А переключатели тоже можно подобным образом стилизировать?

    • Да, Ирина, по смыслу там примерно тоже самое, единственное различие будет в коде JS. Т.к. активный радиобатон может быть только один, необходимо делать проверку на наличие класса .active у элементов <input type=»radio»>, и при клике на неактивный радио убирать .active у предыдущего.

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