What you can achieve through CSS 3D Transforms is limitless. With power comes responsibility, though. There will be cases when you’ll take full advantage of CSS 3D capabilities. In most projects, though, you can just spice things up a little.
Today's nugget is an effect which is getting quite popular and relies on 3D Transforms. In a nutshell, we distributed some images on the z-axis, then we used the mouse as a (fake) 3D camera so that perspective changes while you move the mouse cursor. What we really do is rotating the images in the 3D space according to the mouse position.
Since this effect relies on mouse movement, on mobile devices it won't be visible.
You can see this cool effect in action on websites like Squarespace and HelloMonday.
Image credits: Unsplash and Subtle Patterns.
👋 A new version of this component is available. Download now →.
Creating the structure
The main HTML structure is a <figure>
element containing our hero image (we used 3 different <img>
s) and wrapped in a .cd-background-wrapper
element.
<div class="cd-background-wrapper">
<figure class="cd-floating-background">
<img src="img/cd-img-1.jpg" alt="image-1">
<!-- images here -->
</figure>
</div>
The images used should have the same dimensions.
Adding style
To create the hero image we put the <img>
elements one on top of the others: the first one has a static position, while the others are in absolute position; a different translateZ value is assigned to each of them.
The idea behind the parallax effect: when user moves his mouse over the hero image, the .cd-floating-background
element is rotated (along the X and Y axises) according to the mouse position. Since the <img>
elements have different translateZ values, a different rotation is perceived for each of them.
To properly achieve this effect, we have to make sure that our <img>
s are properly positioned in a 3D-space: first, we assign a perspective value to the .cd-background-wrapper
, which creates a 3D-space shared by its children; then we assign a transform-style: preserve-3d
to the .cd-floating-background
so that its children are positioned in a 3D space rather than flattened (as default). TranslateZ does the rest!
.cd-background-wrapper {
overflow: hidden;
perspective: 4000px;
}
.cd-floating-background {
transform-style: preserve-3d;
}
.cd-floating-background img:first-child {
transform: translateZ(50px);
}
.cd-floating-background img:nth-child(2) {
transform: translateZ(290px);
}
.cd-floating-background img:nth-child(3) {
transform: translateZ(400px);
}
About IE: IE9 doesn't support CSS3 3D Transforms while IE10+ doesn't support the transform-style: preserve-3d property. So the parallax effect won't be visible in IE and you'll see a standard image.
Events handling
We bind the initBackground()
function to the image load event: this function changes the position property value of the <figure>
element from relative to absolute (the 'is-absolute' class is used). At that point, we need to assign a proper height to the .cd-background-wrapper
element (since its child is in absolute position, its default height is 0) and proper dimensions to the .cd-floating-background
(it has to be bigger than its wrapper - this way rotation won't reveal empty borders).
We evaluate the image aspect ratio and the viewport width and assign to the .cd-background-wrapper
a height equal to viewportWidth/heroAspectRatio. The .cd-floating-background
height and width are proportional to the .cd-background-wrapper
ones and its left and top parameters are set so that the image is centered inside its parent.
We then bind the mousemove
event to the .cd-background-wrapper
: the mouse position is evaluated using event.pageX
and event.pageY
and a corresponding rotateX and rotateY value is assigned to .cd-floating-background
.
Note: Modernizr doesn't detect preserve-3d support yet. So, in order to target browsers that don't, we used the getPerspective
function which assigns a preserve-3d/no-preserve-3d class to the <html>
according to browser support (Modernizr - issue 762).