In this blog post, we’ll explore a fascinating example of how CSS can be used to create dynamic 3D effects. We’ll break down a piece of HTML and CSS code that brings images to life with rotation and depth, creating an engaging visual effect on hover. Let’s dive into the details of how this works.
Table of Contents
ToggleThe Code Overview
Here’s the complete code that we’ll be dissecting:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS 3D rotation</title>
</head>
<style>
@property --_l {
syntax: "<length>";
initial-value: 0px;
inherits: true;
}
@property --_r {
syntax: "<length>";
initial-value: 0px;
inherits: true;
}
img {
--d: 18px; /* the depth */
--a: 20deg; /* the angle */
/* the below value is based on the depth and the angle.
the formula is a bit difficult to express so we update it manually
*/
--x: 10px;
width: 250px; /* control the size */
aspect-ratio: 1.1; /* you can use 1 as ratio but I found 1.1 a little better */
object-fit: cover;
padding-block: var(--d);
transform: perspective(400px) rotateY(calc(var(--_i,1)*var(--a)));
outline: var(--d) solid #0008;
outline-offset: calc(-1*var(--d));
--_d: calc(100% - var(--d));
--_l: 0px;
--_r: 0px;
clip-path: polygon(
var(--_l) calc(var(--_d) - var(--x)),
var(--_l) calc(var(--_d) + var(--x)),
var(--d) var(--d),var(--_d) var(--d),
calc(var(--_d) + var(--_r)) calc(var(--_d) + var(--x)),
calc(var(--_d) + var(--_r)) calc(var(--_d) - var(--x)),
var(--_d) var(--_d),var(--d) var(--_d)
);
transition: transform .3s,--_r .15s,--_l .15s .15s;
transition-timing-function: linear;
cursor: pointer;
}
img:hover,
img.alt {
--_l: var(--d);
--_r: var(--d);
--_i: -1;
transition-delay: 0s,.15s,0s;
}
img.alt:hover {
--_l: 0px;
--_r: 0px;
--_i: 1;
transition-delay: 0s,0s,.15s;
}
/* we do a different animation for firefox since it doesn't support @property */
@supports not (-webkit-mask: paint(p)) {
img,
img.alt {
transition: .3s;
}
img:hover,
img.alt:hover {
--_i: 0;
--_l: var(--d);
--_r: 0px;
}
}
body {
margin: 0;
min-height: 100vh;
display: grid;
place-content: center;
grid-auto-flow: column;
gap: 30px;
background: #C44D58;
}
</style>
<body>
<img src="https://picsum.photos/id/318/300/300" alt="Eiffel tower">
<img src="https://picsum.photos/id/629/300/300" class="alt" alt="Pisa tower" style="--d: 13px;--a: 25deg;--x:8px">
</body>
</html>
Breaking Down the CSS
- Custom Properties with
@property
:
@property --_l {
syntax: "<length>";
initial-value: 0px;
inherits: true;
}
@property --_r {
syntax: "<length>";
initial-value: 0px;
inherits: true;
}
These @property
rules define custom properties (--_l
and --_r
) for the CSS variables that will be used in the rotation effect. This feature allows for smoother animations and transitions by specifying how custom properties should behave.
2. Image Styles:
img {
--d: 18px; /* the depth */
--a: 20deg; /* the angle */
--x: 10px;
width: 250px;
aspect-ratio: 1.1;
object-fit: cover;
padding-block: var(--d);
transform: perspective(400px) rotateY(calc(var(--_i,1)*var(--a)));
outline: var(--d) solid #0008;
outline-offset: calc(-1*var(--d));
--_d: calc(100% - var(--d));
--_l: 0px;
--_r: 0px;
clip-path: polygon(
var(--_l) calc(var(--_d) - var(--x)),
var(--_l) calc(var(--_d) + var(--x)),
var(--d) var(--d),var(--_d) var(--d),
calc(var(--_d) + var(--_r)) calc(var(--_d) + var(--x)),
calc(var(--_d) + var(--_r)) calc(var(--_d) - var(--x)),
var(--_d) var(--_d),var(--d) var(--_d)
);
transition: transform .3s,--_r .15s,--_l .15s .15s;
transition-timing-function: linear;
cursor: pointer;
}
- Custom Properties: Variables like
--d
(depth) and--a
(angle) control the 3D effect. - Transformations: The
transform
property applies a perspective and rotation based on these variables. - Clip Path: The
clip-path
property is used to create a clipping shape for the images, allowing for precise control over the visible area. - Transitions: Smooth transitions are defined to animate changes in transform and clipping properties.
3. Hover Effects:
img:hover,
img.alt {
--_l: var(--d);
--_r: var(--d);
--_i: -1;
transition-delay: 0s,.15s,0s;
}
img.alt:hover {
--_l: 0px;
--_r: 0px;
--_i: 1;
transition-delay: 0s,0s,.15s;
}
These rules adjust the custom properties when an image is hovered over, creating the 3D rotation effect. The transition-delay
ensures that the animations occur smoothly and in the correct sequence.
4. Firefox Compatibility:
@supports not (-webkit-mask: paint(p)) {
img,
img.alt {
transition: .3s;
}
img:hover,
img.alt:hover {
--_i: 0;
--_l: var(--d);
--_r: 0px;
}
}
This block ensures that the effect works across different browsers, including Firefox, which does not fully support the @property
feature.
5. Body Styles:
body {
margin: 0;
min-height: 100vh;
display: grid;
place-content: center;
grid-auto-flow: column;
gap: 30px;
background: #C44D58;
}
The body is styled to center the images and provide a pleasing background color.
keep in touch with us to enhance your creativity.
Conclusion
This CSS code showcases how you can create a visually appealing 3D rotation effect using modern CSS features. By combining custom properties, transformations, and clip paths, you can make your web images stand out with interactive and dynamic effects. This approach not only enhances the visual appeal but also provides a smooth user experience across different browsers. Try experimenting with different values for depth and angle to see how they affect the rotation and overall look of your images!
Happy coding, and may your web designs be ever more interactive and engaging!