Кастомизация radiobutton без JS

Однажды, у меня возникла задача, сделать на форме сайта выбор одного из нескольких цветов. Казалось бы, нет ничего проще. Элемент radiobutton, как нельзя лучше, подходит для этой задачи, нужно только чуть-чуть его кастомизировать. Тут-то и начинаются проблемы. Дело в том, что отрисовкой элементов radiobutton и checkbutton управляет не браузер, а ОС. Соответственно, большинство свойств CSS (например, background-color) на них не действует.

В интернете я нашел множество способов кастомизации radiobutton, но все они показались мне слишком сложными, поэтому я решил придумать свой.

Моя идея основана на том факте, что когда пользователь кликает по подписи label, radiobutton переключается. Значит можно кастомизировать не radiobutton, а label.

Рассмотрим пример кода HTML:
<input type="radio" name="color" value="#0000ff" id="blue"/>
<label for="blue" class="blue"></label>
<input type="radio" name="color" value="#00ffff" id="cyan"/>
<label for="cyan" class="cyan"></label>

Здесь нет ничего необычного. Обычные radiobutton и подписи к ним.

Теперь CSS:
// скрываем radiobutton
input[type="radio"]{display: none;}

// кастомизируем label
label{
    width: 20px;
    height: 20px;
}
label.blue{background-color: blue;}
label.cyan{background-color: #00ffff;}

// Для выбранного объекта
input[type="radio"]:checked+label{
    border: black solid 2px;
}

Здесь мы скрываем radiobutton и рисуем, как нам хочется label. Рисуем label для отмеченного состояния input[type="radio"]:checked+label. Всё просто и элегантно.

На этом можно было бы закончить пост, если бы не одно «но».

Пара гнилых помидоров в сторону Apple

Мир был бы хорош и прекрасен, если бы в нём не было одной корпорации у которой особый путь развития. Это корпорация Apple, которая отказывает своим пользователям в праве тыкать по label. В следствии чего, мой способ не работает на iPhone и iPad. Самое интересное, что Safari на Windows пережевывает всё правильно. К сожалению не было под рукой ни одного iMac, чтобы проверить.

Специально для хипстеров пришлось таки применить JS (код рассчитан на использование в связке с jQuery):
    var deviceAgent = navigator.userAgent.toLowerCase();
    var iOS = deviceAgent.match(/(iphone|ipod|ipad)/);
    if (iOS) {
        $('label').click(function (event) {
            $('#' + $(event.target).attr('for')).attr('checked', true).change();
        });
    }


Пример использования

Long Twit — простой сервис, который рендерит текст в картинку и отправляет в Twitter. Можно выбрать цвет текста и фона.
Поделиться публикацией

Похожие публикации

Комментарии 15

    +3
    Вообще-то лейбл работает на iOS, но необходимо к нему дописать атрибут onclick=""
      0
      Обьясните, пожалуйста, как это применять, желательно с примером?
      Или достаточно просто написать пустой атрибут onclick лейблу?
        0
        Достаточно просто добавить onclick="" к лейблу. читать здесь
          0
          Спасибо, своевременно )
      –1
      Да и без jQuery можно обойтись:

      var lLabels = document.getElementsByTagName('label');
      for(var i=0; i < lLabels.length; i++)
      {
      lLabels[i].onclick = function()
      {
      document.getElementById(this.getAttribute('fur')).checked = true;
      };
      }

      Для чекбоксов будет чуть поболее:

      var lChkBox = document.getElementById(this.getAttribute('fur'));
      lChkBox.checked = !lChkBox.checked;
        0
        input{display: none;} — так вы скроете все инпуты.
        input[type=«radio»] — так — радио.
          0
          забыл дописать во второй строке {display: none}
          input[type="radio"] {display: none}
            0
            Я вам даже больше скажу, в реальности надо скрывать не все radiobutton. Я пытался минимализировать пример кода, чтобы донести основную мысль.
              0
              Естественно. Но как по мне, то сухое input{display: none;}, для статьи со столь громким названием, выглядит по-дилетантски.

              Чтобы раскрывать смысл информации, которую хочешь донести, ее важно не сокращать, а упрощать.
            0
            Как в таком случае изменить состояние объекта в зависимости от того выбран он или нет?
            0
            Имхо, вместо этих костылей лучше юзать старый добрый хелпер () и стилизовать его как душе угодно. + поддержка IE6+ тоже не маловажно. Я не прав?
              0
              блин, парсер съел код <span class="helper"></span>
                0
                IE6 не нужен
                0
                В CSS нужно втавить вместо:
                label{ width: 20px; height: 20px; }
                вставить:
                label{ width: 30px; height: 30px; display: inline-block; }

                Без display: inline-block; не отображаются лейблы

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

                Самое читаемое