Пример элемента на gmail:
Беглое гугление не выдало мне готового решения без JavaScript. Точнее, я нашёл парочку, но они предлагали для изменения состояния кликать в конкретное место на переключателе, что совсем неудобно. Хотя в основном предлагают использовать либо свойство DOM
indeterminate
у чекбокса, либо написание компонента на скриптах, начиная с jQuery, заканчивая Angular. Но мне как-то не хотелось ради такой простой задачи подключать JS вообще.Ещё из пожеланий — мне хотелось иметь рабочий кликабельный
label
, а так как состояния три, то чтобы этот label
показывал текущее состояние.Как я это реализовал? В основе — обычные радио-инпуты спозиционированые абсолютно в верхний левый угол. А вся магия заключается в изменении
z-index
в зависимости от текущего выбранного элемента. Кусочек из CSS:.tristate > input[type="radio"]:checked + input[type="radio"] {
z-index: 10;
}
Иконка и текущий лейбл стилизуется подобными правилами:
.tristate > input[type="radio"]:checked + i + label,
.tristate > input[type="radio"]:checked + i + label + label {
display: none;
}
.tristate-checkbox > input[type="radio"]:checked + input[type="radio"] + i {
/* ... */
}
Осталось всё немного застилизовать, и получаем два симпатичных UI-компонента, как на картинке к посту:
Демо на CodePen
Работоспособность проверял в FF, Chrome, IE9+.
UPDATE: Добавил вариант с «крутилкой»:
Комментарии (29)
mggtsnppr
18.08.2016 15:00Стоит заметить, что это не совсем чекбокс. Этот компонент не получится использовать также, как в Gmail.
Это скорее мультипозиционный переключатель — что в общем то тоже клевая штука.
Если его еще оформить в виде крутящейся ручки с рисками, то будет еще круче.
Кстати, я правильно понимаю, что мы не ограничены тремя радиокнопками? И что мы можем сделать 4-х и более позиционные переключатели?PaulZi
18.08.2016 15:33И кстати можно спокойно застилить в виде крутящихся ручек. Это уже вопрос стилизации.
На самом деле по функционалу это всё тот же набор радио-кнопок, просто застилизованный в виде одного элемента.
goodnickoff
18.08.2016 23:20Чекбокс выглядит здорово!
Но если устраивает поддержка IE10+, то использоватьinput type="range"
для второго варианта (ползунка) куда проще и удобнее. Пальцем опять же потягать можно.PaulZi
18.08.2016 23:45Тогда получится наоборот — двигать можно, а щёлкнуть нельзя.
PaulZi
18.08.2016 23:49И как его стилизовать?
goodnickoff
19.08.2016 02:40Для стилизации даже конструктор CSS есть:
http://danielstern.ca/range.css
Обработка клика реализуется парой строк JS. Но, мне кажется, что таскать его куда интуитивнее чем кликать.
PaulZi
19.08.2016 13:45Парой строк js можно и свайп реализовать) Глянул я как это стилизуется — кошмар, сплошные вендорные псевдоэлементы. В общем, главное в моём посте — показать как можно застилить набор radio-инпутов, а применять или нет — это уже каждый сам решает.
MetaDriver
22.08.2016 11:04Прикольно, конечно, запилить всё это на css. Типа ради спорта. На ангуляре будет чуть меньше разметки, и на порядок меньше CSSa. Правда есть микродоза JS (таки пришлось объявить приложение и пустой контроллер)
Пример тут (добавил снизу).
// Встречный ангулар-прикол: классы для вращения не писал, а прямо в разметке забиндил формулы в атрибут style.PaulZi
22.08.2016 11:08Ну я бы не сказал что у вас разметка сильно проще, и CSS много меньше. Сейчас в примере много CSS так как три варианта переключателей реализовано. А так на JS, конечно можно что-то «одной строчкой» сделать, только предварительно несколько десятков килобайт скриптов подключить)
anttoshka
22.08.2016 11:04Аналогично реализовывал переключение форм регистрации/входа. Честно говоря, думал, что эта практика известна =)
ChALkeRx
Волшебно.
Разве что тут ещё и scss не нужен имхо, можно было с тем же успехом воспользоваться чистым css (переменные, например) + пропозалами в него (nesting), но это уже совсем мелочи и вкусовщина, да и фиксится за минуту на месте.
ChALkeRx
А, вот чего ещё — на тач-устройствах, для второго варианта, таскание его делает немного не то, чего может ожидать пользователь (перетаскивание влево из среднего состояния переключает вправо). Интересно, это можно на чистом css починить?
PaulZi
SCSS использовался только для удобства, всегда можно на codepen нажать «View compiled».
На чистом CSS, конечно, свайпы не реализуешь)
ChALkeRx
Не, оно компилирует в унылый css, проще руками переписать c scss на css с нестингом и переменными, чем compiled упорядочивать. =)
delfi
И сразу отмести IE? Пользователям нужен результат, а не красота в коде, увы
ChALkeRx
Так postcss же.
webdev_proxa
А что браузеры уже поддерживают scss? Или я что то не так понял?
PaulZi
Ещё раз scss — лишь для удобства написания, он компилируется в обычный православный CSS. На codepen можно посмотреть компилированный CSS.
ChALkeRx
Переменные — поддерживают: http://caniuse.com/css-variables, но не все и не в таком виде. Спека — кандидат в рекомендацию, (как и
flexbox
, как иcalc()
, как иvw/vh
, как и градиенты, как и многое другое). Полифиллится на стороне сервера через postcss.Нестинг — не поддерживают, спека в черновике: http://tabatkins.github.io/specs/css-nesting/, но она от того же человека из гугла что и переменные выше. У него есть все шансы. Полифиллится на стороне сервера через postcss.
Кроме этого, в цсс довольно много других вкусных штук ожидается (полифиллы, опять же, есть).
scss не поддерживают, но разумные альтернативы его фичам — да.
webdev_proxa
Понятно, спасибо большое.
ImKremen
У переменных спека «Editor’s Draft, 19 August 2016».
А как их полифилят? Они же в браузере на лету могут значения менять.
Как на postCSS такое поведение реализовать https://googlechrome.github.io/samples/css-custom-properties/?
ImKremen
Таки версия 2015 в RC
ChALkeRx
Последняя версия спеки (в данном случае https://drafts.csswg.org/css-variables/) — зачастую Editor’s Draft, и это та самая версия, на которую надо ориентироваться. Там обычно учтены последние замечания. Считайте это «master»-ом =).
Но у этих черновиков в заголовке есть ссылки на последние опубликованные версии, в данном случае это:
Которая и является Candidate Recommendation.
Это справедливо и для других W3С спек: последняя («Editor’s Draft») — основная и самая интересная, а статус смотреть по «Latest published version». Ну, кроме тех, что уже зарелизили, конечно.
ChALkeRx
Согласен, без динамики и скриптов в клиенте — никак.
Под полифиллами я имел ввиду, что оно работает на таком же уровне, как и переменные в scss, о котором был разговор выше. Ответ был в том, что браузеры scss не поддерживают, а вот его фичи — или поддерживают, или планируют, и полифиллятся эти фичи временно на стороне сервера через postcss — то есть получается ничуть не хуже, чем postcss.
Так-то новые возможности css могут давать гораздо больше, чем то, что можно в статике сполифиллить. Те же vh/vw без js не сполифиллить.