Как создать современный lightbox на CSS3 и JavaScript

На сегодняшний день, lightbox по прежнему остается излюбленным способом показа изображений для пользователя. Это прежде всего, связано с его 3D-анимаций и затемнённым фоном, который позволяет пользователю просматривать изображения не отвлекаясь на посторонние детали.

Сложность

css lightbox

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

В данном руководстве я не объясняю все детали кода, что бы не запутать читателя. Вместо этого, я расскажу некоторые из основных концепций создания современного CSS lightbox. Таким образом, вы сможете использовать эти идеи в своем собственном проекте.

CSS и Лайтбокс

Начнем с HTML:

css лайтбокс

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

Полноразмерное изображение должно быть установлено вместе со свойством display: none, так что начальным состоянием для пользователя будет только миниатюра:

css lightbox

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

Для этого нужно использовать определенные JavaScript события. Поменяем небольшую часть кода в CSS:

var thumbnail = document.querySelector(".first-image img");
var fullSize = document.querySelector(".second-image img");

thumbnail.onclick = function () {

    fullSize.style.display = "block";

}

Сейчас используем события JavaScript в CSS для псевдо-класса :target. Я не знаю, чьей идеей было представить :target в спецификацию CSS3, но его включение стало значительным шагом в разработке веб-проектов.

.second-image dl:target {
    display: block;
}

Псевдо-класс :target работает с использованием фрагмента URL. Ссылка на эскиз имеет следующий фрагмент: #block-1. Это идентификатор полного размера блока-1. При нажатии на ссылку с фрагментом, запускается HTML с его ID, конечно до тех пор, пока вы не укажите его в таблице стилей.

Потому что он отличается от других CSS стилей, псевдо-класс :target может показаться немного странным на первый взгляд. Лучший способ познакомиться с ним это применять его на практике в своих собственных проектах.

В будущем псевдо-класс:target станет одной из наиболее часто используемых функций в CSS3. Правда у него есть один минус, он не поддерживается в  IE 8 и ниже. Я расскажу вам как использовать его альтернативу в следующем разделе.

CSS keyframe довольно прост:

/* анимация основного изображения */
.second-image dl:target .animation {
    -moz-animation: image3D 2000ms cubic-bezier(0.950,0.050,0.795,0.035);
    -webkit-animation: image3D 2000ms cubic-bezier(0.950,0.050,0.795,0.035);
    -ms-animation: image3D 2000ms cubic-bezier(0.950,0.050,0.795,0.035);
    -o-animation: image3D 2000ms cubic-bezier(0.950,0.050,0.795,0.035);
    animation: image3D 2000ms cubic-bezier(0.950,0.050,0.795,0.035);
}

/* 3D эфект изображения */
@-moz-keyframes image3D {
    0% {
       -moz-transform: rotateY(90deg);
    }

    100% {
       -moz-transform: rotateY(0deg);
    }
}

@-webkit-keyframes image3D {
    0% {
       -webkit-transform: rotateY(90deg);
    }

    100% {
       -webkit-transform: rotateY(0deg);
    }
}

@-o-keyframes image3D {
    0% {
       -o-transform: rotateY(90deg);
    }

    100% {
       -o-transform: rotateY(0deg)
    }
}

@-ms-keyframes image3D {
    0% {
       -ms-transform: rotateY(90deg);
    }

    100% {
       -ms-transform: rotateY(0deg);
    }
}

@keyframes image3D {
    0% {
       transform: rotateY(90deg);
    }

    100% {
       transform: rotateY(0deg);
    }
}

Я не буду подробно объяснять весь код, приведенный выше, потому что эта статья не является руководством по CSS3 анимации.

Обратите внимание, в выше указанном коде я использовал Webkit, Firefox, Microsoft и Opera префиксы. Пока нет поддержки keyframes в Internet Explorer или Opera.

JavaScript и Lightbox

Я использовал box-shadows, функцию Calc () , градиенты и CSS3 transforms rotate. Если отключить JavaScript в браузере и попробовать запустить демо в современных браузерах, вы увидите, что оно находится в рабочем состоянии.

Тем не менее, есть некоторые трудности с CSS3, к которым мы будем применять дополнительные методы.

Во-первых,  CSS3 анимация срабатывает только один раз.

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

Сейчас нужно удалить старый класс в методе change_animation (), дублировать соответствующую часть из DOM, добавить дополнительный класс, удалить интернет узел и заменить его дубликатом  DOM:

change_animation: function (htmlElement) {

    var items, random, regEx, result, key, mainBlock, cloneBlock, parentBlock;

    function removeArrayElement(element, index, array) {
       return (!element.search(_private.REMOVE_SEARCH));
    }

    regEx = /.([0-9]+)$/;
    result = regEx.exec(htmlElement.parentNode);
    key = result.filter(removeArrayElement).toString();

    mainBlock = document.querySelector("#block-" + key + " img");

    mainBlock.removeAttribute("class", "");

    cloneBlock = mainBlock.cloneNode(true);

    items = this.classes;
    random = items[Math.floor(Math.random() * items.length)];
    
    cloneBlock.setAttribute("class", random);

    parentBlock = mainBlock.parentNode;
    parentBlock.removeChild(mainBlock);
    parentBlock.appendChild(cloneBlock);

}

Я уверен, что можно было написать не такой большой код, если бы мы использовали JQuery.

Пользовательский интерфейс:

lightbox.init({
   classes: ['image3D', 'flipper', 'bulge', 'bouncing', 'side-spin', 'top-spin', 'shadow-play', 'rush']
});

Чтобы изменить анимацию нужно просто добавить новый класс в CSS и JavaScript. Упомянутый выше, "top-spin" выглядит следующим образом:

/* TOPSPIN */

.top-spin {
    -moz-animation: topSpin 2000ms cubic-bezier(0.000, -0.600, 0.000, 1.650);
    -webkit-animation: topSpin 2000ms cubic-bezier(0.000, -0.600, 0.000, 1.650);
    -ms-animation: topSpin 2000ms cubic-bezier(0.000, -0.600, 0.000, 1.650);
    -o-animation: topSpin 2000ms cubic-bezier(0.000, -0.600, 0.000, 1.650);
    animation: topSpin 2000ms cubic-bezier(0.000, -0.600, 0.000, 1.650);
}

@-moz-keyframes topSpin {
    0% {
       -moz-transform: rotateX(0deg);
       -moz-transform-origin: 0% 50% 0;
    }

    100% {
       -moz-transform: rotateX(360deg);
       -moz-transform-origin: 0% 50% 0;
    }
}

@-webkit-keyframes topSpin {
    0% {
   opacity: 0.1;
       -webkit-transform: rotateX(0deg);
       -webkit-transform-origin: 0% 50% 0;
    }

    100% {
   opacity: 1;
       -webkit-transform: rotateX(360deg);
       -webkit-transform-origin: 0% 50% 0;
    }
}

@-o-keyframes topSpin {
    0% {
       -o-transform: rotateX(0deg);
       -o-transform-origin: 0% 50% 0;
    }

    100% {
       -o-transform: rotateX(360deg);
       -o-transform-origin: 0% 50% 0;
    }
}

@-ms-keyframes topSpin {
    0% {
       -ms-transform: rotateX(0deg);
       -ms-transform-origin: 0% 50% 0;
    }

    100% {
       -ms-transform: rotateX(360deg);
       -ms-transform-origin: 0% 50% 0;
    }
}

@keyframes topSpin {
    0% {
       transform: rotateX(0deg);
       transform-origin: 0% 50% 0;
    }

    100% {
       transform: rotateX(360deg);
       transform-origin: 0% 50% 0;
    }
}

Вторая проблема, стоящая перед реализацией Lightbox CSS3 является отсутствие поддержки в Internet Explorer. К сожалению, с версии 8 и ниже не признают псевдо-класс :target.

Один из способов обойти эту проблему, использовать Polyfill, например Dean Edwards IE7.js или Keith Clarke's Selectivizr (последний имеет поддержку только IE8).

Тем не менее, моя цель для этого демо: создать CSS lightbox полностью независимым от любой JavaScript библиотеки. 

Если браузер не признает CSS псевдо-классы или псевдо-элементы, тогда необходимо разобрать весь блок кода. Это означает, что невозможно применить  CSS стили объекта, для блока в котором используется псевдо-класс :target.

Мое решение было использовать XMLHttpRequest API для сохранения стилей в памяти, а так же все изменения  :target с классом ieTarget, удалить старые стили, а затем добавить новые к классу .IeTarget, потом динамически добавлять и удалять его из HTML в зависимости от действий пользователя.

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

Наконец, если вы собираетесь использовать JavaScript для lightbox, то почему бы не использовать новый полноэкранный API. Он был введен в Webkit в 2011 году и сделал свое первое появление в Firefox в начале 2012 года.

API довольно прост в реализации:

full_page: function () {

    var img, x, docElm, l;

    img = document.querySelectorAll(".first-image img");

    for (x = 0, l = img.length; x < l; x += 1) {

       // call full screen when clicking on the thumbnail
       img[x].addEventListener("click", function (evt) {

           docElm = document.documentElement;

           if (docElm.requestFullScreen) {
               docElm.requestFullScreen();
               _private.add_warning();
               _private.request_smallscreen();
           } else if (docElm.mozRequestFullScreen) {
               docElm.mozRequestFullScreen();
               _private.add_warning();
               _private.request_smallscreen();
           } else if (docElm.webkitRequestFullScreen) {
               docElm.webkitRequestFullScreen();
               _private.add_warning();
               _private.request_smallscreen();
           }

       }, false);

    } 

}

Теперь можно получить доступ к глобальным объектам в нашем интерфейсе, с полноэкранным режимом.

lightbox.init({
   fullscreen: false,
   classes: ['image3D', 'flipper', 'bulge', 'bouncing', 'side-spin', 'top-spin', 'shadow-play', 'rush']
});

Перевод статьи Creating a Modern Lightbox with CSS3 and JavaScript

Тэги: transformlightbox

Вход

Уважаемый пользователь! Мы обнаружили, что вы используете AdBlock и вынуждены скрыть часть материалов на нашем сайте. Siteacademy существует и развивается за счет доходов от рекламы. Просим внести наш сайт в список исключений или отключить Блокировщик рекламы на нашем сайте.