Хочу рассказать простой способ создания слайдера, без использования JS, при помощи анимации CSS.

1) Для начала напишем HTML, предположим что в слайдере будут сменять друг друга 4 изображения.

  <div class="slider">
      <div class="slide slide1"></div>
      <div class="slide slide2"></div>
      <div class="slide slide3"></div>
      <div class="slide slide4"></div>
 </div>

2) Далее оформим размеры блока, и еще несколько настроек, position: relative необходимо для того, чтобы создать контекст форматирования, дальше будет понятно зачем.

.slider {
	width: 500px;
	height: 300px;
	margin: auto;
	margin-top: 25px;
	border: 1px solid black;
	position: relative;
	overflow: hidden;
}

3) Также определим некоторые свойства для самих слайдов:

.slide {
	width: 500px;
	height: 300px;
	position: absolute;
	top: 0;
	left: 0;
}

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

4) Далее нужно определить каким именно образом слайды будут сменять друг друга, не создавая разрывов – для каждого слайда я решил использовать следующую последовательность действий:

1. Слайд находится на исходной позиции, демонстрируется пользователю

2. Слайд двигается влево, пока полностью не выйдет за границу слайдера (у слайдера же, как выше указано, overflow: hidden, соответственно слайд не наезжает на окружающие объекты).

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

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

5. Слайд спускается вниз на один уровень со слайдером

6. Слайд двигается на исходную позицию
Иначе говоря (кадры пока назову согласно номерам из списка выше):

@keyframes slide {
	from {
		top: 0;
		left: 0;
	}
	1 { transform: translate(0px, 0px); }
	2 { transform: translate(-500px, 0); }
	3 { transform: translate(-500px, 300px); }
	4 { transform: translate(500px, 300px); }
	5 { transform: translate(500px, 0); }
	to  { transform: (0px, 0px);  }
}

5) Итак, стало понятно, как выглядит траектория слайда. Каждый слайд «объезжает» вокруг своего контейнера – слайдера – и возвращается на исходную. Таким образом мы можем бесконечно крутить любое количество слайдов. Но остался один нюанс, который является самым важным в этой схеме – время. Нужно правильно рассчитать раскадровку анимации по времени и установить правильную задержку для каждого слайда, чтобы не все одновременно ринулись анимироваться. Для того чтобы понять, как правильно выставит задержку и рассчитать время анимации, я пошел нижеописанным путем.

Давайте возьмем обозначения шагов из предыдущего пункта и разберемся что же происходит в каждом шаге. По сути, шаги №1, 2 и 6 – это те шаги, в которых слайд заходит в видимую область. Из того, что слайды должны двигаться неразрывно и, как бы, выталкивать друг друга из слайдера, можно заключить, что длительность шагов 2 и 6 должна быть равна. Сразу оговорюсь, что мне удалось удачно работать эту конструкцию только при том условии, что длительность первого шага также равна длительности 2-го и 6-го. То, что происходит во время шагов 3,4 и 5 – по сути, технические нужды, и для простоты, давайте объединим эти три шага в 1.

После упрощения имеем:

1. Шаг – слайдер демонстрируется на исходной
2. Шаг – слайдер сдвигается вправо
3. Шаг – слайдер совершает технические перемещения
4. Шаг – слайдер сдвигается влево, возвращаясь на исходную позицию

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

Т.е.:



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

Если время, на круг всей анимации – t;
Кол-во слайдов – n;
Длительность 3 шага – y;
Длительность шагов 1,2 и 4 – x;
Шаг задержки анимации для n-слайда – z;
То:

y = (100 * n — 150)/n;
x = (100 – y) / 3;
x и y необходимо перевести в проценты, и тогда:
z = 2 * x * t;

Для случая, когда n = 4, как в примере выше, получаем:

3-ий шаг – 62,5%, 1, 2 и 4-ый — по 12,5%. Шаг задержки анимации для каждого последующего слайда – 25%.

Какие интервалы будут между этапами внутри третьего шага – не имеет значения.

6) Теперь, когда мы все посчитали и знаем все величины можно привести финальный код.

Анимация:

@keyframes slide {
 from {
  top: 0;
  left: 0;
 }
 12.5% {
  transform: translate(0px, 0px);
 }
 25% {
  transform: translate(-500px, 0);
 }
 36% {
  transform: translate(-500px, 300px);
 }
 37% {
  transform: translate(500px, 300px);
 }
 87.5% {
  transform: translate(500px, 0);
  
 }
 to {
  transform: (0px, 0px);
 }
}

Слайды:

.slide1 { 
 background: url(1.jpg);
 animation-delay: 7.5s;
}
.slide2 { 
 background: url(2.jpg);
 animation-delay: 5s;
}
.slide3 { 
 background: url(3.jpg);
 animation-delay: 2.5s;
}
.slide4 { 
 background: url(4.jpg);
 animation-delay: 0s;
}

Общий CSS для всех слайдов:

.slide {
	width: 500px;
	height: 300px;
	position: absolute;
	top: 0;
	left: 0;
	animation-name: slid;
	animation-duration: 10s;
	animation-timing-function: linear;
	animation-iteration-count: infinite;
}

Вот, собственно и все! Спасибо всем, кто дочитал до конца.
Поделиться с друзьями
-->

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


  1. MikalaiR
    15.03.2017 18:00
    +3

    А где же ссылка, где можно увидеть пример?


    1. GenrikhFetischev
      15.03.2017 19:07

      Можно вот тут посмотреть — genrih-fetischev.myjino.ru/balovstvo, надо было сразу конечно ссылку.


      1. sleeply4cat
        15.03.2017 19:24

        Весьма прожорливо, однако. У меня 40% процессора отъедает. Владельцы планшетов на атоме не оценят.


        1. GeMir
          15.03.2017 21:57

          На i5 2500K загрузка 2%, но анимация местами рывками (Chrome 57, 64-bit).


  1. aliencash
    15.03.2017 19:24
    -2

    Гениально! Как я сам не додумался? (


  1. DjPhoeniX
    15.03.2017 19:39

    Не понял, зачем махинации с движением за кадром. После первой фазы вставить сильно отрицательный z-index, перепрыгнуть направо, вернуть «как было», и (когда придёт время) продолжить (как сейчас) с готовым положением.

    И выложите семпл куда-нибудь на jsfiddle. Со ссылкой в посте.


    1. GenrikhFetischev
      15.03.2017 20:32

      По поводу z-index тоже была мысль, но даже не могу сказать почему не реализовал так, вероятно забыл про эту идею.
      jsfiddle — спасибо, возьму на заметку


    1. Ipauler
      16.03.2017 17:04

      Вот jsfiddle


  1. lipton_ice_tea
    15.03.2017 19:58
    +1

    И каждый раз, когда я захочу добавить еще слайд, или убрать, придется лезть и править css?!


    1. GenrikhFetischev
      15.03.2017 20:34
      -1

      Можно, думаю, использовать какой-нибудь препроцессор, например


  1. lekzd
    15.03.2017 23:18

    картинки из css стоит заменить на обычные img, так удобнее их менять как контент. Магические числа 500 и 300 так-же не нужны, css transform отлично работает с высотой и шириной элемента через проценты. да и css counters можно попробовать использовать для задержки анимации


  1. raveclassic
    15.03.2017 23:57
    +2

    У меня дежавю


    1. 0Ilya
      16.03.2017 08:25
      +1

      Врятли, за последние пол года уже таких статей было 5-6


      1. raveclassic
        16.03.2017 09:45
        +1

        Как раз это и имелось виду :)


  1. Krasnodar_etc
    16.03.2017 17:05
    +1

    +, нада пример. Справедливости ради, скажу, что я раньше не видел css-слайдеров с автоплэй-ем и бесконечной прокруткой.

    Но всё таки, сколько можно об этом писать? Наверное, самая изъезженная тема в вёрстке за год. Да и зачем нужен слайдер, если пользователь не может остановить его и посмотреть слайд/отмотать к нужному слайду? Ну… такое