0,0
рейтинг
6 апреля 2013 в 19:08

Разработка → Стильный CSS переключатель без JavaScript из песочницы tutorial

HTML*, CSS*
Здесь я покажу, как сделать переключатель на основе input-а на чистом CSS.


Демо
Все файлы


Для начала, надо сказать, что у input типом checkbox есть такая особенность:
если он выбран (галочка стоит), то элементу присваивается новый атрибут checked.
На этом эффекте и будет построен наш элемент.

Для начала, опишем сам инпут и обертку
<div class="switcher">
	<input id="sw" type="checkbox" class="switcher-value">
	<label for="sw" class="sw_btn"></label>
	<div class="bg"></div>
</div>


В качестве ползунка будем использовать элемент label, так как он жестко привязывается по ID к конкретному инпуту. То есть нажал на label — считай, кликнул и поставил галочку в input.

Див с классом bg — это просто задний фон.

Опишем основные стили
.switcher {
	width: 124px;
	height: 49px;
	cursor: pointer;
	position: relative;
}
.switcher * {
	transition: all .2s;
	-moz-transition: all .2s;
	-webkit-transition: all .2s;
	-o-transition: all .2s;
	-ms-transition: all .2s;
}
.switcher .sw_btn {
	background: url('btn.png') 0% 0% no-repeat;
	width: 49px;
	height: 49px;
	display: block;
	cursor: pointer;
	z-index: 1;
	position: relative;
}
.switcher .bg { background: url('bg-off.png') 0% 0% no-repeat; }
.switcher input.switcher-value { display: none; }
.switcher .bg {
	width: 100%;
	height: 100%;
	position: absolute;
	top: 0;
	left: 0;
	z-index: 0;
}


Как видно из кода, сам инпут мы скрываем. Он нам нужен только как хранитель значений.
(кстати, получить значение нашего будущего переключателя можно как значение этого самого инпута)

На фон ставим картинку с выключенного переключателя ('bg-off.png):


Так же установим свойство transition для плавности переключений.

А теперь — самое интересное
.switcher input.switcher-value:checked ~ .sw_btn { margin-left: 68px; }
.switcher input.switcher-value:checked ~ .sw_btn ~ .bg { background: url('bg-on.png') 0% 0% no-repeat; }


Эти две строчки и переключают =)

Первая строка означает, что внешний отступ станет 68px у элемента с классом sw_btn,
который следует сразу за ВКЛЮЧЕННЫМ инпутом (об этом нам сообщает :checked).
А вторая, что надо сменить фон для элемента с классом .bg, следующего за элементом с классом sw_btn,
который идет сразу за ВКЛЮЧЕННЫМ инпутом.
Для выключенного инпута эти 2 свойства не работают.

Весь код
.switcher {
	width: 124px;
	height: 49px;
	cursor: pointer;
	position: relative;
}

.switcher * {
	transition: all .2s;
	-moz-transition: all .2s;
	-webkit-transition: all .2s;
	-o-transition: all .2s;
	-ms-transition: all .2s;
}

.switcher .sw_btn {
	background: url('btn.png') 0% 0% no-repeat;
	width: 49px;
	height: 49px;
	display: block;
	cursor: pointer;
	z-index: 1;
	position: relative;
}

.switcher .bg { background: url('bg-off.png') 0% 0% no-repeat; }
.switcher input.switcher-value:checked ~ .sw_btn { margin-left: 68px; }
.switcher input.switcher-value:checked ~ .sw_btn ~ .bg { background: url('bg-on.png') 0% 0% no-repeat; }
.switcher input.switcher-value { display: none; }
.switcher .bg {
	width: 100%;
	height: 100%;
	position: absolute;
	top: 0;
	left: 0;
	z-index: 0;
}



Вот так, с помощью пары небольших трюков и поллитра кофе, можно создать интересный переключатель без нагромождения javascript-анимациями страницу.
Алексей Беспалов @alex_coder
карма
13,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (40)

  • +26
    Круто, конечно. Но его хочется потянуть, а этого нельзя сделать.
    • +50
      А мне наоборот: тянуть не хочется, но хочется, чтобы он переключался, даже если нажать на пустую область, а не только на саму кнопочку.
      • +6
        Да, и все потому, что на всем переключателе курсор — pointer. Стоит сделать pointer только для label и переключатель будет намного понятнее. А вообще идея просто отличная.
    • +1
      В таком случае уже нужен JS
      • –4
        почему?
        • 0
          Сделайте переключатель без JS
  • +8
    Обычный переключатель. Кстати, блюр обрезается.
  • +19
    Непонятно почему нужно нажимать именно на шестиугольник, а не на весь переключатель?
    Подсветка лампочки обрезанная, а должна быть круглая :)
  • +22
    Я делал такое, тоже CSS, только без картинок cssdeck.com/labs/hp17u02i а pepelsbey еще раньше с SVG pepelsbey.net/2012/08/stylish-switch/
    • +8
      Оба варианта намного интереснее, чем в статье. Как с точки зрения логики (клик в любом месте), так и с точки зрения реализации в целом. Отличные примеры.
  • 0
    Сразу бросилось в глаза, что свечение на бэкграунде обрезано справа.
  • 0
    Таки действительно бросилось в глаза обрезанное свечение, да и не сразу въехал, что нажимать можно не на весь чекбокс. А так вообще, классно. Пока неочень понял как оно плавно работает, позже поковыряю transition
  • +1
    Лично я на блок не кликал, все таки кликабельную часть сделать лучше всей, а не конкретный участок.
  • 0
    Зеленый свет обрезается справа(
  • +5
    А у меня он при первом клике моргнул (картинка подгружалась), используйте спрайты.
  • –8
    ie8 и младше не поддерживают
    • +14
      Странно, да?
    • +10
      В Links тоже не работает. Не понимаю, куда смотрит автор?
  • +1
    Нужно картинки для такого делать спрайтами… Иначе первый раз исчезает фон при переключении.
  • +1
    Раз в месяц кто-нибудь пишет на хабр пост о переключателе на чистом css.
    http://pepelsbey.net/2012/08/stylish-switch/
  • 0
    Элегантно! Голь на выдумку хитра :-). Но для реализации всего ожидаемого пользователям функционала и удобства потребуется всё это выбросить и написать с нуля, используя javascript.
  • +2
    Поставьте, пожалуйста, свойства без префикса последними в списке — это важно. Почему? Ответ в статье Мейера про префиксы, ближе к концу: Префикс или постхак.
  • 0
    Какой же это «чистый CSS» — если картинки в бэкграунде используются? Формулировка «чистый CSS» обычно как раз и подразумевает отсутствие изображений.
  • 0
    Красиво, конечно, но слишком уж громоздко. Для личной странички или портфолио отлично, а на практике напоминает 2000-е.
  • 0
    > input.switcher-value { display: none; }

    focus — нет, не слышал

    Делайте инпут прозрачным, а не недоступным.
  • 0
    jsfiddle.net/axwNY/ накидал за пару мин пример получше имхо (стили можно нанизывать уже любые… и без картинок можно обойтись)
    • 0
      Ну вот, а могли бы статью! :)
      • +3
        бред — писать статью про это…
        • 0
          Ну, почему же — по-моему, ваш пример выглядит гораздо более стильно, чем то, что представлено в посте.
    • –1
      input:before в firefox не работает
      • 0
        То, что это где-то работает — явно баг. Псевдоэлементы :before и :after существуют в контексте элемента, а что может быть внутри input?
        • 0
          Круче только псевдоэлементы внутри img
  • 0
    как сделать переключатель на основе input-а на чистом CSS.

    А слабо по-настоящему на чистом CSS сделать такое, без картинок то бишь?
  • 0
    Эх, можно бы было такое для конструкции вида:
    <label><input type="checkbox"/></label>
    

    Поскорее бы в CSS возможность выбирать предков элемента.
  • 0
    По-моему, лучший на сегодня — lea.verou.me/2013/03/ios-6-switch-style-checkboxes-with-pure-css/
    Плюс там используется интересный способ отсева старых браузеров — стили сделаны для чекбокса с псевдоклассом :root
    • 0
    • +1
      Поддерживаю, лучше еще и потому, что поддерживает фокус и изменение пробелом. Все остальные (включая уважаемого pepelsbey) забывают что по элементам еще можно (и иногда удобнее) перемещаться без мыши.
      • +2
        Обновил пост, теперь пример с чекбоксом реагирует на таб и слушается пробела, а вот с радиокнопкой (доп. примером в конце) сложнее: их под слайдером две и сделать переключение по пробелу не получится.

        Спасибо за подсказку.
        • 0
          Здорово, в который раз впечатляюсь твоей талантливостью :)
  • 0
    Демо и файлы не работают больше…

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