Создаем эффект lightbox при помощи CSS3

Original author: Mary Lou
  • Translation

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

С помощью псевдо-класса :target, мы сможем показывать изображения и переходить по ним.

Красивые изображения, используемые в демо-примерах, от Joanna Kustra, они используются на условиях лицензии Attribution-NonCommercial 3.0 Unported Creative Commons License.

Обратите внимание, что эти примеры будут работать только в браузерах, которые поддерживают псевдо класс :target.

Итак, давайте сделаем это!

HTML-разметка

Сначала создадим набор миниатюр, каждая из которых имеет название, которое будет отображаться при наведении курсора. При нажатии на миниатюру, мы будем показывать большую версию изображения в блоке с классом lb-overlay, который изначально будет спрятан. Итак, мы будем использовать неупорядоченный список, где каждый элемент списка будет содержать миниатюру и блок с соответствующим большим изображением:

<ul class="lb-album">
 <li>
 <a href="#image-1">
 <img src="images/thumbs/1.jpg" alt="image01">
 <span>Pointe</span>
 </a>
 <div class="lb-overlay" id="image-1">
 <img src="images/full/1.jpg" alt="image01" />
 <div>
 <h3>pointe <span>/point/</h3>
 <p>Dance performed on the tips of the toes</p>
 <a href="#image-10" class="lb-prev">Предыдущий</a>
 <a href="#image-2" class="lb-next">Следующий</a>
 </div>
 <a href="#page" class="lb-close">x Закрыть</a>
 </div>
 </li>
 <li>
 <!-- ... -->
 </li>
</ul> 



Якорь в миниатюрах, например, href="#image-1" будет указывать на элемент с id image-1, который представляет собой div классом lb-overlay. Для того, чтобы переходить по изображениям, мы добавим две ссылки, которые указывают на предыдущее и следующее (большое) изображение.

Для того, чтобы «закрыть» lightbox, мы будем просто кликать на ссылку с классом lb-close, которая указывает на элемент с ID page, который является, в нашем примере, тегом body.

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

Теперь давайте обратимся к стилям.

CSS

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

Ниже представлены стили нашего основного слоя, неупорядоченного списка и миниатюр:

.lb-album{
 width: 900px;
 margin: 0 auto;
 font-family: 'BebasNeueRegular', 'Arial Narrow', Arial, sans-serif;
}
.lb-album li{
 float: left;
 margin: 5px;
 position: relative;
}
.lb-album li > a,
.lb-album li > a img{
 display: block;
}
.lb-album li > a{
 width: 150px;
 height: 150px;
 position: relative;
 padding: 10px;
 background: #f1d2c2;
 box-shadow: 1px 1px 2px #fff, 1px 1px 2px rgba(158,111,86,0.3) inset;
 border-radius: 4px;
} 

Название каждой миниатюры будут невидимым и мы будем добавлять переход для непрозрачности, которая станет равной 1, когда мы наведем курсор мыши на якорь миниатюры. Мы будем использовать гладкий радиальный градиент в качестве фона:
.lb-album li > a span{
 position: absolute;
 width: 150px;
 height: 150px;
 top: 10px;
 left: 10px;
 text-align: center;
 line-height: 150px;
 color: rgba(27,54,81,0.8);
 text-shadow: 0px 1px 1px rgba(255,255,255,0.6);
 font-size: 24px;
 opacity: 0;
 background:
 radial-gradient(
 center,
 ellipse cover,
 rgba(255,255,255,0.56) 0%,
 rgba(241,210,194,1) 100%
 );
 transition: opacity 0.3s linear;
}
.lb-album li > a:hover span{
 opacity: 1;
} 

Слоя наложения будет иметь такой же радиальный градиент, также мы установим свойство position равное fixed, с нулевой высотой и шириной:
.lb-overlay{
 width: 0px;
 height: 0px;
 position: fixed;
 overflow: hidden;
 left: 0px;
 top: 0px;
 padding: 0px;
 z-index: 99;
 text-align: center;
 background:
 radial-gradient(
 center,
 ellipse cover,
 rgba(255,255,255,0.56) 0%,
 rgba(241,210,194,1) 100%
 );
} 

Как только мы нажмем на миниатюру, мы раскроем на весь экран этот блок поверх остальных, но сначала давайте посмотрим на дочерние элементы.

Давайте зададим стили для основного названия и описания:
.lb-overlay > div{
 position: relative;
 color: rgba(27,54,81,0.8);
 width: 550px;
 height: 80px;
 margin: 40px auto 0px auto;
 text-shadow: 0px 1px 1px rgba(255,255,255,0.6);
}
.lb-overlay div h3,
.lb-overlay div p{
 padding: 0px 20px;
 width: 200px;
 height: 60px;
}
.lb-overlay div h3{
 font-size: 36px;
 float: left;
 text-align: right;
 border-right: 1px solid rgba(27,54,81,0.4);
}
.lb-overlay div h3 span,
.lb-overlay div p{
 font-size: 16px;
 font-family: Constantia, Palatino, serif;
 font-style: italic;
}
.lb-overlay div h3 span{
 display: block;
 line-height: 6px;
}
.lb-overlay div p{
 font-size: 14px;
 text-align: left;
 float: left;
 width: 260px;
}   

Разместим ссылку для закрытия lightbox-a чуть выше картинки:
.lb-overlay a.lb-close{
 background: rgba(27,54,81,0.8);
 z-index: 1001;
 color: #fff;
 position: absolute;
 top: 43px;
 left: 50%;
 font-size: 15px;
 line-height: 26px;
 text-align: center;
 width: 50px;
 height: 23px;
 overflow: hidden;
 margin-left: -25px;
 opacity: 0;
 box-shadow: 0px 1px 2px rgba(0,0,0,0.3);
} 

Изображение будет иметь максимальную высоту 100%. Мы также добавим переход для создания полупрозрачности. Как только мы «откроем» большое изображение, прозрачность будет анимирована. Позже мы увидим, как мы можем использовать анимацию для изображения.
.lb-overlay img{
 max-height: 100%;
 position: relative;
 opacity: 0;
 box-shadow: 0px 2px 7px rgba(0,0,0,0.2);
 transition: opacity 0.5s linear;
}  

Теперь давайте зададим стили для элементов навигации:
.lb-prev, .lb-next{
 text-indent: -9000px;
 position: absolute;
 top: -32px;
 width: 24px;
 height: 25px;
 left: 50%;
 opacity: 0.8;
}
.lb-prev:hover, .lb-next:hover{
 opacity: 1;
}
.lb-prev{
 margin-left: -30px;
 background: transparent url(../images/arrows.png) no-repeat top left;
}
.lb-next{
 margin-left: 6px;
 background: transparent url(../images/arrows.png) no-repeat top right;
} 



Когда мы нажимаем на якорь миниатюры, он будет указывать на соответствующее большое изображение, которое находится в блоке с классом lb-overlay. Таким образом, с целью нахождения этого элемента мы можем использовать псевдо-класс :target. Мы добавим padding для lb-overlay и «растянем» его, установив ширину и высоту auto (это на самом деле не обязательно) и установим right и bottom равные 0px. Помните, что мы уже установили top и left раньше.
.lb-overlay:target {
 width: auto;
 height: auto;
 bottom: 0px;
 right: 0px;
 padding: 80px 100px 120px 100px;
}

Теперь мы установим прозрачность для изображения и ссылки закрытия равную 1:
.lb-overlay:target img,
.lb-overlay:target a.lb-close{
 opacity: 1;
}  

И это все стили!

Давайте также посмотрим на два других варианта, которые мы используем в примере 1 и примере 2.

В первом примере мы сделали так, что изображение появляется с помощью анимации, изменяя его масштаб и увеличивает его значение непрозрачности:
.lb-overlay:target img {
 animation: fadeInScale 1.2s ease-in-out;
}
@keyframes fadeInScale {
 0% { transform: scale(0.6); opacity: 0; }
 100% { transform: scale(1); opacity: 1; }
}  

Во втором примере мы создали обратный эффект, то есть масштаб изображения уменьшается:
.lb-overlay:target img {
 animation: scaleDown 1.2s ease-in-out;
}
@-webkit-keyframes scaleDown {
 0% { transform: scale(10,10); opacity: 0; }
 100% { transform: scale(1,1); opacity: 1; }
}  

Демо-примеры

Пример 1: Scale-up/fade-in animation
Пример 2: Scale-down/fade-in animation
Пример 3: Fade-in & navigation

Как вы увидите, каждый браузер работает совершенно по-разному, когда речь идет о переходах/анимации. Регулируя длительность, временные функции и задержки, вы сможете сделать эффекты более гладкими, т.е. вы можете изменить время анимации для Firefox только изменив -moz-свойства.

Это все! Я надеюсь, вам понравились эти примеры! Mary Lou

Скачать исходники
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 19

    +1
    А как пролистывать изображения? Вперед-назад. При большой галерее очень не хватает.
    Как это вообще возможно реализовать таким способом?
      0
      Смотрите третий демо-пример, там есть ссылки «Вперед-назад»
        0
        На нетбуке эти ссылки сразу и не заметил. Не эргономично они находятся!)
          +3
          Очень плохо, что эти кнопки прыгают по высоте, в зависимости от размеров фотографии.
        +12
        Вот честное слово оборвал бы руки людям, сделавшим такую галерею с якорями в контакте, прямо выводит из себя, когда перелистав чью-то галерею хочу вернуться на страницу назад и попадаю в галерею…
        По поводу этой галереи: да — красиво, да — css3 дрочеры покакают ландышами, да — не ново и нет — прыгающие контролы это не круто.
          0
          Для этого вконтактик все левое поле отдал кнопке «назад».
          –1
          Любые «кликовые» псевдоклассы имеют недостатки(и существенные). Однако, в который раз убеждаюсь: если нет прямой задачи прыгать по странице, то лучше использовать :focus.
            0
            Очень красиво всё на представленных примерах в хроме

            Решил проверить как дело с поддержкой у остальных

            1) в ие9 не работает

            2) в опере тормозит и не работает :)

            3) в сафари все еще лучше хрома!

            4) ну и в самом фф 9.0.1, работает но тормозит

            пока всё так, о применении этой штуки речи не идет
              0
              Как-то делал галерейку на CSS VK-like (Вот она), вот только не доделал.
              Суть в том, что не нравится прицеливаться в навигационные стрелки, проще тыкнуть куда-то справа и пролистать вперёд или слева и, соответственно, пролистать назад. Используются те же :target и :not, разве что без украшений.

              P.S. У вас или у автора сей статьи небольшой баг в FF, который решается добавлением outline:none; к <a>:
              • UFO just landed and posted this here
                0
                Использование :target — это ужасно. Прыгающая страница от кликов — мрак.
                Так что все такие галереи (а подобных примеров сотни по интернетам) — баловство и не более…
                • UFO just landed and posted this here
                    0
                    Нет, ну понятно, что я имел ввиду, что использование :target ужасно конкретно тут, а не вообще. Конечно, в своих юзкейсах он полезен.

                    Со вторым абзацем согласен полностью
                  +4
                  «Пример 2» — мегаохуенный.
                    +1
                    Тут еще фотографии сами классные.
                    0
                    Google Chrome 16.0.912.63 beta\Ubuntu 10.04 LTS3 — показывает белый экран при клике, в Opera и FF работает, но в Опере не видно анимации
                      +6
                      хм…
                      мне кажется css3 стал уж очень громоздким, плохочитаемым.
                      Стили предназначены для визуального оформления, а не для логики.
                      Решение на javascript лучше тем, что там есть своеобразный MVC: html это модель, view это css, controller это js. Все понятно, структурированно и очевидно.
                      Если заглянуть в прошлое, мы увидим что css появился как «навесок» для html, чтобы разделить представление от данных. И это было хорошо. Сейчас же css делает похожую ошибку пытаясь работать с логикой. Не для этого ли уже придуман js?
                      Мне кажется что в будущем от css «отпочкуется» еще какой-нибудь субязык, который будет работать с логикой в css. И это плохо.
                        0
                        Ну во первых сначала css3 станет поддерживаться всеми браузерами, затем его начнут использовать и дорабатывать для работы с логикой а уже из за громоздкости «отпочкуется» субязык для визуального оформления не оглядываясь что он уже был.
                        0
                        спасибо, воспользовался при открытии-скрытии блока с корзиной с затенением остального фона

                        Only users with full accounts can post comments. Log in, please.