Как стать автором
Обновить

Галерея на CSS3

Время на прочтение4 мин
Количество просмотров25K
Здравствуйте, хабровчане!
Совсем недавно я озадачился попробовать css3-плюшки в действии. Посмотреть на что они годны в реальности. Мой взор пал на знакомые всем галереи fancybox и т.д. Другими словами — решил сделать подобие js-галереи, но только на чистом html+css.
Приступим.
С расположением картинок я особо не заморачивался, выстроив их в «стенку» через float:left. Родителем для изображения выступила ссылка (тег «a»), почему – станет понятно ниже. Т.к. я решил сделать четыре ряда по четыре картинки, задаем им по 25% высоты и ширины. Бордеры «помещаем» в контейнер через box-sizing. Выглядит это так:
a{
float: left;
width: 25%;
height: 25%;
position: relative;
border: 1px solid #333;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}


Теперь работаем с изображением. Задаем ему размеры 100%, позиционирование абсолютом и transition. Код прилагается:
a img{
display: block;
width: 100%;
height: 100%;
-webkit-transition-property: width, height; /* указываем, какие свойства нам надо изменить*/
-webkit-transition-duration: 300ms; /* указываем, с какой скоростью надо вернуть изображение в исходный вид*/
-moz-transition-property: width, height;
-moz-transition-duration: 300ms;
-o-transition-property: width, height;
-o-transition-duration: 300ms;
position: absolute;
opacity: 0.3; /* делаем прозрачность для красоты*/
cursor: pointer;
}


В одном из вариантов галереи я решил сделать подпись фотографиям. Реализовал через псевдоэлемент :after.
a:after {
display: block;
position: absolute;
width: 100%; 
height: 100%;
content: "Studio.com";
color: #eaeaea;
font-family: "Trebuchet MS";
font-size: 16px;
opacity: 0.5;
}

Думаю, тут все понятно.

Встал вопрос, по какому действию открывать изображение. Ведь необходимо, чтобы оно открылось и осталось в этом состоянии, пока мы не засмотримся. Выход нашел в псевдоклассе :focus. А так как он работает только для полей формы и ссылок, нам и понадобился тег «a»
Оформляем:
a:focus img{
width: 250%;  /* до такого размера мы увеличили изображение*/
height: 250%;
position: absolute;
opacity: 1; /* прозрачность стала не нужна*/
z-index: 1; /* чтобы фотография разворачивалась поверх всех изображений*/
-moz-box-shadow: 0 0 15px 2px #000;
-webkit-box-shadow: 0 0 15px 2px #000;
box-shadow: 0 0 15px 2px #000;  /* добавляем немного красоты */
-webkit-transition-property: width, height; /* делаем «сворачивание» изображения*/
-webkit-transition-duration: 2s; /* указываем, с какой скоростью нам надо увеличить изображение*/
-webkit-transition-delay: 0.3s; /* как долго будет думать браузер, перед тем, как развернуть фотографию*/
-moz-transition-property: width, height;
-moz-transition-duration: 2s;
-moz-transition-delay: 0.3s;
-o-transition-property:width, height;
-o-transition-duration: 2s;
-o-transition-delay: 0.3s;
cursor: default;
}


Заметка. Псевдокласс :focus не совсем корректно работает с бразуером Chrome, выход нашел путем добавления ссылке tabindex.

В принципе все уже готово и можно начать использовать. Но вот беда — все изображения разворачиваются с левого верхнего угла в правый нижний, и не всегда это сыграет на руку. Ведь если эта галерея окажется около правой или нижней границ окна браузера, то развернувшееся изображение будет образовывать соответствующие скролл-бары. Как от этого избавиться? На выход пришел псевдокласс :nth-child, с его возможностью задавать периодичность применения свойств:
a:nth-child(4n+4) img, a:nth-child(4n+3) img{
right: 0;
} /* каждый четвертый элемент начиная с 3-го и 4-го будут разворачиваться от правой границы окна браузера*/


a:nth-child(n+9) img{
bottom: 0;
} /* все элементы, начиная с девятого начнут разворачиваться снизу*/


Т.к. сетка у меня 4*4, то в этом случае 12 элемент, например, будет разворачиваться снизу и справа в левый верхний угол. Таким образом у нас все изображения будут показываться внутри самого контейнера с изображениями. Попутно решили проблему с динамически добавляемыми изображениями – нам не надо присваивать классы — :nth-child позаботится об этом сам.

Ну теперь точно все… А как принудительно закрыть изображение? Резонный вопрос. Решаем. Раз у нас фотография открывается по «фокусу», то чтобы ее закрыть, нам надо убрать с нее фокус. Здесь я сильно не заморачивался и решил сделать одну общую «кнопку» и повесить ее в правый верхний угол от галереи. Из примечательного здесь то, что я ее сделал обычным плюсом, повернув его на 45 градусов и добавил к нему тень:
-webkit-text-shadow: 0px 0px 5px #222;
-moz-text-shadow: 0px 0px 5px #222;
text-shadow: 0px 0px 5px #222;
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
cursor: pointer;


Однако мы привыкли, что один элемент может зависеть от другого и реагировать на его действия только если он является потомком. А плодить 20 потомков неохота(кстати, по этой же причине я сделал всего одну кнопку.)
Нам на помощь пришел селектор обобщенных родственных элементов «~». В итоге мы сделали один элемент в разметке и поместили его в контейнер к нашим изображениям, чтобы они имели одного общего родителя. Ну и применяем стандартный прием:
.closed{
display: none;
}
a:focus~.closed{
display: block;
}


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

Работающие примеры:
первый вариант
второй вариант
Теги:
Хабы:
+54
Комментарии21

Публикации