суббота, 23 августа 2014 г.

[вёрстка] Делаем для сайта слайдер на CSS. Часть 3.

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

Слайдер с эффектом прокрутки

За основу возьмём код слайдера А из первой статьи. Содержимое кадров слайдера я поместил в отдельный div:

<div class='sliderC'>
    <input type="radio" name="slider1" id="slider1_1" checked="checked">
    <label for="slider1_1"></label>

    <input type="radio" name="slider1" id="slider1_2">
    <label for="slider1_2"></label>

    <input type="radio" name="slider1" id="slider1_3">
    <label for="slider1_3"></label>

    <input type="radio" name="slider1" id="slider1_4">
    <label for="slider1_4"></label>

    <div> <!-- контейнер для кадров -->
        <div>
            <p>Восход над островом</p>
            <img src='https://lh3.googleusercontent.com/-XGgw41OSARk/VePicTdAdgI/AAAAAAAAAS4/WeBbxp4ebQg/s400-Ic42/00099_manaisland_1920x1200.jpg' alt=''>
        </div><div>
            <p>Озёрный край</p>
            <img src='https://lh3.googleusercontent.com/-aafAKIoTkT4/VePihWk2BHI/AAAAAAAAATA/zQVtiYD_eDc/s400-Ic42/00201_lakejipe_1920x1200.jpg' alt=''>
        </div><div>
            <p>Закатная синева</p>
            <img src='https://lh3.googleusercontent.com/-ikbDMRhLc_I/VePkT4XLFtI/AAAAAAAAATg/qaHqQk89RAw/s400-Ic42/00744_laclahachesunset_1920x1200.jpg' alt=''>
        </div><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>

Этот контейнер кадров мы вытянем по горизонтали, и все кадры разместим в нём вплотную один за другим при помощи режима inline-block. Обратите внимание, что между кадрами я удалил все пробелы и переводы строки — открывающий тег следующего кадра прижат к закрывающему тегу предыдущего кадра: </div><div>. Если этого не сделать, пробельные символы создадут нам лишние зазоры между кадрами.

При переключении кадров мы будем сдвигать контейнер кадров так, чтобы в «Ð¾ÐºÐ¾ÑˆÐºÐ¾» слайдера попал соответствующий кадр. Если вы помните, похожим приёмом мы пользовались, когда делали вкладки на сайте для старых браузеров. Ð’ тот раз мы использовали ссылки-якоря, чтобы заставить контейнер вкладок прокрутиться к нужной вкладке. На этот раз мы решим схожую задачу средствами одного лишь CSS.

Для сдвигания контейнера мы будем использовать набор правил CSS следующего вида:

  • По умолчанию отображается первый кадр (left: 0px).
  • Если включена вторая радиокнопка, сдвинуть контейнер на один кадр (left: -100%).
  • Если включена третья радиокнопка, сдвинуть контейнер на два кадра (left: -200%).
  • Если включена четвёртая радиокнопка, сдвинуть контейнер на три кадра (left: -300%).
  • ...и так далее.

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

    .sliderC > div {
        position: absolute;
        top: 0px;
        left: 0px;
        bottom: 0px;
        z-index: 0;
        width: 1000%; /* 100% * 10 кадров. Если вам требуется больше кадров, увеличьте это число. */
        text-align: left;
        transition: left 800ms cubic-bezier(0.77, 0, 0.175, 1) 0s;
    }

    /* По одному правилу для каждого кадра (кроме первого). */
    .sliderC > input:nth-of-type(2):checked ~ div { left: -100%; }
    .sliderC > input:nth-of-type(3):checked ~ div { left: -200%; }
    .sliderC > input:nth-of-type(4):checked ~ div { left: -300%; }
    .sliderC > input:nth-of-type(5):checked ~ div { left: -400%; }
    .sliderC > input:nth-of-type(6):checked ~ div { left: -500%; }
    .sliderC > input:nth-of-type(7):checked ~ div { left: -600%; }
    .sliderC > input:nth-of-type(8):checked ~ div { left: -700%; }
    .sliderC > input:nth-of-type(9):checked ~ div { left: -800%; }
    .sliderC > input:nth-of-type(10):checked ~ div { left: -900%; }

    .sliderC > div > div {
        display: inline-block;
        position: relative;
    }

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

Также я доработал внешний вид слайдера. Я добавил слайдеру белую границу с небольшой тенью и изменил внешний вид кнопок переключения кадров. Итоговый код:

    .sliderC {
        width: 400px;
        height: 250px;
        border: 8px solid #fff;
        box-shadow: 1px 1px 4px #666;
        border-radius: 5px;
        position: relative;
        text-align: center;
        overflow: hidden;
    }

    .sliderC > input {
        display: none;
    }

    .sliderC > input + label {
        width: 10px;
        height: 10px;
        border-radius: 8px;
        background: rgba(90, 90, 90, 0.5);
        border: 2px solid rgba(190, 190, 190, 1);

        cursor: pointer;

        z-index: 100;
        position: relative;

        display: inline-block;
        margin-right: 4px;
        top: 90%;

        transition: border 0.8s ease-out 0s;
    }

    .sliderC > input + label:after {
        content: ' ';
        display: block;
        box-sizing: border-box;
        width: 100%;
        height: 100%;
        border-radius: 8px;
        border: 2px solid rgba(90, 90, 90, 0.8);
        background: rgba(230, 230, 230, 1);
        opacity: 0;
        transition: opacity 0.8s ease-out 0s;
    }

    .sliderC > input + label:hover,
    .sliderC > input:checked + label {
        border: 2px solid rgba(230, 230, 230, 1);
    }

    .sliderC > input:checked + label:after {
        opacity: 1;
    }

    .sliderC > div {
        position: absolute;
        top: 0px;
        left: 0px;
        bottom: 0px;
        z-index: 0;
        width: 1000%; /* 100% * 10 кадров. Если вам требуется больше кадров, увеличьте это число. */
        text-align: left;
        transition: left 800ms cubic-bezier(0.77, 0, 0.175, 1) 0s;
    }

    /* По одному правилу для каждого кадра (кроме первого). */
    .sliderC > input:nth-of-type(2):checked ~ div { left: -100%; }
    .sliderC > input:nth-of-type(3):checked ~ div { left: -200%; }
    .sliderC > input:nth-of-type(4):checked ~ div { left: -300%; }
    .sliderC > input:nth-of-type(5):checked ~ div { left: -400%; }
    .sliderC > input:nth-of-type(6):checked ~ div { left: -500%; }
    .sliderC > input:nth-of-type(7):checked ~ div { left: -600%; }
    .sliderC > input:nth-of-type(8):checked ~ div { left: -700%; }
    .sliderC > input:nth-of-type(9):checked ~ div { left: -800%; }
    .sliderC > input:nth-of-type(10):checked ~ div { left: -900%; }

    .sliderC > div > div {
        display: inline-block;
        position: relative;
    }

    .sliderC > div > div > p {
        position: absolute;
        top: 0px;
        left: 0px;
        right: 0px;
        text-align: center;
        color: #fff;
        text-shadow: 1px 1px 2px #000;
    }

Вот такой слайдер у нас получился:

Восход над островом

Озёрный край

Закатная синева

Сельский пейзаж

Слайдер с эффектом прокрутки и стрелками «Ð’перёд» и «ÐÐ°Ð·Ð°Ð´»

Мы можем объединить слайдер с прокруткой и слайдер со стрелками, который мы создали во второй статье о слайдерах. Здесь я тоже слегка изменил оформление стрелок, чтобы не повторяться и показать вам больше вариантов. На этот раз оформим стрелки в виде изображений. Код:

<style>
    .sliderC2 {
        width: 400px;
        height: 250px;
        border: 8px solid #fff;
        box-shadow: 1px 1px 4px #666;
        border-radius: 5px;
        position: relative;
        text-align: center;
        overflow: hidden;
    }

    .sliderC2 > input {
        display: none;
    }

    .sliderC2 > input + label,
    .sliderC2 > input + label + label {
        display: none;
    }


    .sliderC2 > input:checked + label,
    .sliderC2 > input:checked + label + label {
        display: block;
        width: 50px;
        height: 50px;

        opacity: 0.4;
        transition: opacity 0.8s ease-out 0s;

        cursor: pointer;

        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        z-index: 100;
    }

    .sliderC2 > input:checked + label:hover,
    .sliderC2 > input:checked + label + label:hover {
        opacity: 0.6;
    }


    .sliderC2 > input:checked + label {
        left: 0px;
        background: url('https://lh3.googleusercontent.com/-tacAA4lVYgc/VeVDqFrDRRI/AAAAAAAAAT4/RBongekAUqI/s800-Ic42/prev.png')
    }

    .sliderC2 > input:checked + label + label {
        right: 0px;
        background: url('https://lh3.googleusercontent.com/-gy6RMZnCdAc/VeVDqJF1S5I/AAAAAAAAAT0/D4nN8T9RGro/s800-Ic42/next.png')
    }


    .sliderC2 > div {
        position: absolute;
        top: 0px;
        left: 0px;
        bottom: 0px;
        z-index: 0;
        width: 1000%;
        text-align: left;
        transition: left 800ms cubic-bezier(0.77, 0, 0.175, 1) 0s;
    }

    .sliderC2 > input:nth-of-type(2):checked ~ div { left: -100%; }
    .sliderC2 > input:nth-of-type(3):checked ~ div { left: -200%; }
    .sliderC2 > input:nth-of-type(4):checked ~ div { left: -300%; }
    .sliderC2 > input:nth-of-type(5):checked ~ div { left: -400%; }
    .sliderC2 > input:nth-of-type(6):checked ~ div { left: -500%; }
    .sliderC2 > input:nth-of-type(7):checked ~ div { left: -600%; }
    .sliderC2 > input:nth-of-type(8):checked ~ div { left: -700%; }
    .sliderC2 > input:nth-of-type(9):checked ~ div { left: -800%; }
    .sliderC2 > input:nth-of-type(10):checked ~ div { left: -900%; }

    .sliderC2 > div > div {
        display: inline-block;
        position: relative;
    }

    .sliderC2 > div > div > p {
        position: absolute;
        top: 0px;
        left: 0px;
        right: 0px;
        text-align: center;
        color: #fff;
        text-shadow: 1px 1px 2px #000;
    }
</style>

<div class='sliderC2'>
    <input type="radio" name="slider2" id="slider2_1" checked="checked">
    <label for="slider2_4"></label>
    <label for="slider2_2"></label>

    <input type="radio" name="slider2" id="slider2_2">
    <label for="slider2_1"></label>
    <label for="slider2_3"></label>

    <input type="radio" name="slider2" id="slider2_3">
    <label for="slider2_2"></label>
    <label for="slider2_4"></label>

    <input type="radio" name="slider2" id="slider2_4">
    <label for="slider2_3"></label>
    <label for="slider2_1"></label>

    <div>
        <div>
            <p>Восход над островом</p>
            <img src='https://lh3.googleusercontent.com/-XGgw41OSARk/VePicTdAdgI/AAAAAAAAAS4/WeBbxp4ebQg/s400-Ic42/00099_manaisland_1920x1200.jpg' alt=''>
        </div><div>
            <p>Озёрный край</p>
            <img src='https://lh3.googleusercontent.com/-aafAKIoTkT4/VePihWk2BHI/AAAAAAAAATA/zQVtiYD_eDc/s400-Ic42/00201_lakejipe_1920x1200.jpg' alt=''>
        </div><div>
            <p>Закатная синева</p>
            <img src='https://lh3.googleusercontent.com/-ikbDMRhLc_I/VePkT4XLFtI/AAAAAAAAATg/qaHqQk89RAw/s400-Ic42/00744_laclahachesunset_1920x1200.jpg' alt=''>
        </div><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>

Результат:

Восход над островом

Озёрный край

Закатная синева

Сельский пейзаж

Если вам не нравится сквозная прокрутка (с последнего на первый кадр и с первого на последний), можно присвоить соответствующим меткам стиль visibility: hidden прямо в коде HTML. Вот что получится:

Восход над островом

Озёрный край

Закатная синева

Сельский пейзаж

Собираем всё вместе: вариант слайдера с двумя видами кнопок

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

<style>
    .sliderC3 {
        width: 400px;
        height: 250px;
        border: 8px solid #fff;
        box-shadow: 1px 1px 4px #666;
        border-radius: 5px;
        position: relative;
        text-align: center;
        overflow: hidden;
    }

    .sliderC3 > input {
        display: none;
    }

    .sliderC3 > input + label {
        width: 10px;
        height: 10px;
        border-radius: 8px;
        background: rgba(90, 90, 90, 0.5);
        border: 2px solid rgba(190, 190, 190, 1);

        cursor: pointer;

        z-index: 100;
        position: relative;

        display: inline-block;
        margin-right: 4px;
        top: 90%;

        transition: border 0.8s ease-out 0s;
    }

    .sliderC3 > input + label:after {
        content: ' ';
        display: block;
        box-sizing: border-box;
        width: 100%;
        height: 100%;
        border-radius: 8px;
        border: 2px solid rgba(90, 90, 90, 0.8);
        background: rgba(230, 230, 230, 1);
        opacity: 0;
        transition: opacity 0.8s ease-out 0s;
    }

    .sliderC3 > input + label:hover,
    .sliderC3 > input:checked + label {
        border: 2px solid rgba(230, 230, 230, 1);
    }

    .sliderC3 > input:checked + label:after {
        opacity: 1;
    }

    .sliderC3 > input + label + label,
    .sliderC3 > input + label + label + label {
        display: none;
    }


    .sliderC3 > input:checked + label + label,
    .sliderC3 > input:checked + label + label + label {
        display: block;
        width: 50px;
        height: 50px;

        opacity: 0.4;
        transition: opacity 0.8s ease-out 0s;

        cursor: pointer;

        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        z-index: 100;
    }

    .sliderC3 > input:checked + label + label:hover,
    .sliderC3 > input:checked + label + label + label:hover {
        opacity: 0.6;
    }

    .sliderC3 > input:checked + label + label {
        left: 0px;
        background: url('https://lh3.googleusercontent.com/-tacAA4lVYgc/VeVDqFrDRRI/AAAAAAAAAT4/RBongekAUqI/s800-Ic42/prev.png')
    }

    .sliderC3 > input:checked + label + label + label {
        right: 0px;
        background: url('https://lh3.googleusercontent.com/-gy6RMZnCdAc/VeVDqJF1S5I/AAAAAAAAAT0/D4nN8T9RGro/s800-Ic42/next.png')
    }

    .sliderC3 > div {
        position: absolute;
        top: 0px;
        left: 0px;
        bottom: 0px;
        z-index: 0;
        width: 1000%;
        text-align: left;
        transition: left 800ms cubic-bezier(0.77, 0, 0.175, 1) 0s;
    }

    .sliderC3 > input:nth-of-type(2):checked ~ div { left: -100%; }
    .sliderC3 > input:nth-of-type(3):checked ~ div { left: -200%; }
    .sliderC3 > input:nth-of-type(4):checked ~ div { left: -300%; }
    .sliderC3 > input:nth-of-type(5):checked ~ div { left: -400%; }
    .sliderC3 > input:nth-of-type(6):checked ~ div { left: -500%; }
    .sliderC3 > input:nth-of-type(7):checked ~ div { left: -600%; }
    .sliderC3 > input:nth-of-type(8):checked ~ div { left: -700%; }
    .sliderC3 > input:nth-of-type(9):checked ~ div { left: -800%; }
    .sliderC3 > input:nth-of-type(10):checked ~ div { left: -900%; }

    .sliderC3 > div > div {
        display: inline-block;
        position: relative;
    }

    .sliderC3 > div > div > p {
        position: absolute;
        top: 0px;
        left: 0px;
        right: 0px;
        text-align: center;
        color: #fff;
        text-shadow: 1px 1px 2px #000;
    }
</style>

<div class='sliderC3'>
    <input type="radio" name="slider4" id="slider4_1" checked="checked">
    <label for="slider4_1"></label>
    <label for="slider4_4"></label>
    <label for="slider4_2"></label>

    <input type="radio" name="slider4" id="slider4_2">
    <label for="slider4_2"></label>
    <label for="slider4_1"></label>
    <label for="slider4_3"></label>

    <input type="radio" name="slider4" id="slider4_3">
    <label for="slider4_3"></label>
    <label for="slider4_2"></label>
    <label for="slider4_4"></label>

    <input type="radio" name="slider4" id="slider4_4">
    <label for="slider4_4"></label>
    <label for="slider4_3"></label>
    <label for="slider4_1"></label>

    <div>
        <div>
            <p>Восход над островом</p>
            <img src='https://lh3.googleusercontent.com/-XGgw41OSARk/VePicTdAdgI/AAAAAAAAAS4/WeBbxp4ebQg/s400-Ic42/00099_manaisland_1920x1200.jpg' alt=''>
        </div><div>
            <p>Озёрный край</p>
            <img src='https://lh3.googleusercontent.com/-aafAKIoTkT4/VePihWk2BHI/AAAAAAAAATA/zQVtiYD_eDc/s400-Ic42/00201_lakejipe_1920x1200.jpg' alt=''>
        </div><div>
            <p>Закатная синева</p>
            <img src='https://lh3.googleusercontent.com/-ikbDMRhLc_I/VePkT4XLFtI/AAAAAAAAATg/qaHqQk89RAw/s400-Ic42/00744_laclahachesunset_1920x1200.jpg' alt=''>
        </div><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>

Финальный слайдер:

Восход над островом

Озёрный край

Закатная синева

Сельский пейзаж

4 комментария

Анатолий

А почему может не работать в записи в вордпресс? Создаю чистый html всё работает, в записи нет. Предполагаю проблема с CSS от темы, но я всем div input label добавил свой класс div.slid - <div class="slid"

Дмитрий

Здравствуйте!
Отличная статья. Все сделал, все получилось.
Один вопрос - как сделать это слайдер "резиновым"?

Дмитрий

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

Анонимный

Я Хелена Хулио из Эквадора, я хочу хорошенько поговорить о мистере Педро на эту тему.
Г-н Педро и его кредитная компания оказывают мне финансовую поддержку, когда все банки в моем городе отклонили мою просьбу предоставить мне ссуду в размере 500 000,00 долларов США, я старался изо всех сил, чтобы получить ссуду в своих банках здесь, в Эквадоре, но все они мне отказали потому что мой кредит был низким, но с Божьей милостью я узнал о мистере Педро на платформе ссуды, поэтому я решил попробовать подать заявку на ссуду. С Божьей помощью они предоставили мне ссуду в размере 500 000,00 долларов США. В просьбе о ссуде, в которой мне отказали мои банки здесь, в Эквадоре, было действительно здорово вести с ними дела, и мой бизнес сейчас идет хорошо. Электронная почта / контакт, если вы хотите подать заявку на ссуду от них.
[email protected]

Отправить комментарий