Управление формой с помощью CSS-свойства currentColor и псевдо-элементов

Все это возможно благодаря тому, что CSS-свойство currentColor и псевдо-элементы отлично работают в паре.

Недавно начал экспериментировать с этим свойством, и осознал, что оно может быть очень полезным. Некоторые утверждают, что это первая реализованная в CSS-переменная:

Я подумал, что можно создать собственные контроллеры для формы при помощи псевдо-элементов и currentColor. И решил оформить радиокнопки и чекбоксы.

Посмотреть демо

Разметка

Разметка радиокнопок и чекбоксов включает в себя Label, в который оборачивается элемент ввода и нужный текст. Как вы уже наверняка знаете, при вкладывании элементов управления html друг в друга улучшается их юзабилити, и вам не придется использовать id:

<label class="form-group">
  <input type="checkbox">
  <span class="form-control checkbox">
    Orange
  </span>
</label>

Разметка радиокнопки выглядит следующим образом.

Стили

Далее я постараюсь объяснить практически каждое правило CSS, которое используется в этом примере.

Общие стили

Свойство box-sizing: border-box является одним из самых простых способов реализации:

: *,
*:before,
*:after {
  box-sizing: border-box;
}

К Label, который оборачивает чекбокс, радиокнопку и текст, применяется .form-group. В этом стиле используется указатель, так как он дополняет юзабилити нашего элемента, сообщая пользователю, что к этому элементу можно применить действие. user-select: none; не является стандартным свойством CSS, и его действие в будущем может измениться.

На данный момент, это эффективный способ запретить выделение текста при помощи CSS:

.form-group {
  cursor: pointer;
  line-height: 1;
  user-select: none;            
}

В данном случае, мы изменяем радиокнопки и чекбоксы при помощи псевдо-элементов, поэтому «родные» элементы управления формы нам нужно скрыть. Далее представлен наиболее подходящий способ сделать это, так как здесь не используются display: none или visibility: hidden, которые обычно отрицательно сказываются на удобстве всего интерфейса:

.form-group > [type="checkbox"],
.form-group > [type="radio"] {
  position: absolute; 
  overflow: hidden; 
  clip: rect(0 0 0 0); 
  height: 1px; width: 1px; 
  margin: -1px; padding: 0; border: 0; 
}

Теперь переходим к CSS-правилам, которые подготавливают «почву» к последующим действиям. У .form-control выставлено относительное позиционирование, так как его псевдо-элементы будут иметь абсолютное позиционирование.

Я думаю, вы обратили внимание на единицы измерения em. Их использование позволяет контроллерам формы изменяться в размерах в зависимости от выбранного значения font-size:

Общие стили
.form-control {
  display: inline-block;
  position: relative;
  padding-left: 1.3em;
}

.form-control::before,
.form-control::after {
  content: '';
  position: absolute;
  left: 0;
}        

.form-control::before {
  width: 1em;
  height: 1em;
  border: .1em solid;
}

.form-control::after {
  top: .1em; left: .1em;
  width: .8em; height: .8em;
}

Чекбокс

Здесь основной трюк заключается в использовании мнемоника (сущности) HTML check, в юникоде представленного под номером U+2714. Для чекбоксов, и радиокнопок мы будем использовать родственные селекторы, чтобы получить функционал переключения.

Все остальное будет реализовано при помощи CSS:

.form-control.checkbox::before {
  border-radius: .1em;
}

.form-control.checkbox::after {  
  text-align: center;          
  content: "2714";
  line-height: .8em;                   
  opacity: 0;
  transform: scale(.5);
  transition: transform .1s ease;
}

.form-group > .form-control.checkbox:hover::after {
  opacity: .4;
}

.form-group > input:checked + .form-control.checkbox::after {
  opacity: 1;
  transform: scale(1);       
}

Радиокнопка

Для радиокнопки формы, мы используем свойство border, которое позволит нам добиться желаемого эффекта. Также добавим border-radius, чтобы получить закругленные углы, и background-clip, чтобы исключить выход фона за пределы границы.

В этом примере главным свойством является currentColor, в котором отражено высчитанное значение цвета элемента. Позже мы будем использовать JavaScript для случайного вывода цветов, чтобы посмотреть, как изменяются цвета элементов управления формы:

.form-control.radio::before,
.form-control.radio::after {
  border-radius: 50%;
}

.form-control.radio::after {
  background-color: currentColor;
  background-clip: padding-box;
  border: .2em solid transparent;
  opacity: 0;
  transition: border .1s ease;
}

.form-group >.form-control.radio:hover::after {
  opacity: .4;          
}            

.form-group > input:checked + .form-control.radio::after {
  border-width: .1em;
  opacity: 1;         
}

Небольшой JS-сниппет

Ради эксперимента я решил использовать PleaseJS – JavaScript-библиотеку для случайного вывода цветов. Только не забудьте несколько раз подряд обновить страницу с демо, чтобы увидеть эффект:

var formControl       = document.querySelectorAll('.form-group'),
    formControlLength = formControl.length,
    pleaseColor       = Please.make_color({
      colors_returned: formControlLength,
      saturation: 1,
      value: .9
    });

for (var i = 0; i < formControlLength; i++) {
  formControl[i].style.color = pleaseColor[i];
};

Поддержка браузерами

Этот пример не будет работать в устаревших браузерах ниже IE8. С другой стороны, эффект отлично работает в современных браузерах и смартфонах. Также хотелось бы узнать ваше мнение относительно этой статьи.

РедакцияПеревод статьи «Form controls with CSS currentColor and pseudo elements»