[вёрстка] Как сделать слайдер на CSS и HTML, без Javascript
В одной из предыдущих статей мы рассмотрели, как сделать вкладки на CSS при помощи трюка с радио-кнопками. В этой статье мы при помощи аналогичного подхода создадим симпатичный слайдер, не требующий Javascript для работы.
Слайдеры, как правило делаются с использованием Javascript. Обычно для этого задействуют библиотеку JQuery. Хотя CSS и не позволяет создать полнофункциональный слайдер с кучей возможностей, таких как анимация по таймеру, листание пальцем на тач-скрине и т.п., во многих случаях такие продвинутые возможности и не требуются.
Простой слайдер для блога гораздо проще сверстать на чистом HTML и CSS, чем задействовать для этого возможности Javascript. Во-первых, код стилей слайдера получится гораздо проще и понятнее, чем код слайдера на Javascript. Во-вторых, та часть пользователей, которая параноидально не доверяет сайтам и заходит на незнакомые сайты только с аддоном NoScript, вырезающим весь JS-код, тоже сможет воспользоваться вашим слайдером.
Поехали!
Простой слайдер с анимированным переключением кадров
Примечание: В этом примере я буду ориентироваться на самые новые возможности CSS. Код не предназначен для работы в старых браузерах.
Начнём создание слайдера с такого кода:
<div class='sliderA'> <input type="radio" name="slider1" id="slider1_1" checked="checked"> <label for="slider1_1"></label> <div></div> <input type="radio" name="slider1" id="slider1_2"> <label for="slider1_2"></label> <div></div> <input type="radio" name="slider1" id="slider1_3"> <label for="slider1_3"></label> <div></div> <input type="radio" name="slider1" id="slider1_4"> <label for="slider1_4"></label> <div></div> </div>
Контейнер слайдера — div с классом sliderA. Каждый кадр слайдера описывается трёмя тегами:
- Радиокнопкой (input type="radio"), отвечающей за состояние данного кадра (видно / не видно)
- Меткой label, отвечающей за отображение кнопки перехода на данный слайдер.
- Тегом div в котором находится содержимое кадра.
Радиокнопки внутри одного слайдера должны иметь одинаковое имя name. Также, все радиокнопки должны иметь уникальные (различные) идентификаторы id. Метка в поле for должна содержать значение id соответствующей радиокнопки. (Если вам не понятно, почему и зачем всё это делается читайте статью про вкладки. Там всё это объяснено подробно.)
Начинаем работать над стилями. Контейнер:
.sliderA { width: 400px; height: 250px; border: 1px solid #888; position: relative; text-align: center; }
Мы задаём фиксированные размеры контейнера. Я установил их равными размеру изображений, которые я буду использовать в этом примере. Свойство position: relative необходимо, чтобы задать новую точку отсчёта позиций вложенных контейнеров. Свойство text-align: center я добавил, чтобы выровнять по центру полосу меток-кнопок, которые я буду позиционировать как inline-элементы.
Отображение радиокнопок нам не нужно, скрываем их:
.sliderA > input { display: none; }
Оформляем метки-кнопки. Кода много, но ничего сложного нет:
.sliderA > input + label { display: inline-block; width: 10px; height: 10px; border-radius: 8px; background: rgba(90, 90, 90, 0.8); border: 2px solid rgba(190, 190, 190, 0.8); cursor: pointer; z-index: 100; position: relative; margin-right: 4px; top: 90%; transition: background 0.8s ease-out 0s; } .sliderA > input + label:hover { background: rgba(250, 250, 250, 0.8); } .sliderA > input:checked + label { background: rgba(220, 220, 220, 0.8); }
Я устанавливаю свойство display: inline-block, что позволит разместить метки одной строкой и выровнять их по центру как строчные элементы, и вместе с тем задать им фиксированные размеры как блокам. Затем я задаю ширину и высоту, а также радиус скругления углов, цвет фона и цвет границы. Всё это приводит к тому, что наши метки будут отображаться в виде маленьких круглых кнопок.
Свойство cursor позволяет задать внешний вид курсора мыши при наведении на кнопку. Я установил значение pointer, т.е. вид указателя мыши будет такой же, как при наведении на ссылку («указательный палец»).
Свойство z-index необходимо для того, чтобы метки-кнопки лежали поверх кадров слайдера. Для этого же установлено свойство position: relative — иначе z-index не будет работать.
margin-right добавляет отступы между кнопками, а top: 90% сдвигает их в нижнюю часть контейнера. Можно было задать вертикальную позицию кнопок более грамотно, но здесь я ограничусь этим способом.
Также я задаю цвет фона для нажатой кнопки и кнопки, на которую наведена мышь. Свойство transition определяет анимацию для смены фона.
Также нам следовало устранить все пробелы и переводы строк между тегами слайдера, так как при использовании display: inline-block они дадут нам лишние зазоры между кнопками. Так мы поступали в предыдущей статье. Я не стал сейчас этого делать для упрощения восприятия кода HTML.
Получилась вот такая заготовка слайдера:
Добавляем стили для div-ов, в которых будет находиться содержимое кадра:
.sliderA > div { position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 0; }
Все кадры будут занимать одно и то же положение. position: absolute позволяет изъять блоки из потока и разместить из произвольным образом. top, left, right, bottom задают координаты кадра таким образом, что кадр занимает весь контейнер слайдера целиком. z-index отправляет кадры под кнопки переключения кадров, иначем мы не сможем эти кнопки ни увидеть, ни нажать.
Теперь самая главная часть слайдера — показ и скрытие кадров в зависимости от нажатой кнопки. Традиционный подход скрытия элементов страницы с использованием свойства display: none нам не совсем подходит. Ведь для слайдера хотелось бы сделать плавное переключение кадров, но CSS не позволяет задать анимацию значения display при помощи правил transition.
Для плавного скрытия и появления кадров нам понадобятся два свойства: opacity и visibility; а также упомянутый transition.
Свойство opacity позволяет в виде десятичной дроби задать уровень прозрачности элемента страницы, от 0 (полностью прозрачный) до 1 (полностью непрозрачный). Например, opacity: 0.5 — прозрачность 50%.
Но даже полностью прозрачный элемент, хоть и невидимый, продолжает реагировать на нажатия мышью. Поэтому, если у вас в слайдере находятся ссылки, нажатие на ссылку может привести к срабатыванию совсем не той ссылки, которая видна на экране.
Чтобы полностью отключить элемент и сделать его прозрачным для щелчков мышью, понадобится второе свойство: visibility: hidden. Однако visibility не позволяет задать частичную прозрачность. Элемент либо виден, либо нет.
Поэтому мы будем при помощи transition анимировать оба свойства, чтобы добиться нужного нам эффекта. Суть метода в следующем:
- Когда пользователь переключает кадр, новый кадр появляется с visibility: visible, но с opacity: 0.
- Затем происходит анимация значения opacity у обоих кадров. У старого кадра она плавно опускается до нуля, а у нового — плавно поднимается до единицы.
- После завершения анимации, visibility старого кадра устанавливается в значение hidden, чтобы он не мешал щелчкам мышью по новому кадру.
Вот такой код у меня получился:
Также я добавил правило для тега p внутри кадра, чтобы сделать подписи к картинкам:.sliderA > div { visibility: hidden; opacity: 0; transition: opacity 0.8s ease-out 0.1s, visibility 0.1s ease-out 0.9s; } .sliderA > input:checked + label + div { visibility: visible; opacity: 1; transition: opacity 0.8s ease-out 0.1s, visibility 0.1s ease-out 0s; }
.sliderA > div > p { position: absolute; top: 0px; left: 0px; right: 0px; text-align: center; color: #fff; text-shadow: 1px 1px 2px #000; }
Дописываем HTML-код слайдера для нашего примера:
<div class='sliderA'> <input type="radio" name="slider1" id="slider1_1" checked="checked"> <label for="slider1_1"></label> <div> <p>Восход над островом</p> <img src='https://lh3.googleusercontent.com/-XGgw41OSARk/VePicTdAdgI/AAAAAAAAAS4/WeBbxp4ebQg/s400-Ic42/00099_manaisland_1920x1200.jpg' alt=''> </div> <input type="radio" name="slider1" id="slider1_2"> <label for="slider1_2"></label> <div> <p>Озёрный край</p> <img src='https://lh3.googleusercontent.com/-aafAKIoTkT4/VePihWk2BHI/AAAAAAAAATA/zQVtiYD_eDc/s400-Ic42/00201_lakejipe_1920x1200.jpg' alt=''> </div> <input type="radio" name="slider1" id="slider1_3"> <label for="slider1_3"></label> <div> <p>Закатная синева</p> <img src='https://lh3.googleusercontent.com/-ikbDMRhLc_I/VePkT4XLFtI/AAAAAAAAATg/qaHqQk89RAw/s400-Ic42/00744_laclahachesunset_1920x1200.jpg' alt=''> </div> <input type="radio" name="slider1" id="slider1_4"> <label for="slider1_4"></label> <div> <p>Сельский пейзаж</p> <img src='https://lh3.googleusercontent.com/-BLXeHJNyOqw/VePimp_e_wI/AAAAAAAAATQ/BVw_9LFehyU/s400-Ic42/00442_pyrenees_1920x1200.jpg' alt=''> </div> </div>
И получаем вот такой результат:
Простой слайдер с анимированным переключением кадров, второй вариант
В слайдере можно размещать как обычные фотографии, так и любой текст, ссылки на другие страницы сайта и так далее.
В случае, когда вы используете слайдер для размещения простых изображений (например, вы турист, и публикуете фотографии из ваших путешествий) возникает желание усовершенствовать слайдер так, чтобы нажатие на слайдер приводило к переходу к следующему изображению. В предыдущем примере кадры слайдера переключаются только круглыми кнопками, а нажатие на само изображение ничего не даёт.
Усовершествуем наш слайдер. В шаблон слайдера добавим по еще одной метке для каждого кадра:
<div class='sliderA' > <input type="radio" name="slider2" id="slider2_1" checked="checked"> <label for="slider2_1"></label> <div></div> <label for="slider2_2"></label> <input type="radio" name="slider2" id="slider2_2"> <label for="slider2_2"></label> <div></div> <label for="slider2_3"></label> <input type="radio" name="slider2" id="slider2_3"> <label for="slider2_3"></label> <div></div> <label for="slider2_4"></label> <input type="radio" name="slider2" id="slider2_4"> <label for="slider2_4"></label> <div></div> <label for="slider2_1"></label> </div>
Как видите, метка идущая после первого кадра, активирует второй кадр. Метка, расположенная после второго кадра, активирует третий кадр; после третьего — чертвёртый. Последняя метка активирует первый кадр.
Метки мы расположим так, чтобы они перекрывали весь слайдер и лежали выше изображения, но ниже полосы кнопок. Метки прозрачные, поэтому сквозь них видно содержимое кадра. При показе кадра номер N вместе с ним отображается метка для перехода на кадр N + 1. (Для последнего кадра — метка перехода на первый кадр.)
.sliderA > input + label + div + label { display: none; } .sliderA > input:checked + label + div + label { display: block; position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 50; }
Таким образом, при щелчке по изображению срабатывает активация следующего изображения. Результат:
У нас получился симпатичный слайдер для фотографий с вкладочным переключением кадров. Такой слайдер отлично подойдёт, например, для публикации фотографий в блоге о путешествиях.
В следующей статье о CSS я рассмотрю другой вариант слайдера: с переключением кадров при помощи кнопок «вперёд» и «назад».
18 комментариев
Подскажите, получится ли прикрутить такой слайдер на http://decoacoustic.ru вместо штатного?
замечательно выходит!!!
Только, скажите пожалуйста, почему этот слайдер не работает при входе на сайт со смартфона?
Последнее сообщение моё. Приношу извинения!!! Всё работает, это были проблемы со смартфоном.
А как зделать чтоб изображения сами переключались как слайдшоу?
пасибо
Как буд-то не работает у меня слайдер, checked не переключает
Возможно ли вмето инпутов использовать div ? например при наведение на блок с боку будет менятся картинка?
Я все с точностью скопировала, но у меня не получился слайдер. На верху 5 точек вертикально и под ними 5 рисунков просто вставлены. Как исправить? Или может помимо этого что то писать надо?
напишите так в .sliderA > input + label у автора неправильно
background: rgba(90, 90, 90, 0.8) none repeat scroll 0 0;
border: 2px solid rgba(190, 190, 190, 0.8);
border-radius: 8px;
cursor: pointer;
display: block;
float: left;
height: 10px;
left: 43%;
margin-right: 4px;
position: relative;
top: 105%;
transition: background 0.8s ease-out 0s;
width: 10px;
z-index: 100;
Спасибо большое! Всё работает, СУПЕР!!!
Спасибо большое! Очень понятное объяснение даже для новичка! Все получилось!
Хороший слайдер, скажите будет ли работать на странице html на сайте http://feoparagliding.com ?
Прошу разъяснить: почему если не написать
.sliderA > div {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
z-index: 0;
}
то
.sliderA > input + label {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 8px;
background: rgba(90, 90, 90, 0.8);
border: 2px solid rgba(190, 190, 190, 0.8);
cursor: pointer;
z-index: 100;
position: relative;
margin-right: 4px;
top: 90%;
transition: background 0.8s ease-out 0s;
}
не будет корректно работать свойства display: inline-block не будет строить кнопки в линию
top: 80% будет выходить за границы блока родителя, хотя у sliderA position: relative;
В чем связь?
Доработал скрипт, добавил автоматическое перелистывание на JS
var inp = document.getElementsByName('slider1');
var sliderInterval = setInterval(nextSlide, 2000);
function nextSlide(){
for( var i = 0; i < inp.length; i++){
if (inp[i].checked == true) {
i++;
if (i != inp.length) {
inp[i].checked = true;
}
else
inp[0].checked = true;
}
}
}
Добрый день. Помогите пожалуйста с этим слайдером. Все сделал как по инструкции - у меня получается картинки друг под другом и радиокнопки между ними.
Учел также поправку из комментария об ошибке - не помогло.
Можете дать код для вставки у кого работает?
Спасибо большое, все понятно и просто!
покажите кто-нибудь весь код целиком пожалуйста!!!?
О, симпатичный блок комментариев. Поделитесь, где взяли? ))
Отправить комментарий