От автора: проблема пользовательского интерфейса, к которой мы здесь обращаемся – та же, на которой сосредоточены многие мои CSS 3D— работы, такие как пользовательский интерфейс Origami: мы живем в мире очень разнообразных экранов, причем стремительно становятся нормой их маленькие размеры. Это требует переоценки имеющегося пространства: вместо размещения подписей под фотографиями нам может понадобиться поместить их за изображением с тем, чтобы те появлялись при действиях касания или проведения мышью.
Создание основной галереи
Разметка галереи переворачивающихся изображений очень проста:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<div class="flip-3d"> <figure> <img src="yacht.jpg" alt=""> <figcaption>Yacht</figcaption> </figure> </div> <div class="flip-3d"> <figure> <img src="bee.jpg" alt=""> <figcaption>Bee</figcaption> </figure> </div> <div class="flip-3d"> <figure> <img src="queenstown.jpg" alt=""> <figcaption>Queens-town</figcaption> </figure> </div> |
Обратите внимание на внешний div для каждого figure, который будет использован при создании 3D-контекста для содержимого галереи. Чтобы получить показанный в примере 3D-эффект, нам требуется сделать три вещи:
Заставить каждую подпись figcaption покрывать ту же область, которую занимает описываемое им адаптивное изображение.
Перевернуть эту подпись, поместив ее на другой стороне изображения.
Создать отбрасываемую тень, которая станет перемещаться вместе с изображением, не добавляя при этом дополнительной разметки.
Исходный CSS
Сначала самое основное: нам нужно манипулировать элементами figure в трехмерном пространстве. Добиться этого можно, поместив к обычному родительскому элементу фигуры свойство perspective:
1 2 3 |
div.flip-3d { perspective: 1200px; width: 30%; float: left; } |
(Заметьте, что код CSS показан без вендорных префиксов для того, чтобы сэкономить место и сохранить ясность изложения).
Далее разместите масштабируемые элементы фигуры друг около друга с помощью float и сделайте изображения в них адаптивными. Чтобы переход transition элементов figure оставался как можно более результативным, мы заранее определяем, что станем отслеживать только преобразование элемента. Также добавляем часто забываемое свойство transform-style, которое нам пригодится попозже.
1 2 3 4 5 6 7 8 9 |
div.flip-3d figure { position: relative; transform-style: preserve-3d; transition: 1s transform; font-size: 1.6rem; } div.flip-3d figure img { width: 100%; height: auto; } |
(Я добавил в код запрос @media, чтобы упростить галерею на более маленьких экранах и при сужении окна браузера, что здесь не показано).
Размещение подписей
Подписи размещены в точности поверх изображений путем применения position: absolute (что возможно только потому, что у элементов figure относительное расположение position: relative). Использование полуоборота (т.е. вращения на 180°) и крошечного значения translate помещает подписи «за» изображениями, пока свойство transform-style корректно применяется к элементу figure. (Вам, возможно, захочется взглянуть на то, что происходит при удалении этого свойства).
1 2 3 4 5 6 7 8 9 10 |
div.flip-3d figure figcaption { position: absolute; width: 100%; height: 100%; top: 0; transform: rotateY(.5turn) translateZ(1px); background: rgba(255,255,255,0.9); text-align: center; padding-top: 45%; opacity: 0.6; transition: 1s .5s opacity; } |
Текст помещается в центре подписи с помощью маленького трюка, и снабжается белым полупрозрачным фоном. Можно создать полностью непрозрачную figcaption, превратив изображение в трехмерную открытку, но я предпочитаю зрительный эффект постепенного проявления на фоне. Обратите внимание, что это проявление будет отсрочено на полсекунды с тем, чтобы начинаться посредине вращения фигуры, что мы уже установили на последнюю секунду.
Установка вращения
Когда галерея определена, создать анимацию уже совсем просто:
1 2 |
div.flip-3d:hover figure { transform: rotateY(.5turn); } div.flip-3d:hover figure figcaption { opacity: 1; } |
Почему просто не установить :hover к элементам figure?
Оборачивание каждого элемента figure в div кажется немного чрезмерным: почему просто не исключить внешние элементы и установить состояние проведения мышью :hover прямиком к элементам figure?
Причина в том, что figure физически поворачиваются во время перехода, ребром проходя относительно окна браузера по дуге. Поддержание состояния проведения мышью hover к элементу figure сужает активную область во время этого вращения: сбивая браузер с толку по поводу того, находится ли мышь внутри или вне элемента, что в результате приводит к тому, что переходы «дергаются» туда-сюда.
Добавление теней
Я увлекся идеей добавить тени под изображениями, но эта задача осложнялась тремя проблемными вопросами:
Тени нужно создать, не добавляя дополнительной разметки;
Они должны быть широкими и тонкими: другими словами, не по настоящему размеру или силуэту изображения – box-shadow и drop-shadow исключаются.
Тени должны вращаться в собственной плоскости, при этом перемещаясь вместе с изображением.
Решение, к которому я в итоге пришел, состояло в применении сгенерированного контента, заполненного радиальным градиентом, создающим впечатление тени, «привязанной» к своему изначальному элементу:
1 2 3 4 5 6 |
div.flip-3d figure:after { content: " "; display: block; height: 8vw; width: 100%; transform: rotateX(90deg); background-image: radial-gradient(ellipse closest-side, rgba(0, 0, 0, 0.05) 0%, rgba(0, 0, 0, 0) 100%); } |
Наверное, лучше всего увидеть окончательный эффект на иллюстрации с другого ракурса:
Вот и все! Надеюсь, это послужит зерном вдохновения для ваших собственных решений CSS 3D.
Автор: Dudley Storey
Источник: //demosthenes.info/
Редакция: Команда webformyself.
Комментарии (6)