В этой статье рассмотрим процесс создания легкого, простого и адаптивного слайдера для сайта с помощью CSS и JavaScript.

Исходные коды и подключение слайдера к сайту

Проект слайдера расположен на GitHub по этому адресу. Данный слайдер распространяется под лицензией MIT. Его можно использовать бесплатно как в личных проектах, так и в коммерческих. Поблагодарить автора и поддержать дальнейшее развитие слайдера можно на этой страничке.

Основные характеристики слайдера:

  • адаптивный;
  • лёгкий (без jQuery);
  • простой (с минимальным набором функций);
  • наличие механизма автоматического смена слайдов через определенные промежутки времени;
  • универсальный (можно использовать для текстовой информации, изображений, отзывов, товаров и др.).

Подключение слайдера к странице осуществляется посредством выполнения следующих действий:

  • вставить в необходимое место html код слайдера;
  • подключить файл со стилями или добавить их в существующий файл; также стили можно вставить прямо на страницу;
  • подключить js-скрипт слайдера или вставить его в существующий файл; также код можно добавить прямо на страницу.

Демо слайдера расположено на этой странице.

Простой слайдер изображений для сайта на CSS и чистом JavaScript

Инициализация и настройка слайдера

Инициализация карусели осуществляется посредством вызова функции slideShow и указания ей в качестве первого аргумента селектора, определяющего слайдер в документе:

// инициализация элемента .slider в качестве карусели
slideShow('.slider');

Кроме селектора функции slideShow можно передать дополнительные параметры, все они указываются в формате объекта посредством 2 параметра:

// инициализация элемента .slider в качестве карусели и настройка её с помощью дополнительных параметров
slideShow('.slider', {
  isAutoplay: false, // false (по умолчанию) или true
  directionAutoplay: 'next', // 'next' (по умолчанию) или 'prev'
  delayAutoplay: 5000, // 5000 (по умолчанию) или любое другое число
  isPauseOnHover: true // true (по умолчанию) или false
});

Назначение ключей:

  • isAutoplay – определяет, необходимо ли инициализировать слайдер с автоматической сменой элементов (по умолчанию этот ключ имеет значение false);
  • directionAutoplay – определяет направление для механизма автоматической смены слайдов (по умолчанию 'next'); для изменения направления установите 'prev';
  • delayAutoplay – задержка в миллисекундах перед процессом автоматической сменой одного слайда на другой (по умолчанию 5000 мс);
  • isPauseOnHover – определяет необходимо ли останавливать автоматическую смену слайдов при нахождении курсора в зоне слайдера (по умолчанию true)

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

// инициализация элемента .slider в качестве карусели и настройка её с помощью дополнительных параметров
slideShow('.slider', {
  isAutoplay: true
});

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

// инициализация элемента .slider в качестве карусели и настройка её с помощью дополнительных параметров
var sliderOne = slideShow('.slider');

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

// выполняет переход на следующий слайд
sliderOne.next();

Список методов слайдера:

  • stop – останавливает автоматическую смену слайдов;
  • next – выполняет переход на следующий слайд;
  • prev – выполняет переход на предыдущий слайд;
  • cycle – включает автоматическую смену слайдов.

Примеры использования слайдера для ротации различной информации

Применение слайдера для ротации изображений:

Слайдер изображений для сайта на CSS и JavaScript

Посмотреть

Использования слайдера для ротации текстовой информации:

Слайдер для ротации текстовой информации для сайта на CSS и JavaScript

Посмотреть

Пример использования слайдера для отображения отзывов:

Простой слайдер отзывов клиентов для сайта на CSS и JavaScript

Применение слайдера для ротации товаров:

Слайдер товаров для сайта на CSS и JavaScript

Описание исходных кодов слайдера и принципа его работы

Исходные коды слайдера состоят из:

  • html кода;
  • CSS кода (стилей);
  • JavaScript кода (скрипта).

HTML структура слайдера:

<div class="slider">
  <div class="slider__wrapper">
    <div class="slider__items">
      <div class="slider__item">
        ...
      </div>
      <div class="slider__item">
        ...
      </div>
      <div class="slider__item">
        ...
      </div>
      <div class="slider__item">
        ...
      </div>
    </div>
  </div>
  <a class="slider__control slider__control_prev" href="#" role="button"></a>
  <a class="slider__control slider__control_next" href="#" role="button"></a>
</div>

В этой разметке основным контейнером, содержащим остальной код слайдера, является элемент div с классом slider. Внутри него находятся три элемента: обёртка для слайдов .slider__wrapper, кнопки для перехода к предыдущему и следующему слайду .slider__control. Кроме этого после вызова функции слайдера в этот блок ещё динамически добавляется элемент с индикаторами .slider__indicators.

Обёртка для слайдов .slider__wrapper содержит в себе элемент .slider__items, а он в свою очередь элементы .slider__item. Такая конструкция позволит при необходимости расположить индикаторы и элементы управления как внутри слайдов, так и за их пределами.

В этом примере слайдер состоит из 4 элементов .slider__item. Эти элементы визуально представляют собой слайды.

Блок с индикаторами .slider__indicators выполнен в виде нумерованного списка. Он состоит из элементов li с атрибутом data-slide-to. Количество элементов в списке определяется числом слайдов. Данный атрибут используется для определения индекса слайда, на которой нужно перейти при нажатии на данный индикатор. В слайдере активный индикатор отмечается с помощью добавления к нему класса active.

Кнопки «назад» и «вперед» размечены с помощью элемента a. Кнопка для перехода к предыдущему слайду имеет классы slider__control и slider__control_prev, а к следующему – slider__control и slider__control_next.

Структура слайдера, построенного на CSS и JavaScript

Стили слайдера:

/* стили основного контейнера слайдера */
.slider {
  position: relative;
  overflow: hidden;
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

/* стили для обёртки, в которой заключены слайды */
.slider__wrapper {
  position: relative;
  overflow: hidden;
}

/* стили для контейнера слайдов */
.slider__items {
  display: flex;
  transition: transform 0.7s ease;
}

/* стили для слайдов */
.slider__item {
  flex: 0 0 100%;
  max-width: 100%;
}

/* стили для кнопок "вперед" и "назад" */
.slider__control {
  position: absolute;
  top: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  color: #fff;
  text-align: center;
  opacity: 0.5;
  height: 50px;
  transform: translateY(-50%);
  background: rgba(0, 0, 0, 0.5);
}

.slider__control:hover,
.slider__control:focus {
  color: #fff;
  text-decoration: none;
  outline: 0;
  opacity: 0.9;
}

.slider__control_prev {
  left: 0;
}

.slider__control_next {
  right: 0;
}

.slider__control::before {
  content: '';
  display: inline-block;
  width: 20px;
  height: 20px;
  background: transparent no-repeat center center;
  background-size: 100% 100%;
}

.slider__control_prev::before {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E");
}

.slider__control_next::before {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E");
}

/* стили для индикаторов */
.slider__indicators {
  position: absolute;
  right: 0;
  bottom: 10px;
  left: 0;
  z-index: 15;
  display: flex;
  justify-content: center;
  padding-left: 0;
  margin-right: 15%;
  margin-left: 15%;
  list-style: none;
  margin-top: 0;
  margin-bottom: 0;
}

.slider__indicators li {
  box-sizing: content-box;
  flex: 0 1 auto;
  width: 30px;
  height: 4px;
  margin-right: 3px;
  margin-left: 3px;
  text-indent: -999px;
  cursor: pointer;
  background-color: rgba(255, 255, 255, 0.5);
  background-clip: padding-box;
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
}

.slider__indicators li.active {
  background-color: #fff;
}

В слайдере в некоторый момент времени пользователю всегда показывается только один слайд. Осуществляется это посредством скрытия всех элементов (слайдов) располагающихся за пределами области внутри .slider__wrapper. В CSS это осуществляется посредством установки .slider__wrapper свойства overflow со значением hidden.

.slider__wrapper {
  overflow: hidden;
}
Изображение, на котором отображено как пользователю в некоторый момент времени показывается только один слайд

Переход от одного слайда к другому осуществляется посредством CSS трансформаций. Для этого к .slider__items посредством кода JavaScript добавляется CSS свойство transform, значение которого содержит функцию translateX с определённым значением. Например, если данной функции указать в качестве значения -100%, то браузер осуществит переход к следующему слайду, а если наоборот, 100% - то к предыдущему.

Изображение, на котором отображено как пользователю в некоторый момент времени показывается только один слайд

Время и скорость, с которой будет осуществляться трансформация определяется с помощью CSS свойства transition:

.slider__items {
  transition: transform 0.7s ease;
}

Логика работы слайдера:

'use strict';
var slideShow = (function () {
  return function (selector, config) {
    var
      _slider = document.querySelector(selector), // основный элемент блока
      _sliderContainer = _slider.querySelector('.slider__items'), // контейнер для .slider-item
      _sliderItems = _slider.querySelectorAll('.slider__item'), // коллекция .slider-item
      _sliderControls = _slider.querySelectorAll('.slider__control'), // элементы управления
      _currentPosition = 0, // позиция левого активного элемента
      _transformValue = 0, // значение трансформации .slider_wrapper
      _transformStep = 100, // величина шага (для трансформации)
      _itemsArray = [], // массив элементов
      _timerId,
      _indicatorItems,
      _indicatorIndex = 0,
      _indicatorIndexMax = _sliderItems.length - 1,
      _config = {
        isAutoplay: false, // автоматическая смена слайдов
        directionAutoplay: 'next', // направление смены слайдов
        delayAutoplay: 5000, // интервал между автоматической сменой слайдов
        isPauseOnHover: true // устанавливать ли паузу при поднесении курсора к слайдеру
      };

    // настройка конфигурации слайдера в зависимости от полученных ключей
    for (var key in config) {
      if (key in _config) {
        _config[key] = config[key];
      }
    }

    // наполнение массива _itemsArray
    for (var i = 0; i < _sliderItems.length; i++) {
      _itemsArray.push({ item: _sliderItems[i], position: i, transform: 0 });
    }

    // переменная position содержит методы, с помощью которой можно получить минимальный и максимальный индекс элемента, а также соответствующему этому индексу позицию
    var position = {
      getItemIndex: function (mode) {
        var index = 0;
        for (var i = 0; i < _itemsArray.length; i++) {
          if ((_itemsArray[i].position < _itemsArray[index].position && mode === 'min') || (_itemsArray[i].position > _itemsArray[index].position && mode === 'max')) {
            index = i;
          }
        }
        return index;
      },
      getItemPosition: function (mode) {
        return _itemsArray[position.getItemIndex(mode)].position;
      }
    };

    // функция, выполняющая смену слайда в указанном направлении
    var _move = function (direction) {
      var nextItem, currentIndicator = _indicatorIndex;;
      if (direction === 'next') {
        _currentPosition++;
        if (_currentPosition > position.getItemPosition('max')) {
          nextItem = position.getItemIndex('min');
          _itemsArray[nextItem].position = position.getItemPosition('max') + 1;
          _itemsArray[nextItem].transform += _itemsArray.length * 100;
          _itemsArray[nextItem].item.style.transform = 'translateX(' + _itemsArray[nextItem].transform + '%)';
        }
        _transformValue -= _transformStep;
        _indicatorIndex = _indicatorIndex + 1;
        if (_indicatorIndex > _indicatorIndexMax) {
          _indicatorIndex = 0;
        }
      } else {
        _currentPosition--;
        if (_currentPosition < position.getItemPosition('min')) {
          nextItem = position.getItemIndex('max');
          _itemsArray[nextItem].position = position.getItemPosition('min') - 1;
          _itemsArray[nextItem].transform -= _itemsArray.length * 100;
          _itemsArray[nextItem].item.style.transform = 'translateX(' + _itemsArray[nextItem].transform + '%)';
        }
        _transformValue += _transformStep;
        _indicatorIndex = _indicatorIndex - 1;
        if (_indicatorIndex < 0) {
          _indicatorIndex = _indicatorIndexMax;
        }
      }
      _sliderContainer.style.transform = 'translateX(' + _transformValue + '%)';
      _indicatorItems[currentIndicator].classList.remove('active');
      _indicatorItems[_indicatorIndex].classList.add('active');
    };

    // функция, осуществляющая переход к слайду по его порядковому номеру
    var _moveTo = function (index) {
      var i = 0, direction = (index > _indicatorIndex) ? 'next' : 'prev';
      while (index !== _indicatorIndex && i <= _indicatorIndexMax) {
        _move(direction);
        i++;
      }
    };

    // функция для запуска автоматической смены слайдов через промежутки времени
    var _startAutoplay = function () {
      if (!_config.isAutoplay) {
        return;
      }
      _stopAutoplay();
      _timerId = setInterval(function () {
        _move(_config.directionAutoplay);
      }, _config.delayAutoplay);
    };

    // функция, отключающая автоматическую смену слайдов
    var _stopAutoplay = function () {
      clearInterval(_timerId);
    };

    // функция, добавляющая индикаторы к слайдеру
    var _addIndicators = function () {
      var indicatorsContainer = document.createElement('ol');
      indicatorsContainer.classList.add('slider__indicators');
      for (var i = 0; i < _sliderItems.length; i++) {
        var sliderIndicatorsItem = document.createElement('li');
        if (i === 0) {
          sliderIndicatorsItem.classList.add('active');
        }
        sliderIndicatorsItem.setAttribute("data-slide-to", i);
        indicatorsContainer.appendChild(sliderIndicatorsItem);
      }
      _slider.appendChild(indicatorsContainer);
      _indicatorItems = _slider.querySelectorAll('.slider__indicators > li')
    };

    // функция, осуществляющая установку обработчиков для событий 
    var _setUpListeners = function () {
      _slider.addEventListener('click', function (e) {
        if (e.target.classList.contains('slider__control')) {
          e.preventDefault();
          _move(e.target.classList.contains('slider__control_next') ? 'next' : 'prev');
          _startAutoplay();
        } else if (e.target.getAttribute('data-slide-to')) {
          e.preventDefault();
          _moveTo(parseInt(e.target.getAttribute('data-slide-to')));
          _startAutoplay();
        }
      });
      document.addEventListener('visibilitychange', function () {
        if (document.visibilityState === "hidden") {
          _stopAutoplay();
        } else {
          _startAutoplay();
        }
      }, false);
      if (_config.isPauseOnHover && _config.isAutoplay) {
        _slider.addEventListener('mouseenter', function () {
          _stopAutoplay();
        });
        _slider.addEventListener('mouseleave', function () {
          _startAutoplay();
        });
      }
    };

    // добавляем индикаторы к слайдеру
    _addIndicators();
    // установливаем обработчики для событий
    _setUpListeners();
    // запускаем автоматическую смену слайдов, если установлен соответствующий ключ
    _startAutoplay();

    return {
      // метод слайдера для перехода к следующему слайду
      next: function () {
        _move('next');
      },
      // метод слайдера для перехода к предыдущему слайду          
      left: function () {
        _move('prev');
      },
      // метод, отключающий автоматическую смену слайдов
      stop: function () {
        _config.isAutoplay = false;
        _stopAutoplay();
      },
      // метод, запускающий автоматическую смену слайдов
      cycle: function () {
        _config.isAutoplay = true;
        _startAutoplay();
      }
    }
  }
}());

slideShow('.slider', {
  isAutoplay: true
});

Код слайдера написан на «чистом» JavaScript, без использования библиотеки jQuery. Программный код структурирован и организован в виде «модуля».

Основные функции, выполняющие всю логику, используемые внутри модуля slideShow:

  • _startAutoplay – функция для запуска автоматической смены слайдов через определённые промежутки времени определяемым параметром delayAutoplay (по умолчанию 5 секунд);
  • _stopAutoplay – функция, отключающая автоматическую смену слайдов;
  • _move – функция, выполняющая смену слайда в указанном направлении;
  • _slideTo – функция, осуществляющая переход к слайду по его порядковому номеру; она используется при обработке события «click» на индикаторах;
  • _addIndicators – функция, добавляющая индикаторы к слайдеру;
  • _setupListener – функция, осуществляющая установку обработчиков для событий для слайдера.

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