惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
C
CERT Recently Published Vulnerability Notes
Forbes - Security
Forbes - Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
L
LINUX DO - 最新话题
The Hacker News
The Hacker News
Google Online Security Blog
Google Online Security Blog
SecWiki News
SecWiki News
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
The Last Watchdog
The Last Watchdog
S
Schneier on Security
T
Troy Hunt's Blog
N
News | PayPal Newsroom
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Schneier on Security
Schneier on Security
P
Privacy & Cybersecurity Law Blog
T
Tor Project blog
T
Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
A
Arctic Wolf
S
Secure Thoughts
P
Proofpoint News Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Security Latest
Security Latest
Scott Helme
Scott Helme
Security Archives - TechRepublic
Security Archives - TechRepublic
Latest news
Latest news
PCI Perspectives
PCI Perspectives
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News - Newest:
Hacker News - Newest: "LLM"
L
LINUX DO - 热门话题
P
Palo Alto Networks Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
G
GRAHAM CLULEY
V2EX - 技术
V2EX - 技术
Google DeepMind News
Google DeepMind News
Project Zero
Project Zero
V
Vulnerabilities – Threatpost
T
Threat Research - Cisco Blogs
Webroot Blog
Webroot Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News and Events Feed by Topic
TaoSecurity Blog
TaoSecurity Blog
大猫的无限游戏
大猫的无限游戏
T
Tenable Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Visual Studio Blog
H
Hacker News: Front Page
Simon Willison's Weblog
Simon Willison's Weblog
AWS News Blog
AWS News Blog

CSS Articles by Temani Afif

Get Ready For the Powerful CSS border-shape Property! | CSS-Tricks Let’s Play With Gap Decorations! How to Control Infinite CSS Animations (Part 2 of 2) How to Control Infinite CSS Animations (Part 1 of 2) Two Circles, One Arrow, and Anchor Positioning Making a Responsive Pyramidal Grid With Modern CSS | CSS-Tricks How to Create a CSS-only Elastic Text Effect Making Complex CSS Shapes Using shape() | CSS-Tricks Responsive Hexagon Grid Using Modern CSS | CSS-Tricks Responsive List of Avatars Using Modern CSS (Part 2) | CSS-Tricks Responsive List of Avatars Using Modern CSS (Part 1) | CSS-Tricks Perfectly Pointed Tooltips: To The Corners Perfectly Pointed Tooltips: All Four Sides Perfectly Pointed Tooltips: A Foundation Sequential linear() Animation With N Elements | CSS-Tricks Infinite Marquee Animation using Modern CSS Better CSS Shapes Using shape() — Part 4: Close and Move | CSS-Tricks Drawing CSS Shapes using corner-shape Better CSS Shapes Using shape() — Part 3: Curves | CSS-Tricks Better CSS Shapes Using shape() — Part 2: More on Arcs | CSS-Tricks Better CSS Shapes Using shape() — Part 1: Lines and Arcs | CSS-Tricks Creating Blob Shapes using clip-path: shape() Creating Flower Shapes using clip-path: shape() Custom progress element using the attr() function A CSS-Only Star Rating Component and More! (Part 2) | CSS-Tricks A CSS-Only Star Rating Component and More! (Part 1) | CSS-Tricks How to Create Wavy Boxes Using CSS Full-Bleed Layout with Modern CSS Fancy Menu Navigation Using Anchor Positioning | CSS-Tricks How to Create a Zig-Zag Box Using CSS How to Create Zig-Zag CSS Loaders Using One Element Custom Progress Element Using Anchor Positioning & Scroll-Driven Animations How to Create Filling CSS Loaders Using One Element How to Create Curved-Edge and Rounded-Edge Shapes Using CSS CSS Tricks That Use Only One Gradient | CSS-Tricks How to create Shapes with Inner Curves using CSS Mask Custom Range Slider Using Anchor Positioning & Scroll-Driven Animations How to Get the Width/Height of Any Element in Only CSS How Keyboard Navigation Works in a CSS Game How To Create Cut-Out Shapes using The clip-path property The Modern Guide For Making CSS Shapes — Smashing Magazine css-shape.com: The Ultimate Collection of CSS-only Shapes ⚡️ Sliding 3D Image Frames In CSS — Smashing Magazine CSS Tricks To Master The clip-path Property Creating Wavy Circles with Fancy Animations in CSS Modern CSS Tooltips And Speech Bubbles (Part 2) — Smashing Magazine Do you need a Tooltip or a Speech Bubble? I have created 100 using CSS 😲 Modern CSS Tooltips And Speech Bubbles (Part 1) — Smashing Magazine Creating Flower Shapes using CSS Mask & Trigonometric Functions CSS Shapes: The Triangle The Complex But Awesome CSS border-image Property — Smashing Magazine CSS Tricks to add 3D Effects to your Text CSS Responsive Multi-Line Ribbon Shapes (Part 2) — Smashing Magazine CSS Responsive Multi-Line Ribbon Shapes (Part 1) — Smashing Magazine I have made 100+ CSS-only Ribbon Shapes | The Perfect Collection 🎀 How to create a CSS-only infinite scroll animation Re-Creating The Pop-Out Hover Effect With Modern CSS (Part 2) — Smashing Magazine Re-Creating The Pop-Out Hover Effect With Modern CSS (Part 1) — Smashing Magazine How to Create CSS Ribbon Shapes with a Single Element CSS Shapes: The Ribbon Revealing Images With CSS Mask Animations — Smashing Magazine css-loaders.com: The Biggest Collection of Loading Animations (more than 500 🤯) How To Define An Array Of Colors With CSS — Smashing Magazine CSS effects on images II What's your Lucky CSS Pattern? Check It Now! How to Add a CSS Reveal Animation to Your Images Modern Layouts using CSS Grid I created 100+ unique CSS patterns | The best collection 🤩 How to Create a Custom Range Slider Using CSS CSS Shapes: The Heart CSS Shapes: Polygon & Starburst A Text Reveal Animation using CSS CSS Tip: learn CSS the easy way! How to build a CSS-only accordion How to create Breadcrumb Navigation with CSS Different Ways to Get CSS Gradient Shadows | CSS-Tricks A CSS-only responsive Stepper component A Fancy Hover Effect For Your Avatar | CSS-Tricks How to make a zoom effect using CSS Creating a Custom Cursor using CSS CSS Infinite 3D Sliders | CSS-Tricks CSS Infinite Slider Flipping Through Polaroid Images | CSS-Tricks How to create a responsive sidebar menu using CSS CSS Infinite and Circular Rotating Image Slider | CSS-Tricks Making Static Noise From a Weird CSS Gradient Bug | CSS-Tricks CSS Grid and Custom Shapes, Part 3 | CSS-Tricks Fancy Image Decorations: Outlines and Complex Animations | CSS-Tricks Fancy Image Decorations: Masks and Advanced Hover Effects | CSS-Tricks Fancy Image Decorations: Single Element Magic | CSS-Tricks How to create an infinite image slider using CSS How to Create Wavy Shapes & Patterns in CSS | CSS-Tricks How I Made a Pure CSS Puzzle Game | CSS-Tricks How to create a Tooltip/Speech Bubble using CSS CSS Grid and Custom Shapes, Part 2 | CSS-Tricks CSS Grid and Custom Shapes, Part 1 | CSS-Tricks Zooming Images in a Grid Layout | CSS-Tricks How to create a CSS-only loader with one element Exploring CSS Grid’s Implicit Grid and Auto-Placement Powers | CSS-Tricks How to create background pattern using CSS & conic-gradient Single Element Loaders: The Bars | CSS-Tricks
Shines, Perspective, And Rotations: Fancy CSS 3D Effects For Images — Smashing Magazine
https://www.smashingmagazine.com/author/temani-afif/ · 2023-07-07 · via CSS Articles by Temani Afif

CSS has all kinds of tricks that are capable of turning images into neat, interactive elements. This article is a collection of fancy 3D effects for images that demonstrate those CSS powers. Get ready to learn how they work as we get our hands dirty with CSS features that add perspective, depth, rotation, and even a slick shine to images that you can use on your next project.

We all agree that 3D effects are cool, right? I think so, especially when they are combined with subtle animations. In this article, we will explore a few CSS tricks to create stunning 3D effects!

“Why do we need another article about CSS 3D effects… aren’t there already a million of those?” Yes, but this one is a bit special because we are going to work with the smallest amount of HTML possible. In fact, this is the only markup we will use to craft some pretty amazing CSS effects for images:

<img src="" alt="">

That’s it! All we need is an <img> tag. Everything else will be done in CSS.

Here’s how it’s going to work. We are going to explore three different effects that are not linked to each other but might borrow a little from one another. You don’t need to read the entire article in one sitting. Actually, I suggest reading one section at a time, taking time to understand the concepts and what the underlying code is doing before moving on to another effect.

Table Of Contents

  • CSS 3D Shine
  • CSS 3D Parallax
  • CSS 3D Rotation

CSS 3D Shine

For the first effect, we are going to add a shine animation to the image, as well as a slight rotation when hovered.

See the Pen [3D Shine effect on hover](https://codepen.io/t_afif/pen/VwEJqKV) by Temani Afif.

See the Pen 3D Shine effect on hover by Temani Afif.

See that? The image starts slightly askew but then straightens out on hover while a shine reflects off the surface. This is a neat way to add a bit of realism to a UI without going overboard.

The first thing I did in that demo was add a rotation to the image in CSS:

img {
  transform: perspective(400px) rotate3d(1, -1, 0, 8deg);
}
img:hover {
  transform: perspective(400px) rotate3d(1, -1, 0, -8deg);
}

rotate3d allows us to define an axis for the image to rotate around. I won’t dig into the math details, but to get a diagonal axis, we make the z-axis equal to 0 and use 1 or -1 for both the x-axis and y-axis.

Then, we use the perspective property to add a little imbalance to the image. There is no particular logic behind the 400px value or the 8deg applied to the rotation, but I’ve found that a small angle combined with a big perspective gives a good result. Feel free to edit them, and maybe you will find better values for your specific use case.

We can simplify this! To avoid repetition on :hover, we can use a CSS variable to update the sign of the angle on hover. That way, there’s no need to re-write the entire declaration simply to change 8deg to -8deg.

img {
  transform: perspective(400px) rotate3d(1, -1, 0, calc(var(--i, 1) * 8deg));
}
img:hover {
  --i: -1;
}

Notice how I’m using calc() in there. By multiplying the degree value by 1 (defined by the --i variable), we get 8deg by default. Then we swap that out by changing 1 to -1 in the hover ruleset and let calc() do the heavy lifting.

That’s fun! But it gets even more interesting when we start working on the shine. An intuitive approach to making a shine might be to rely on an overlay that we place above the image. But remember, we’re working with nothing but a single <img> element, and an overlay would require more markup.

You might also be tempted to reach for a pseudo-element instead. But that’s not going to work here, unfortunately, because they won’t work with the <img> tag.

What we are going to do is “fake” it with a CSS mask and an animated gradient. I am saying “fake” because, in reality, the image you see is partially transparent. On hover, the transparency is updated to create a shiny effect.

I know it’s not easy to grasp, but if you consider that our background is black — and, yes, that is part of the trick! — making the image partially transparent is similar to making the image darker. And when the image is hovered, we adjust the transparency to brighten it up.

Here is a simplified example using opacity to better understand what I mean:

See the Pen [Opacity transition](https://codepen.io/t_afif/pen/RwqNjeo) by Temani Afif.

See the Pen Opacity transition by Temani Afif.

That’s the basic idea. Now, instead of opacity, we are going to use mask with a linear-gradient()

/* Diagonal gradient that is opaque 
 * in the center and semi-transparent 
 * on both sides.
*/
mask: linear-gradient(135deg, #000c 40%, #000, #000c 60%);

When masking in CSS, the color doesn’t matter considering the default mask-mode. All that matter is the alpha channel that will define the level of transparency. In our case, the diagonal part is opaque, while the sides are partially transparent. #000c is equivalent to rgb(0 0 0 / 80%).

See the Pen [Adding the gradient mask](https://codepen.io/t_afif/pen/VwVYrVa) by Temani Afif.

See the Pen Adding the gradient mask by Temani Afif.

The gradient is super subtle because we only reduced the transparency a little. That’s a good thing because we don’t want the user to notice that the image is partially transparent by default.

The next step is to animate that gradient. We increase its size to the point where the opaque center is out of view. Then we move it from the top-left corner of the image to the bottom-right corner:

img {
  mask:
    linear-gradient(135deg, #000c 40%, #000, #000c 60%)
    100% 100%/ /* initial position, bottom-right */
    240% 240%; /* width and height */
}
img:hover {
    mask-position: 0 0; /* Move to the top-left on hover */
}

Check it out; we have a nice shine on hover!

See the Pen [Adding the hover effect](https://codepen.io/t_afif/pen/eYQmebX) by Temani Afif.

See the Pen Adding the hover effect by Temani Afif.

Cool, right? Now let’s combine that shine above with the 3D rotation to get the full effect.

img {
  transform: perspective(400px) rotate3d(1,-1,0,calc(var(--i,1)*8deg));
  mask:
    linear-gradient(135deg,#000c 40%,#000,#000c 60%)
    100% 100%/240% 240%;
  transition: .4s;
  cursor: pointer;
}
img:hover {
  --i: -1;
  mask-position: 0 0;
}

One HTML element and a few lines of CSS are all we needed to make that happen. Here is a figure to illustrate the different values used inside the mask:

Demonstrating how the CSS mask covers the image and how it slides on hover
Demonstrating how the CSS mask covers the image and how it slides on hover. (Large preview)

The green box illustrates the gradient where the blue lines define the color stops we used. Initially, it’s placed at 100% 100%, and on hover, we slide it to 0 0. The slide effect will move the diagonal part of the gradient (the opaque part) along the image to create the shine effect.

Here is the full demo again. I’m even including a second variation for you to tear apart and investigate how it works.

See the Pen [3D Shine effect on hover](https://codepen.io/t_afif/pen/VwEJqKV) by Temani Afif.

See the Pen 3D Shine effect on hover by Temani Afif.

CSS 3D Parallax

We normally think of “parallax” as this thing we use for interesting scrolling effects where elements change position at different speeds. But we can use it to make a slick hover effect on our image too.

See the Pen [3D parallax effect on hover](https://codepen.io/t_afif/pen/qBJyXNy) by Temani Afif.

See the Pen 3D parallax effect on hover by Temani Afif.

Like the shine effect we made in the last section, we start with a slightly skewed image that straightens out on hover. But, instead of applying a shine, we’re sliding the image over a smidge with a transition to make it look like the focal point rotates with the image, adding a sense of depth to it.

You might think we need to stack two versions of the same image to pull this off, but not at all! The effect is done with a single image and a few lines of CSS for the “fake” parallax effect. Yes, I’m calling this a “fake” effect because it’s not really a parallax implementation but a combination of movements that trick your brain into thinking it is! If you want to see “real” parallax at work, this pen from Sladjan is a great example.

The image is very important here. For a perfect illusion, consider an image where the main element is placed at the center, and the background is uniform. That might be a bit of a limitation as far as this effect goes, so it might not be the best approach for every image.

The image rotates and changes perspective on hover, just like the shine effect in the last section. This time, however, we’re rotating along the y-axis (rotateY()) instead of all three axes (rotate3d()).

img {
  transform: perspective(400px) rotateY(8deg);
}
img:hover {
  transform: perspective(400px) rotateY(-8deg);
}

We accomplish the sliding movement with a combination of CSS clipping and translation. This is the trickiest part of the effect. Here is a simplified demo to illustrate the main idea:

See the Pen [Moving the image inside a box](https://codepen.io/t_afif/pen/QWJweZP) by Temani Afif.

See the Pen Moving the image inside a box by Temani Afif.

We have an image inside a box with a green border representing the clipped area. The clipped area is square, and the image overflows the right edge a bit. On hover, we slide the image to the left (using transform: translateX()) while the clipped area remains in place.

If we hide the part of the image that overflows the clipped area (overflow: hidden) and add the same rotation we made in the last section, we get the “fake” parallax effect we want:

See the Pen [Adding the rotation + the overflow](https://codepen.io/t_afif/pen/VwVYoqr) by Temani Afif.

See the Pen Adding the rotation + the overflow by Temani Afif.

But that demo uses an extra <div> element to pull it off. Our challenge is to do the same thing without that element. That’s where clip-path is really helpful:

img {
  --f: .1; /* parallax factor (the smaller, the better) */

  --_f: calc(100 * var(--f) / (1 + var(--f)));
  width: 250px; /* image size */
  aspect-ratio: calc(1 + var(--f));
  object-fit: cover;
  clip-path: inset(0 var(--_f) 0 0);
  transition: .5s;
}
img:hover {
  clip-path: inset(0 0 0 var(--_f));
  transform: translateX(calc(-1 * var(--_f)))
}

The --f variable controls the effect, describing how much the image should move. You will notice that I am using it to calculate an aspect-ratio that is slightly greater than 1 to create a non-square image that we later clip to get a square image. --_f defines the portion we must cut from the image to get a 1:1 square ratio.

Demonstrating how the clip-path values change when the image is in a hovered state
Demonstrating how the clip-path values change when the image is in a hovered state. (Large preview)

The clip-path defines the clipped area, and we need that area to remain fixed. That’s why we added a translation on hover to move the image in the opposite direction of the clip-path.

See the Pen [Clip-path + translation](https://codepen.io/t_afif/pen/PoxwMry) by Temani Afif.

See the Pen Clip-path + translation by Temani Afif.

We add the rotation to the mix, and the effect is perfect:

img {
  --f: .1; /* parallax factor (the smaller the better) */
  --r: 10px; /* the radius */

  --_f: calc(100%*var(--f)/(1 + var(--f)));
  --_a: calc(90deg*var(--f));

  width: 250px; /* image size */
  aspect-ratio: calc(1 + var(--f));
  object-fit: cover;
  clip-path: inset(0 var(--_f) 0 0 round var(--r));
  transform: perspective(400px) translateX(0px) rotateY(var(--_a));
  transition: .5s;
}
img:hover {
  clip-path: inset(0 0 0 var(--_f) round var(--r));
  transform: perspective(400px) translateX(calc(-1*var(--_f))) rotateY(calc(-1*var(--_a)));
}

I’ve rounded the edges of the clipped area slightly to make the effect a little more fancy. If you’re wondering why I didn’t use the border-radius property, it’s because the property doesn’t work well with clipped areas. Luckily, clip-path accepts a round value to get the same sort of rounded corners.

That’s it! We’re actually done with this neat hover effect on our image.

See the Pen [3D parallax effect on hover](https://codepen.io/t_afif/pen/qBJyXNy) by Temani Afif.

See the Pen 3D parallax effect on hover by Temani Afif.

You can adjust the parallax factor and the rotation angle, then work with the best image possible for using it in your own work. If you do use it, please show me your demos in the comments!

CSS 3D Rotation

For this last demo, we will add depth to the image and transform it into a 3D box.

See the Pen [3D images with hover effect](https://codepen.io/t_afif/pen/yLRRBKj) by Temani Afif.

See the Pen 3D images with hover effect by Temani Afif.

For this one, I will skip the rotation part because it’s the same as what we just made in the last demo. Let’s focus instead on the 3D part, using the outline and clip-path properties. The following image illustrates how they come together to form a 3D box.

An outline surrounds the image (1), then is offset to cover the image (2) so that it can be clipped in the shape of a box (3)
An outline surrounds the image (1), then is offset to cover the image (2) so that it can be clipped in the shape of a box (3). (Large preview)

Here’s how that works. First, we add some padding to the top and the bottom of the image and apply an outline that is semi-transparent black.

Second, we apply a negative outline-offset so that the outline covers the image on the left and right sides but leaves the top and bottom alone:

img {
  --d: 18px;  /* depth */

  padding-block: var(--d);
  outline: var(--d) solid #0008;
  outline-offset: calc(-1 * var(--d));
}

Notice that I have created a variable, --d, that controls the thickness of the outline. This is what gives the image depth.

The last step is to add the clip-path. We need a polygon with eight points for that.

An image with the eight points of the clipped polygon shape
Showing the eight points of the clipped polygon shape. (Large preview)

The red points are fixed, and the green points are ones that we will animate to reveal the depth. I know it’s far from a 3D box, but this next visual, where we add the rotation, gives a better illustration.

The image starts with depth facing in one direction (left), then is rotated on hover to hide the depth for a flat appearance (center). We can change the direction of the depth as well (right)
The image starts with depth facing in one direction (left), then is rotated on hover to hide the depth for a flat appearance (center). We can change the direction of the depth as well (right). (Large preview)

Initially, the image is rotated with some perspective. The green points on the right are aligned with the red ones. Thus, we hide the outline on that side to keep it visible only on the left side. We have our 3D box with the depth on the left.

On hover, we move the green points on the left while rotating the image. Halfway through the animation, all the green points are aligned with the red ones, and the rotation angle is equal to 0deg, hiding the outline and giving the image a flat appearance.

Then, we continue the rotation, and the green points on the right move while the left ones remain in place. We get the same 3D effect but with the depth on the right side.

Bear with me because the next block of code is going to look really confusing at first. That’s due to a few new variables and the eight-point polygon we’re drawing on the clip-path property.

@property --_l {
  syntax: "<flength>";
  initial-value: 0px;
  inherits: true;
}
@property --_r {
  syntax: "<length>";
  initial-value: 0px;
  inherits: true;
}

img {
  --d: 18px;  /* depth */
  --a: 20deg; /* angle */
  --x: 10px;

  --_d: calc(100% - var(--d));
  --_l: 0px;
  --_r: 0px;

  clip-path: polygon(
    /* The two green points on the left */
    var(--_l) calc(var(--_d) - var(--x)),
    var(--_l) calc(var(--d)  + var(--x)),

    /* The two red points on the top */
    var(--d) var(--d),var(--_d) var(--d),

    /* The two green points on the right */
    calc(var(--_d) + var(--_r)) calc(var(--d)  + var(--x)),
    calc(var(--_d) + var(--_r)) calc(var(--_d) - var(--x)),

    /* The two red points on the bottom */
    var(--_d) var(--_d),var(--d) var(--_d)

    );
  transition: transform .3s, --_r .15s, --_l .15s .15s;
}

/* Update the points of the polygon on hover */
img:hover{
  --_l: var(--d);
  --_r: var(--d);
  --_i: -1;
  transition-delay: 0s, .15s, 0s;
}

I’ve used comments to help explain what the code is doing. Notice I am using the variables --_l and --_r to define the position of the green points. I animate those variables from 0 to the depth (--d) value. The @property declarations at the top allow us to animate the variables by specifying the type of values they are (<length>).

Note: Not all browsers currently support @property. So, I’ve added a fallback in the demo with a slightly different animation.

After the polygon is drawn on the clip-path property, the next thing the code does is apply a transition that handles the rotation. The full rotation lasts .3s, so the green points need to transition at half that duration (.15s). On hover, the polygon points on the left move immediately (0s) while the right points move at half the duration (courtesy of a .15s delay). When we leave the hovered state, we use different delays because we need the right points to move immediately (0s) while the left points move at half the duration.

What’s up with that --x variable, right? If you check the first image that I provided to illustrate the clip-path points, you will notice that the green points are slightly shifted from the top and bottom edges, which is logical to simulate the 3D effect. The --x variable controls how much shifting takes place, but the math behind it is a bit complex and not easy to express in CSS. So, we update it manually based on each case until we get a value that feels right.

That gives us our final result!

See the Pen [3D images with hover effect](https://codepen.io/t_afif/pen/yLRRBKj) by Temani Afif.

See the Pen 3D images with hover effect by Temani Afif.

Wrapping Up

I hope you enjoyed — and perhaps were even challenged by — this exploration of CSS 3D image effects. We worked with a whole bunch of advanced CSS features, including masks, clipping, gradients, transitions, and calculations, to make some pretty incredible hover effects for images that you certainly don’t see every day.

And we did it in a way that only needed one line of HTML. No divs. No classes or IDs. No pseudo-elements. Just a single <img> tag is all we need. Yes, it’s true that more markup may have made the CSS less complex, but the fact that it relies on a plain HTML element means the CSS can be used more broadly. CSS is powerful enough to do all of this on a single element!

I’ve written extensively about advanced CSS styles for images. If you’re looking for more ideas and inspiration, I encourage you to check out the following articles I’ve published:

I also run a site called CSS Tip that explores even more fancy effects — subscribe to the RSS feed to keep up with the experiments I do over there!

Further Reading On SmashingMag

Smashing Editorial (gg, yk)