Авторизация







Регистрация / Забыли пароль?

Регистрация нового пользователя











< Назад

Восстановление пароля





< Назад

Добро пожаловать

Выход


Ежедневное обновление статей и уроков, будь в курсе, держи руку на пульсе событий!

Главная >> CSS

Как создать простой мульти-слайдер товара для интернет-магазина

Урок есть и в видеоформате! Смотреть?

Статья о том, как создать простой слайдер категорий, с минимальным дизайном с помощью CSS-анимации и jQuery. Идея заключается в том, чтобы визуально, последовательно, в зависимости от выбранной категории товара, дать человеку всю необходимую информацию.


    В сегодняшнем уроке, давайте займёмся созданием простого слайдера для интернет-магазина. Для его воплощения, мы будем использовать CSS-анимацию, и некоторый jQuery код. Сама идея, была навеяна слайдером компании Apple, и хотелось бы реализовать её в виде альтернативного минималистичного плагина, для интернет магазина в котором есть категории товаров.  Количество категорий будет ограничено, но если вы хотите их разнообразить, то сделать это вы сможете легко, просто добавив необходимые элементы и написав необходимые стили.

    РАЗМЕТКА

    В HTML мы будем использовать  неупорядоченные списки, в которых будут содержаться элементы и навигационные ссылки для категорий. Каждый элемент списка будет иметь ссылку, содержащую изображение, и H4 заголовок.

<div id="mi-slider" class="mi-slider">
    <ul>
        <li><a href="#"><img src="images/1.jpg" alt="img01"><h4>Сапоги</h4></a></li>
        <li><a href="#"><img src="images/2.jpg" alt="img02"><h4>Полуботинки</h4></a></li>
        <li><a href="#"><img src="images/3.jpg" alt="img03"><h4>Туфли</h4></a></li>
        <li><a href="#"><img src="images/4.jpg" alt="img04"><h4>Кроссовки</h4></a></li>
    </ul>
    <ul>
        <li><a href="#"><img src="images/5.jpg" alt="img05"><h4>Ремни</h4></a></li>
        <li><a href="#"><img src="images/6.jpg" alt="img06"><h4>Шляпы &amp; Шапки</h4></a></li>
        <li><a href="#"><img src="images/7.jpg" alt="img07"><h4>Солнцезащитные очки</h4></a></li>
        <li><a href="#"><img src="images/8.jpg" alt="img08"><h4>Шарфы</h4></a></li>
    </ul>
    <ul>
        <li><a href="#"><img src="images/9.jpg" alt="img09"><h4>Повседневные</h4></a></li>
        <li><a href="#"><img src="images/10.jpg" alt="img10"><h4>Люкс</h4></a></li>
        <li><a href="#"><img src="images/11.jpg" alt="img11"><h4>Спортивные</h4></a></li>
    </ul>
    <ul>
        <li><a href="#"><img src="images/12.jpg" alt="img12"><h4>Для путешествий</h4></a></li>
        <li><a href="#"><img src="images/13.jpg" alt="img13"><h4>Повседневная</h4></a></li>
        <li><a href="#"><img src="images/14.jpg" alt="img14"><h4>Наручные сумки</h4></a></li>
        <li><a href="#"><img src="images/15.jpg" alt="img15"><h4>Портфели</h4></a></li>
    </ul>
    <nav>
        <a href="#">Обувь</a>
        <a href="#">Аксессуары</a>
        <a href="#">Часы</a>
        <a href="#">Сумки</a>
    </nav>
</div>

    CSS

    Обратите внимание, CSS приведённый в уроке,  не содержит каких-либо префиксов, но вы их сможете найти в файле с демонстрацией примера. Вот что мы будем здесь делать: изначально, мы показываем первый список, в то время как остальные, будут далеко справа и их будет не видно. По нажатию на элементы  навигации категорий, в зависимости от того места где мы находимся, будут показываться другие списки, т.е. будет происходить смена.

    Для начала, давайте создадим необходимый стиль для блока с классом mi-slider. В нём будет определена необходимая высота и отступ, которые нам нужны, чтобы правильно отображался плагин.

.mi-slider {
    position: relative;
    margin-top: 30px;
    height: 490px;
}

    Списки UL, будут позиционироваться абсолютно, что означает, что они будут как бы накладываться друг на друга. Элементы же списка, будут располагаться один за другим как и раньше. Давайте установим так же pointer-events, при этом элемент перестанет реагировать на hover, click и другие события мыши. Он станет «прозрачным» для взаимодействия, а hover и click будут передаваться элементу, лежащему под ним.

.mi-slider ul {
    list-style-type: none;
    position: absolute;
    width: 100%;
    left: 0;
    bottom: 140px;
    overflow: hidden;
    text-align: center;
    pointer-events: none;
}

    Актуальный спискок следует сбросить, так чтобы, содержащиеся в нём ссылки стали кликабельны:

.mi-slider ul.mi-current {
    pointer-events: auto;
}

    Если JavaScript у пользователя отключен, то мы ничего не сможем увидеть (поэтому мы используем Modernizr):

.no-js .mi-slider ul {
    position: relative;
    left: auto;
    bottom: auto;
    margin: 0;
    overflow: visible;
}

    Для того чтобы центровать  все элементы списка, мы передали им text-align: center, а сейчас, давайте всем элементам li установим свойство inline-block и ширину в 20%. Эти значения создадут уверенность, в том, что наши элементы, будут находиться в списке, и не выйдут из него при масштабировании и т.д.

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

.mi-slider ul li {
    display: inline-block;
    padding: 20px;
    width: 20%;
    max-width: 300px;
    transform: translateX(600%);
    transition: opacity 0.2s linear;
}

    В случае если у пользователя отключен JavaScript, трансформацию мы производить не будем:

.no-js .mi-slider ul li {
    transform: translateX(0);
}

    Давайте займёмся стилями для элементов списка. Обратите внимание, мы устанавливаем max-width изображения в 100%. Это будет гарантировать целостность макета, но изображение будет такого же размера как wrapper, который является нашим элементом меню с шириной указанной в %.

.mi-slider ul li a,
.mi-slider ul li img {
    display: block;
    margin: 0 auto;
}
 
.mi-slider ul li a {
    outline: none;
    cursor: pointer;
}
 
.mi-slider ul li img {
    max-width: 100%;
    border: none;
}
 
.mi-slider ul li h4 {
    display: inline-block;
    font-family: Baskerville, "Baskerville Old Face", "Hoefler Text", Garamond, "Times New Roman", serif;
    font-style: italic;
    font-weight: 400;
    font-size: 18px;
    padding: 20px 10px 0;
}

    При наведении курсора, происходит изменение прозрачности элемента списка:

.mi-slider ul li:hover {
    opacity: 0.7;
}

    Наша навигация, расположена абсолютно, поэтому ей нужно ввести отступ сверху, чтобы она не располагалась под элементами категорий. А для того чтобы выровнять по центу, давайте зададим ей отступы, давая боковым значениям параметр auto, и зададим максимальную ширину в 800px.

.mi-slider nav {
    position: relative;
    top: 400px;
    text-align: center;
    max-width: 800px;
    margin: 0 auto;
    border-top: 5px solid #333;
}

    Мы не будем показывать навигацию, если у пользователя отключен JavaScript:

.no-js nav {
    display: none;
}

    Навигационным ссылкам назначим большие внутренние отступы, и создадим стиль для события hover:

.mi-slider nav a {
    display: inline-block;
    text-transform: uppercase;
    letter-spacing: 5px;
    padding: 40px 30px 30px 34px;
    position: relative;
    color: #888;
    outline: none;
    transition: color 0.2s linear;
}
 
.mi-slider nav a:hover,
.mi-slider nav a.mi-selected {
    color: #000;
}

    Классы mi-selected и mi-current мы будем назначать с помощью JavaScript.

    А сейчас, давайте добавим маленькие стрелки сверху актуальной категории. Мы будем использовать псевдо – классы :before и :after для создания двух треугольников с границами:

.mi-slider nav a.mi-selected:after,
.mi-slider nav a.mi-selected:before {
    content: '';
    position: absolute;
    top: -5px;
    border: solid transparent;
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
}
 
.mi-slider nav a.mi-selected:after {
    border-color: transparent;
    border-top-color: #fff;
    border-width: 20px;
    left: 50%;
    margin-left: -20px;
}
 
.mi-slider nav a.mi-selected:before {
    border-color: transparent;
    border-top-color: #333;
    border-width: 27px;
    left: 50%;
    margin-left: -27px;
}

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

.mi-slider ul:first-child li,
.no-js .mi-slider ul li {
    animation: scaleUp 350ms ease-in-out both;
}
 
@keyframes scaleUp {
    0% { transform: translateX(0) scale(0); }
    100% { transform: translateX(0) scale(1); }
}

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

.mi-slider ul:first-child li:first-child {
    animation-delay: 90ms;
}
 
.mi-slider ul:first-child li:nth-child(2) {
    animation-delay: 180ms;
}
 
.mi-slider ul:first-child li:nth-child(3) {
    animation-delay: 270ms;
}
 
.mi-slider ul:first-child li:nth-child(4) {
    animation-delay: 360ms;
}

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

    Для анимации смены элементов, мы будем использовать четыре случая: два, для скольжения новых элементов и два, для скольжения текущих элементов, в зависимости от направления. Так, мы определим четыре класса для списков, которые добавим с помощью JavaScript:

/* движение с правой  стороны*/
 
.mi-slider ul.mi-moveFromRight li {
    animation: moveFromRight 350ms ease-in-out both;
}
 
/* движение с левой  стороны */
 
.mi-slider ul.mi-moveFromLeft li {
    animation: moveFromLeft 350ms ease-in-out both;
}
 
/* движение вправо */
 
.mi-slider ul.mi-moveToRight li {
    animation: moveToRight 350ms ease-in-out both;
}
 
/* движение слева */
 
.mi-slider ul.mi-moveToLeft li {
    animation: moveToLeft 350ms ease-in-out both;
}

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

.mi-slider ul.mi-moveToLeft li:first-child,
.mi-slider ul.mi-moveFromRight li:first-child,
.mi-slider ul.mi-moveToRight li:nth-child(4),
.mi-slider ul.mi-moveFromLeft li:nth-child(4) {
    animation-delay: 0ms;
}

    Увеличение задержки будет назначено соответственно:

.mi-slider ul.mi-moveToLeft li:nth-child(2),
.mi-slider ul.mi-moveFromRight li:nth-child(2),
.mi-slider ul.mi-moveToRight li:nth-child(3),
.mi-slider ul.mi-moveFromLeft li:nth-child(3) {
    -webkit-animation-delay: 90ms;
    animation-delay: 90ms;
}
 
.mi-slider ul.mi-moveToLeft li:nth-child(3),
.mi-slider ul.mi-moveFromRight li:nth-child(3),
.mi-slider ul.mi-moveToRight li:nth-child(2),
.mi-slider ul.mi-moveFromLeft li:nth-child(2) {
    -webkit-animation-delay: 180ms;
    animation-delay: 180ms;
}
 
.mi-slider ul.mi-moveToLeft li:nth-child(4),
.mi-slider ul.mi-moveFromRight li:nth-child(4),
.mi-slider ul.mi-moveToRight li:first-child,
.mi-slider ul.mi-moveFromLeft li:first-child  {
    -webkit-animation-delay: 270ms;
    animation-delay: 270ms;
}

    А теперь, давайте определимся с анимацией движения. Например, для перехода справа translateX устанавливаем от 600% до 0. Двигаясь слева, мы зададим начальное значение от -600%, таким образом, элементы в левой стороне, останутся вне зоны просмотра. И так далее:

@keyframes moveFromRight {
    0% { transform: translateX(600%); }
    100% { transform: translateX(0); }
}
 
@keyframes moveFromLeft {
    0% { transform: translateX(-600%); }
    100% { transform: translateX(0); }
}
 
@keyframes moveToRight {
    0% { transform: translateX(0%); }
    100% { transform: translateX(600%); }
}
 
@keyframes moveToLeft {
    0% { transform: translateX(0%); }
    100% { transform: translateX(-600%); }
}

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

@media screen and (max-width: 910px){
    .mi-slider nav {
        max-width: 90%;
    }
 
    .mi-slider nav a {
        font-size: 12px;
        padding: 40px 10px 30px 14px;
    }
}

    Поскольку мы установили фиксированную высоту для блока, мы хотим, убедиться, что он адаптируется правильно:

@media screen and (max-width: 740px){
    .mi-slider {
        height: 300px;
    }
 
    .mi-slider nav {
        top: 220px;
    }
}

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

@media screen and (max-width: 490px){ 
    .mi-slider {
        text-align: center;
        height: auto;
    }
 
    .mi-slider ul {
        position: relative;
        display: inline;
        bottom: auto;
        pointer-events: auto;
    }
 
    .mi-slider ul li {
        animation: none !important;
        transform: translateX(0) !important;
        padding: 10px 3px;
        min-width: 140px;
    }
 
    .mi-slider nav {
        display: none;
    }
}

    Со стилями всё. А сейчас, давайте перейдём к контролю со стороны jQuery.

    JAVASCRIPT

    Давайте создадим простой jQuery плагин для нашего слайдера. Большую часть работы, берёт на себя CSS, где мы определили всю анимацию. В основном, наш плагин посвящён добавлению и удалению классов, а так же контролю за актуальной категорией. Для браузеров, которые не поддерживают анимацию, мы будем возвращать простой переход, в виде скрыть/показать.

    Давайте начнём с того, что закэшируем некоторые из элементов, и инициализируем необходимые переменные:

_init : function( options ) {
 
    // категории (ul)
    this.$categories = this.$el.children( 'ul' );
    // навигация
    this.$navcategories = this.$el.find( 'nav > a' );
    var animEndEventNames = {
        'WebkitAnimation' : 'webkitAnimationEnd',
        'OAnimation' : 'oAnimationEnd',
        'msAnimation' : 'MSAnimationEnd',
        'animation' : 'animationend'
    };
    // префикс анимация для конца наименования события
    this.animEndEventName = animEndEventNames[ Modernizr.prefixed( 'animation' ) ];
    // поддержка анимации и трансформации
    this.support = Modernizr.csstransforms && Modernizr.cssanimations;
    // если в настоящее время происходит анимация
    this.isAnimating = false;
    // текущая категория
    this.current = 0;
    var $currcat = this.$categories.eq( 0 );
    if( !this.support ) {
        this.$categories.hide();
        $currcat.show();
    }
    else {
        $currcat.addClass( 'mi-current' );
    }
    // актуальная nav категория
    this.$navcategories.eq( 0 ).addClass( 'mi-selected' );
    // инициализация событий
    this._initEvents();
 
}

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

_initEvents : function() {
 
    var self = this;
    this.$navcategories.on( 'click.catslider', function() {
        self.showCategory( $( this ).index() );
        return false;
    } );
 
    // сброс на изменения размеров окна..
    $( window ).on( 'resize', function() {
        self.$categories.removeClass().eq( 0 ).addClass( 'mi-current' );
        self.$navcategories.eq( self.current ).removeClass( 'mi-selected' ).end().eq( 0 ).addClass( 'mi-selected' );
        self.current = 0;
    } );
 
}
 
showCategory : function( catidx ) {
 
    if( catidx === this.current || this.isAnimating ) {
        return false;
    }
    this.isAnimating = true;
    // обновление выбранной навигации
    this.$navcategories.eq( this.current ).removeClass( 'mi-selected' ).end().eq( catidx ).addClass( 'mi-selected' );
 
    var dir = catidx > this.current ? 'right' : 'left',
        toClass = dir === 'right' ? 'mi-moveToLeft' : 'mi-moveToRight',
        fromClass = dir === 'right' ? 'mi-moveFromRight' : 'mi-moveFromLeft',
        // текущая категория
        $currcat = this.$categories.eq( this.current ),
        // новая категория
        $newcat = this.$categories.eq( catidx ),
        $newcatchild = $newcat.children(),
        lastEnter = dir === 'right' ? $newcatchild.length - 1 : 0,
        self = this;
 
    if( this.support ) {
 
        $currcat.removeClass().addClass( toClass );
         
        setTimeout( function() {
 
            $newcat.removeClass().addClass( fromClass );
            $newcatchild.eq( lastEnter ).on( self.animEndEventName, function() {
 
                $( this ).off( self.animEndEventName );
                $newcat.addClass( 'mi-current' );
                self.current = catidx;
                var $this = $( this );
                // решить ошибку chrome
                self.forceRedraw( $this.get(0) );
                self.isAnimating = false;
 
            } );
 
        }, $newcatchild.length * 90 );
 
    }
    else {
 
        $currcat.hide();
        $newcat.show();
        this.current = catidx;
        this.isAnimating = false;
 
    }
 
}

    Вот и все! Надеюсь, вам понравилась эта статья, и вы нашли  её полезной и вдохновляющей!

    Материал взят из зарубежного источника. И представлен исключительно в ознакомительных целях.


Дата публикации: 25.02.2013
Опубликовал: Сергей Кашурин
Просмотров: 784
Правила перепечатки

Правила перепечатки

Уважаемый посетитель сайта!
Ниже преведены условия использования и перепечатки материалов сайта /
Все материалы данного сайта подготовлены для Вас лично мной.

Большая часть материалов сайта - это авторские уроки, остальные, это переводы уроков с английского языка на русский.
Если Вы решили использовать материалы данного сайта где-то на своих ресурсах или в рассылке, то соблюдайте следующие требования:
1. Урок или статья должны перепечатываться «как есть» с сохранением всех ссылок на источник урока, а если это перевод, то и на сайт, авторы которого подготовили его.
2. Ссылки на сайт источника и переводчика обязательно должны быть работоспособными (при нажатии по ссылке человек должен перейти на сайт автора/переводчика). Если Вы перепечатали какой-либо документ, обязательно проверьте ссылку на работоспособность.
3. Искажение информации об авторе, источнике, переводчике при перепечатке материалов запрещено!
4. Содержание урока или статьи при перепечатке не должно подвергаться модификациям и переделке. Все уроки и статьи, размещенные на сайте, должны перепечатываться как есть. Вы не имеете права урезать, исправлять или иным образом коверкать републикуемый документ.
С уважением, Сергей Кашурин– владелец сайта /


110 бесплатных PSD элементов, для ваших слайдеров, лент, выпадающих меню навигации и аудио видео проигрывателей
Используйте бесплатно распространяемую графику, вместо того, чтобы тратить ваше драгоценное время, особенно, когда дело доходит до веб дизайна. Ведь его вы можете потратить на более нужные вещи, такие как проявление творчества. Чтобы сделать из вашего проекта конфетку, ниже приведены 110 бесплатных PSD элементов для создания слайдеров, лент, выпадающих меню навигации и аудио видео проигрывателей, полученных нами с различных веб-сайтов и отдельных лиц, которые вносят вклад в графику для дизайнеров, абсолютно бесплатно.
5 прекраснейших дизайнерских решений для ваших форм входа
Уважаемые друзья, в этом уроке, собраны 5 красивейших форм регистрации/авторизации, с пошаговым объяснением, и с возможность бесплатно скачать. Вы всё ещё думаете читать или нет? А кто-то уже вовсю пользуется ими!
24 классных PHP библиотеки, о которых вы должны знать
Для PHP-разработчика, и времени лучшего не придумаешь чем сейчас. Ведь каждый день, появляются всё новые и новые вспомогательные элементы, такие, как например полезные библиотеки.

Уроки и статьи

«Найден Самый Дешевый и Эффективный Способ Рекламы в Интернете!»

Доказанo: ведение своей почтовой рассылки - это самый действенный и дешевый метод рекламы в Интернете.

Используете ли Вы его?

Если нет, то Вы давно теряете свои деньги! Если да, то пришло время вести Вашу почтовую рассылку на самом эффективном инструменте в Рунете - сервисе рассылок SmartResponder.ru

Узнать об этом подробнее >>

Быть в курсе всех событий: