On this article, we’ll discover some CSS tips that enable us to create a hover animation for revealing our photos.

We is likely to be pondering “Nicely, that’s a simple job! An additional component above the picture that you simply animate and it’s carried out.” True, however we gained’t use any further component or pseudo-element. We’re going to work utilizing solely the <img> component. Nothing extra!

It could sound inconceivable as a result of, utilizing solely the picture component, we are able to’t have one thing above it. Certainly, we gained’t have one thing above it, however we’ll faux it!

Under is a CodePen demo of what we’re going to discover collectively.

See the Pen
A reveal hover effect with one element
by Temani Afif (@t_afif)
on CodePen.

Cool, proper? A reveal animation utilizing just a few traces of code and no further component. Comply with me, and let’s dissect the magic behind the code.

The Preliminary Configuration

We’ll begin by defining the dimensions of the picture:

img {
  --s: 200px; 

  width: var(--s);
  top: var(--s);
  box-sizing: border-box;
}

Nothing advanced thus far. We’re utilizing a sq. picture for simplicity, however it may be a picture of any dimension. It’s essential to explicitly set width and top and never use aspect-ratio or depart the default dimension of the picture. That is obligatory for our animation, and we’ll see why later.

Notice using box-sizing: border-box as properly, which can also be essential. It has no impact for now, however let’s transfer to the subsequent step to grasp why it’s wanted.

Including Some Padding

What’s going to occur if we add some padding to a picture the place we’ve outlined a hard and fast dimension and we’ve used box-sizing: border-box? Let’s attempt!

See the Pen
Untitled
by Temani Afif (@t_afif)
on CodePen.

The picture is squished, as we are able to see within the above demo. We add 100px of padding on the left, which is able to depart solely 100px of area for the picture (the content-area). That’s the impact of box-sizing: border-box.

As defined by MDN:

border-box tells the browser to account for any border and padding within the values you specify for a component’s width and top. In case you set a component’s width to 100 pixels, that 100 pixels will embrace any border or padding you added, and the content material field will shrink to soak up that further width.

Now, think about a state of affairs the place the padding is the same as the width. Sure, the picture will disappear! Within the demo under, hover over the picture and see the end result.

See the Pen
Animating the padding
by Temani Afif (@t_afif)
on CodePen.

There are two issues particularly to notice within the above demo. Padding might be animated, which is cool, and we are able to see the significance of the CSS variable we used beforehand to outline the dimensions of the picture. We’ve used the identical variable to outline the padding, so we don’t must repeat the identical worth.

Including a Background Colour

Let’s take the earlier instance and add a background to it.

See the Pen
Untitled
by Temani Afif (@t_afif)
on CodePen.

We’re beginning to get someplace now. The background will logically cowl the entire component. We don’t see it below the picture (until we use one with transparency), however we see it on the padding space.

Our objective is to disclose the picture, so let’s begin by having the padding after which making it 0 on hover — the alternative of what we at the moment have.

See the Pen
Untitled
by Temani Afif (@t_afif)
on CodePen.

This nonetheless isn’t what we’re aiming for, however we’re getting nearer! We’re lacking just one ingredient to make our “faux” reveal animation excellent!

Including object-fit and object-position

The lacking half is to keep away from the squishing of the picture, and right here comes the ultimate trick. We’re going to make use of object-fit with the cowl worth.

As defined by MDN:

The changed content material is sized to take care of its facet ratio whereas filling the component’s total content material field. If the item’s facet ratio doesn’t match the facet ratio of its field, then the item might be clipped to suit.

Two elements are essential right here:

  • “The changed content material is sized to take care of its facet ratio”. Which means that the picture gained’t get squished however will maintain its intrinsic ratio. We used a sq. picture, so it can stay sq..
  • “filling the component’s total content material field … might be clipped to suit”. The picture ought to fill all of the content material space (the realm we cut back by including some padding), but when it gained’t match inside, we clip it.

Let’s do this within the following demo.

See the Pen
Untitled
by Temani Afif (@t_afif)
on CodePen.

See that? The picture is not squished! It’s preserving its ratio contained in the content material space whereas we add/take away the padding.

Okay, so we could also be pondering that the impact isn’t the identical as within the preliminary demo. The picture is transferring unusually. True. So now we flip to object-position. The default worth is heart, so the picture might be centered within the content material space on a regular basis and can get clipped to suit inside. That’s why it strikes with the animation.

What we’ll do subsequent ought to be straightforward to foretell. We’ll change the place to ensure the picture gained’t transfer. We’ll add the padding from the left, so we should always repair the place of the picture to the best utilizing object-position: proper.

See the Pen
Untitled
by Temani Afif (@t_afif)
on CodePen.

Our reveal animation is completed! We didn’t want any overlay or an additional component above the picture. Through the use of a easy background coloration, together with some positioning tips for the picture, we get a elaborate reveal animation with a small quantity of straightforward code.

We will simply replace the path by adjusting the padding path and the object-position. Right here’s the primary demo from earlier, which incorporates the 4 instructions.

See the Pen
A reveal hover effect with one element
by Temani Afif (@t_afif)
on CodePen.

Right here’s the CSS we’re utilizing:

img {
  --s: 200px; 

  width: var(--s);
  top: var(--s);
  box-sizing: border-box;
  object-fit: cowl;
  cursor: pointer;
  transition: .5s;
}

img.left {
  object-position: proper;
  padding-left: var(--s);
  background: #542437;
}

img.proper {
  object-position: left;
  padding-right: var(--s);
  background: #8A9B0F;
}

img.high {
  object-position: backside;
  padding-top: var(--s);
  background: #E94E77;
}

img.backside {
  object-position: high;
  padding-bottom: var(--s);
  background: #7A6A53;
}

img:hover {
  padding: 0;
}

Extra Reveal Animations

We will lengthen the trick to create extra variations utilizing the identical concept. As an alternative of including/eradicating the padding from one aspect, we are able to do it for 2 sides and even all sides.

See the Pen
A reveal hover effect with one element II
by Temani Afif (@t_afif)
on CodePen.

If we examine the code of the demo above, we gained’t discover a massive distinction from the earlier one. All that we’re doing is setting totally different padding configurations to create extra variation for a similar impact.

There’s one trick within the first and final instance the place we’re utilizing object-fit: none as a substitute of object-fit: cowl. In these instances, the padding will cut back the width and the peak of the content material space to 0, whereas in all of the others instances, we both cut back the peak or width. In such configurations, cowl gained’t work, however none can do the job.

MDN states:

The changed content material shouldn’t be resized.

Why aren’t we simply utilizing none in all instances? We can use it, and it really works, nevertheless it has a small downside. none will think about the intrinsic dimension of the picture, so we’re obliged to have the CSS width and top equal to the intrinsic dimension for the trick to work. cowl, however, retains solely the ratio of the picture and can resize it to suit the realm, so we are able to safely outline any CSS dimension for the photographs.

Right here’s a comparability so we are able to see the distinction.

See the Pen
Untitled
by Temani Afif (@t_afif)
on CodePen.

In each instances, we’ve the reveal animation, however when utilizing object-fit: none, the picture isn’t resized and is preserving its default dimension (500x500), which isn’t good. object-fit: cowl is simply preserving the ratio and can resize the picture to suit the field dimension.

Conclusion

I hope you loved this little CSS experiment. Utilizing easy tips and some traces of code, we achieved a cool reveal animation with solely the <img> component. We additionally did many variations utilizing the identical code construction.

We will do much more with this trick. I’ll depart you with a final instance the place I remodel black and white photos into coloured ones on hover.

See the Pen
Color your image with a sliding hover effect
by Temani Afif (@t_afif)
on CodePen.

I’ll allow you to proceed the exploration and attempt to discover extra fancy animations!