用CSS設計出3D骨牌照片
A very cool CSS 3D Captioned image with domino effect created by Dudley Storey.
While Codrops and CodePlayer have shown recent variations of this technique, I felt their solutions were lacking in several regards: the images weren’t mobile-ready, the markup lacked semantic value, and the CSS tended to be overly complex. Thus, this derivation and tutorial…
Markup
The HTML5 code is very simple, relying primarily on <figure>
and <figcaption>
elements:
<div>
<figure>
<figcaption>Autumn, by Lucien Agasse</figcaption>
</figure>
</div>
The <div>
element contains the context of 3D perspective; it will also ensure that user interactions are captured by an element that remains static on the screen.
Styling
div {
perspective: 1000px; width: 33%;
margin: 0 auto;
margin-top: 3rem;
}
The <figure>
contains a full-width background image that is cut off by a height set in vw
units (and thus responds to the width of the browser window).
figure {
margin: 0; width: 100%; height: 29.5vw;
position: relative; background-size: 100%;
background: url("winter-hat.jpg");
transform-origin: center bottom;
transform-style: preserve-3d;
transition: 1s transform;
}
The transform-origin
of the <figure>
element is set to “swing” from its lower edge, like a trapdoor. Next, the image caption:
figcaption {
width: 100%; height: 50px;
position: relative; top: 29.5vw;
background: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)),
url("winter-hat.jpg");
background-size: 100%;
background-position: bottom;
color: #fff;
transform-origin: center top;
transform: rotateX(-89.9deg);
font-size: 1.2vw; text-align: center;
line-height: 3;
}
The <figcaption>
element is provided with a set height and moved to the exact position where the <figure>
is cut off. The element uses the same background-image
as the <figure>
, only starting from the bottom of the element, rather than the top. This background is overlaid with a “wash” of rgba
color to fade it, a technique I’ve discussed before. Then, the <figcaption>
is “hinged” from the top and folded back by a little less than 90 degrees.
Creating The Shadow
The shadow is a pseudo-element generated from the <figure>
, its size and shape determined by the rule that absolutely positioned elements take their cues from relatively positioned parents:
figure:before {
content: '';
position: absolute; top: 0; left: 0;
width: 100%; height: 100%;
box-shadow: 0 0 100px 50px rgba(0, 0, 0, 0.1),
inset 0 0 250px 250px rgba(0, 0, 0, 0.1);
transition: 1s;
transform: rotateX(95deg) translateZ(-80px) scale(0.75);
transform-origin: inherit;
}
The shadow is given the appearance of “solidity” by using both a standard outer box-shadow
and an inset
one. Then, it is rotated back while being moved and scaled down, providing the impression of a “ground”.
Adding The Transition
The movement of the <figure>
and its shadow are initiated by hovering over the <div>
element:
div:hover figure {
transform: rotateX(75deg) translateZ(5vw);
}
div:hover figure:before {
box-shadow: 0 0 25px 25px rgba(0, 0, 0, 0.5),
inset 0 0 250px 250px rgba(0, 0, 0, 0.5);
transform: rotateX(-5deg) translateZ(-80px) scale(1);
}
The <figure>
is rotated back while being moved down, and the box-shadow
rotated up to meet it. At the same time, the shadow darkens and focuses (note the altered alpha and blur values). As part of the <figure>
(and because we added transform-style: preserve-3d
earlier) the <figcaption>
moves in synchronicity.
Adding Breakpoints
The image is perfect for large viewports, but requires some intervention at smaller sizes: realistically, we can’t leave the <div>
at ⅓rd the browser window width if the screen is only 320 pixels wide. <figcaption>
will also need some intervention, as set vw
units do not remain appropriate for text across the entire spectrum of screen sizes.
@media screen and (max-width: 800px) {
div { width: 50%; }
figure { height: 45vw; }
figcaption { top: 45vw; font-size: 2vw; }
}
@media screen and (max-width: 500px) {
div { width: 80%; margin-top: 1rem; }
figure { height: 70vw; }
figcaption { top: 70vw; font-size: 3vw; }
}
Adaption For Mobile
Support for :hover
is inconsistent across mobile platforms; a quick, albeit imperfect solution is to add an empty onclick
action for the <div>
:
<div onclick="">
There’s much more that can be done with this interaction pattern, as I’ll show in future articles.
http://www.cssreflex.com/2014/02/css-3d-captioned-domino-image.html/
http://demosthenes.info/blog/830/CSS-3D-Captioned-Domino-Image