Интересный и одновременно простой слайдер на чистом CSS3

Я никому не открою Америку, не удивлю публику новым фокусом и не взорву мозг тем, кто в CSS3 плавает, как аквалангист. Расскажу простой способ, как создать слайдер с помощью простых функций CSS3 без необходимости использовния javascript.

1. Верстаем основу


Для реализации слайдера нам понадобится довольно простой набор тэгов, которые будут в свою очередь отвечать за элементы слайдера.

<div class="wrapper">
	<input type="radio" name="point" id="slide1" checked>
	<input type="radio" name="point" id="slide2">
	<input type="radio" name="point" id="slide3">
	<input type="radio" name="point" id="slide4">
	<input type="radio" name="point" id="slide5">
	<div class="slider">
		<div class="slides slide1"></div>
		<div class="slides slide2"></div>
		<div class="slides slide3"></div>
		<div class="slides slide4"></div>
		<div class="slides slide5"></div>
	</div>	
	<div class="controls">
		<label for="slide1"></label>
		<label for="slide2"></label>
		<label for="slide3"></label>
		<label for="slide4"></label>
		<label for="slide5"></label>
	</div>
</div>

Здесь мы видим, что общий блок «wrapper» содержит в себе блок «slider» с 5-ю слайдами, внутри которых можно поместить любой html-код, который будет располагаться на слайде. Перед общим блоком находятся радио-кнопки, которые впоследствии будут скрыты, чтобы создать для них собственную панель навигации по слайдам, с которой нам помогут лейблы в блоке «controls».

2. Оформляем слайдер


Здесь мы остановимся и немного рассмотрим css. Обратите внимание, что для некоторых свойств проставлены кроссбраузерные префиксы, чтобы все современные браузеры могли их понимать.

* {
	margin: 0;
	padding: 0;
	-webkit-box-sizing: border-box;
	-moz-box-sizing: border-box;
	-o-box-sizing: border-box;
	box-sizing: border-box;
}

body {
	background-image: url(http://habrastorage.org/files/996/d76/d04/996d76d0410d422fa54cc433ce7ead2a.png);
}

С оформлением фона и общими стилями всё понятно.

.wrapper {
	height: 350px;
	margin: 100px auto 0;
	position: relative;
	width: 700px;
}

.slider {
	background-color: #ddd;
	height: inherit;
	overflow: hidden;
	position: relative;
	width: inherit;
	-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, .5);
	-moz-box-shadow: 0 0 20px rgba(0, 0, 0, .5);
	-o-box-shadow: 0 0 20px rgba(0, 0, 0, .5);
	box-shadow: 0 0 20px rgba(0, 0, 0, .5);
}

Общий блок и блок с слайдером имеют одинаковые размеры, чтобы идеально контролировать положение слайдера на странице. Пока отсутствуют слайды, слайдер мы временно покрасили в светло-серый цвет.

.wrapper > input {
	display: none;
}

Радио-кнопки скрываем. Они нам понадобятся позже.

Результат на данный момент такой:

image

3. Оформляем слайды


Здесь мы пропишем общие стили для слайдов и каждый слайд отдельно:

.slides {
	height: inherit;
	position: absolute;
	width: inherit;
}

.slide1 { background-image: url(http://habrastorage.org/files/3f2/628/bd5/3f2628bd58c8452db516195cb0c9bfc9.jpg); }
.slide2 { background-image: url(http://habrastorage.org/files/3e1/95d/c7f/3e195dc7f5a64469807f49a14f97ba0e.jpg); }
.slide3 { background-image: url(http://habrastorage.org/files/663/6b1/d4f/6636b1d4f8e643d29eab8c192fc1cea3.jpg); }
.slide4 { background-image: url(http://habrastorage.org/files/e59/424/c04/e59424c046be4dab897d84ab015c87ea.jpg); }
.slide5 { background-image: url(http://habrastorage.org/files/53c/ff6/c1c/53cff6c1caf842368c70b8ef892d8402.jpg); }

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

image

4. Делаем навигацию по слайдам


Так как радио-кнопки скрыты и нужны нам как переключатели, оформляем подготовленные лейблы:

.wrapper .controls {
	left: 50%;
	margin-left: -98px;
	position: absolute;
}

.wrapper label {
	cursor: pointer;
	display: inline-block;
	height: 8px;
	margin: 25px 12px 0 16px;
	position: relative;
	width: 8px;
	-webkit-border-radius: 50%;
	-moz-border-radius: 50%;
	-o-border-radius: 50%;
	border-radius: 50%;
}

.wrapper label:after {
	border: 2px solid #ddd;
	content: " ";
	display: block;
	height: 12px;
	left: -4px;
	position: absolute;
	top: -4px;
	width: 12px;
	-webkit-border-radius: 50%;
	-moz-border-radius: 50%;
	-o-border-radius: 50%;
	border-radius: 50%;
}

Навигацию мы делаем классической. Каждая кнопка представляет собой область в виде круга, внутри которого при активном слайде пустая область частично окрасится. Пока же у нас следующий результат:

image

5. Учим кнопки нажиматься


Пришло время научить слайдер переключать слайды по нажатию на определённую кнопку:

.wrapper label {
	cursor: pointer;
	display: inline-block;
	height: 8px;
	margin: 25px 12px 0 16px;
	position: relative;
	width: 8px;
	-webkit-border-radius: 50%;
	-moz-border-radius: 50%;
	-o-border-radius: 50%;
	border-radius: 50%;
	-webkit-transition: background ease-in-out .5s;
	-moz-transition: background ease-in-out .5s;
	-o-transition: background ease-in-out .5s;
	transition: background ease-in-out .5s;
}

.wrapper label:hover, 
#slide1:checked ~ .controls label:nth-of-type(1),
#slide2:checked ~ .controls label:nth-of-type(2),
#slide3:checked ~ .controls label:nth-of-type(3),
#slide4:checked ~ .controls label:nth-of-type(4),
#slide5:checked ~ .controls label:nth-of-type(5) {
	background: #ddd;
}

В оформленные кнопки навигации добавляем плавное окрашивание внутри них. Также добавляем условия, при которых активная кнопка и кнопка, на которую навели курсор, будет плавно окрашиваться. Наши собственные радио-кнопки готовы:

image

6. Оживляем слайдер


Ну, а теперь делаем так, чтобы слайды наконец-то переключались:

.slides {
	height: inherit;
	opacity: 0;
	position: absolute;
	width: inherit;
	z-index: 0;
	-webkit-transform: scale(1.5);
	-moz-transform: scale(1.5);
	-o-transform: scale(1.5);
	transform: scale(1.5);
	-webkit-transition: transform ease-in-out .5s, opacity ease-in-out .5s;
	-moz-transition: transform ease-in-out .5s, opacity ease-in-out .5s;
	-o-transition: transform ease-in-out .5s, opacity ease-in-out .5s;
	transition: transform ease-in-out .5s, opacity ease-in-out .5s;
}

#slide1:checked ~ .slider > .slide1,
#slide2:checked ~ .slider > .slide2,
#slide3:checked ~ .slider > .slide3,
#slide4:checked ~ .slider > .slide4,
#slide5:checked ~ .slider > .slide5 {
	opacity: 1;
	z-index: 1;
	-webkit-transform: scale(1);
	-moz-transform: scale(1);
	-o-transform: scale(1);
	transform: scale(1);
}

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

Далее мы приписываем условие, при котором, в зависимости от активной кнопки навигации, в окне слайдера появлялся необходимый слайд.

Результат можно посмотреть здесь: демка слайдера.

Итог


Слайдер не требует js. Пускай он не умеет сам переключаться, но любому, кто знает основы CSS, transition и transform, будет легко придумать свои эффекты для переключения слайдов.

P.S. За основу взят слайдер от «Sorax», который я переделал на свой лад.

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

Средняя зарплата в IT

110 000 ₽/мес.
Средняя зарплата по всем IT-специализациям на основании 8 385 анкет, за 2-ое пол. 2020 года Узнать свою зарплату
Реклама
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее

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

    –13
    Просто. Зачем?
      +18
      — Зачем?
      — Просто.
      +23
      Надо добавить кадр в слайдер — побежали править css. Не надо так.
        +1
        Конечно, для пользовательской галереи это не подойдет, однако, на мой взгляд, такие вещи и не должны использоваться таким образом. С другой стороны, делать все на статике нереально, разве что только из принципа, тогда вообще отпадает необходимость прибегать к таким ухищрениям, намного проще взять готовый js.

        Данное решение можно использовать, например, в генераторе статик сайтов. Написал код один раз, дальше он генерит этот css без необходимости правки кода: добавил картинку в папку, код увидел больше картинок, для каждой перегенерил css.

        Какие плюсы с точки зрения браузера: я лично не особо опытный, поэтому плюсов никаких не вижу. Наверное, если браузер старый, то тут уже ничего не поможет.

        Если брать, например, работу в joomla 2.5, то из-за того, что там mootools, там постоянно возникают проблемы со слайдами из jquery из-за конфликтующих функций. С этой позиции — не будет конфликта js.

        Буду признателен, если кто-то поделится своим взглядом и опытом. Спасибо.
        +18
        То же самое, только универсально и без необходимости редактировать CSS для каждой новой картинки: jsbin.com/miwuke/

        .slider {
        	position:relative;
        	width:700px;
        	padding-top:370px;
        	text-align:center;
        	}
        	.slider__check {
        		position:absolute;
        		clip:rect(0 0 0 0);
        		overflow:hidden;
        		}
        	.slider__image {
        		position:absolute;
        		top:0;
        		left:0;
        		}
        	.slider__label {
        		overflow:hidden;
        		display:inline-block;
        		width:20px;
        		height:20px;
        		background:#069;
        		border-radius:50%;
        		text-indent:-9999px;
        		}
        
        /* Display */
        .slider__image {
        	display:none;
        	}
        .slider__check:checked + .slider__label + .slider__image {
        	display:block;
        	}
        
        /* Current */
        .slider__check:checked + .slider__label {
        	background:#C00;
        	}


        Добавьте анимации по вкусу.
          0
          Можно еще на animation сделать автоматическую смену кадров.
          Только по-моему, гораздо более интересной задачей было бы сделать именно что слайдер, то есть «приезжание» из-за границы родительского блока. Без js
          –8
          В сторону: тем, кто кладёт картинки в виде фона, хочется оторвать руки. Я всё равно до них доберусь, если захочу сохранить, но потрачу лишнее время.
            +9
            Вы в самом деле думаете что это делается чтобы «защитить» изображения?
              –9
              Я не вижу других причин, озвучьте.
                +6
                Растягивание изображение на весь размер блока с сохранением пропорций
                  +1
                  Этого легко добиться позиционированием img внутри контейнера.
                    +1
                    Если заранее известны размеры контейнера и изображения, то да. Можно, конечно, написать скрипт, который будет определять размеры контейнера и изображения и позиционировать его в нём, но это требует больше действий, нежели поместить изображение в фон. Поэтому часто предпочитают ставить изображение в качестве фона.

                    Я согласен с Вами, что вставлять изображения через img лучше по ряду причин, поэтому предпочитаю использовать img.
                      –1
                      Вот есть, например, такое отличное свойство object-fit. Позволяет делать с картинками все то же самое, что и позиционирование внутри background-image. Но при взгляде на его поддержку, сразу же ухудшается настроение: его не поддерживает даже Edge caniuse.com/#feat=object-fit
                      Вот и получается, если нужно добиться такого результата, который дают background-size: cover / contain; проще всего их и использовать. Как вариант, адрес картинки поместить в инлайновые стили, а остальные свойства — в CSS. По-моему, решение хоть и не самое красивое, но самое простое и рабочее.
                    0
                    Тупо потому что для <img/> нельзя указать src из CSS?
                  0
                  Это делается просто потому, что у background больше возможностей, чем у img.
                    +2
                    Камень в огород W3C. У background ещё есть куча ограничений для Safari в iOS к примеру.
                      0
                      Каких?
                        +1
                        background-attachment: fixed не работает ни в safari под ios, ни в chrome под андоид вместе с background-size: cover.
                          0
                          Да там банально ещё есть ограничение на размер. У нас картинка просто не показывалась когда была больше 1024x1024 (при наличии других картинок в системе). Но у нас ещё осложнялось тем, что это был не сам Safari а WebView…

                          Как я понял, если картинка висит в background то всегда в памяти (причём видео), что бы потом можно было производить манипуляции на лету. Img же рендрится в сам контекст и вгружается в память только по требованию перерисовки (изменение размера или видимо скругление углов). У смартфонов что с памятью, что с GPU тухло от сюда и ограничения.
                            0
                            Сегодня словили глитч в chrome на андроид (nexus 7 2013), когда картинка в 16 мегапикселей просто вытягивалась как будто в 1000 раз по ширине, с неким набором стилей.
                      • НЛО прилетело и опубликовало эту надпись здесь
                          0
                          Тут не в реализации дело. Иначе это реализовать трудно, что бы ещё и быстро работало. По сути это неявные ограничения для background.

                          ЗЫ не знаю как, сейчас но одно время смотрел как картинки в background влияют на скорость отрисовки, и на десктопе оно так прилично просаживало
                        +4
                        У img есть object-fit / object-position / image-orientation / image-rendering / image-resolution… Так что возможностей тоже хватает, правда не везде оно пока что поддерживается.
                          0
                          Мдя… ещё пару лет чую нельзя будет это юзать. Если object-fit IE боится то object-position даже safari, а image-orientation кажется только FF любит.
                            –1
                            Оно начисто игнорируется даже, казалось бы, современным браузером Edge (популярность которого, как мне кажется, сейчас начнет стремительно расти, потому что в нем, в принципе есть все, что нужно обычному юзеру, а значит его нельзя списывать со счетов).
                            Так что вряд ли разумно использовать сейчас эти свойства: достаточно много людей увидят вместо того, что вы верстали, растянутую и уродливую картинку.
                            –5
                            Расскажите о конкретных примерах, когда содержимое страницы (если мы говорим про эту галерею) нужно засунуть в оформление и сделать его недоступным пользователю.
                              0
                              Сделайте слайдер с картинкой, где можно задавать какое либо небольшое количество опций слайда, не зная размера картинки, не используя java-script. Сам слайдер может иметь любой размер, в том числе и адаптироваться под контент внутри него.

                              screencloud.net/v/wwXW
                                –3
                                можно задавать какое-либо небольшое количество опций слайда


                                Честно говоря, я не понял задачи и тем более, почему фон здесь лучше, чем img
                                  0
                                  Сделайте, чтобы картинка повторялась. Сделайте, чтобы картинка занимала всё пространство с сохранением пропорций без жс. Сделайте паралакс без жс.
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                      –1
                                      С вас такой верстальщик смотрю, как и комментатор. То есть хреновый.

                                      1. Имелось ввиду background-size: cover. Картинка заполняет собой всё пространство, масштабируется по меньшей стороне, а лишнее обрезается. К тому же пример в тостере крайней плохой, и в сафари не работает — screencloud.net/v/fE7f
                                      2. Такой метод не применим к живым сайтам, в которых может редактироваться контент. В которых блоки занимают не определённую высоту и позицию. А тем более это не применимо к слайдеру.
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                          0
                                          Ну вот, а говорите верстать умеете, а живых сайтов не делали, и требований клиентов не знаете. Дальше говорит не о чем. Типичный кодер тимфорестера.
                                          • НЛО прилетело и опубликовало эту надпись здесь
                                              0
                                              На личности перешли вы. Но как и прежде, видно ваши «глубокие» знания, особенно про object-fit. А так же, все реальные задачи, с которым сталкиваются кодеры в реальной жизни для вас странные — не лицо не хватка опыта.

                                              PS. background-size caniuse.com/#feat=background-img-opts, object-fit — caniuse.com/#feat=object-fit. Рас старые кодеры не умеют гуглить и не знают где и как работают те или иные свойста. Представляю какой малины вы учите в ваших статьях.
                                              • НЛО прилетело и опубликовало эту надпись здесь
                                • НЛО прилетело и опубликовало эту надпись здесь
                                    0
                                    Под контентом слайдера я имел текст внутри слайда.

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

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