Something Nobody Told You About The Image Element (It Can Overflow!)

Temani Afif Temani Afif on

Adding images to a website is a pretty straightforward task. You grab your link, and you summon the image element like below:

<img src="your_link" alt="image content">Code language: HTML, XML (xml)

Then, you add your favorite CSS, and you have a nice-looking image!

What if I tell you that the most common element is hiding some secrets? You have been working with images for too long, but you have probably never noticed the little quirks I will show you here.

Think I am exaggerating? Follow along, and you will see!

An Image Can Overflow

If you inspect the CSS code of an image element, you will notice default styles applied by the browsers, and one of them is overflow: clip.

It means that any overflow is clipped/hidden by default. We can, of course, change that and make the overflow visible:

ìmg {
  overflow: visible;
}Code language: CSS (css)

But what could overflow an image? We are dealing with a single element that cannot contain any other element. There is no container-content relation to talk about overflowing!

Actually, an image element has content, and its content is the image resource. It’s confusing, right? Let’s make a figure to better understand:

The <img> element (the HTML element) is the “container”, and the image resource (the actual image) is loaded inside that “container” and becomes the “content”. We have our container-content relation so we can talk about overflow.

Even with this clarification, it’s hard to imagine how the content of the image can overflow, but there is a very common situation where this can happen. One CSS line that you know for sure:

img {
  object-fit: cover;
}Code language: CSS (css)

Here is a demo where you can hover the image to show/hide the overflow:

Surprising, right? The object-fit: cover; declaration tries to maintain the intrinsic ratio of the image to avoid any distortion. This generally means that some parts of the image get clipped. To be more precise, the image “content” is bigger than the image “container,” leading to some overflow. That overflow is, by default, clipped, but we can change that.

An image can overflow… itself!

What if I tell you there is another well-known property that can make an image overflow?

Think about it.

Yes, you know it very well!

You got it?

It’s border-radius! The image, which is a rectangle, can overflow its rounded corners.

Another less common situation where an image can overflow is when using object-position.

img {
  object-position: 50px 0;
}Code language: CSS (css)

The above will translate the image content by 50px from the left without affecting the image element (the container), which will logically create an overflow.

Yet another overflow! We will see a bit later how this feature can be used to create some cool demos.

object-fit: none

When talking about the object-fit property, everyone thinks of the cover and contain values, but if you check the specification, you will find more values, and one of them is interesting: the none value.

none

The replaced content is not resized to fit inside the element’s content box

It has quite a strange definition, and no, it’s not the default value. To better understand what it does, let’s consider the following configuration:

img {
  width: 80vw;
  height: 80vh;
  object-fit: none;
}Code language: CSS (css)

Do you see what is happening?

The image element (the container) is sized using the viewport dimension (it has a variable size), but the image resource (the content) keeps a fixed dimension, which is the intrinsic size of the image resource (300 x 300 in our case).

As the definition states, the content is not resized. Regardless of the image dimension you set using CSS, the content will remain fixed. This means we can also have overflow when using object-fit: none if the image element is smaller than its content.

But what is the default value of object-fit?

It’s the fill value, and it has the exact opposite effect to the none value.

fill

The replaced content is sized to fill the element’s content box

Whatever the size of the image resource (its intrinsic size), it will always get sized to fit the size of the image element set using CSS.

Here is the previous demo with the ability to change the object-fit value. Open the demo in full screen and resize the page to better understand the effect of each value.

If you are a bit lost and confused, don’t worry. You were used to considering the <img> element as a simple element that shows an image, but it’s more complex than that. It’s both a container and its content at the same time, with two sizes that can be controlled separately. Not to mention the ability to make its own content overflow.

If we want to be accurate, an image is a “replaced element”. You have surely heard about that strange term without understanding what it means, but with what we saw, it should be clearer.

replaced element

An element whose content is outside the scope of the CSS formatting model, such as an image or embedded document. For example, the content of the HTML img element is often replaced by the image that its src attribute designates.

Replaced elements often have natural dimensions. For example, a bitmap image has a natural width and a natural height specified in absolute units (from which the natural ratio can obviously be determined)

The content of replaced elements is not considered in the CSS formatting model; however, their natural dimensions are used in various layout calculations

Enough theory. Let’s see some cool demos.

Show Me The Demos!

Here is a fancy hover effect that places the image inside its frame with a nice transition.

Another idea with a 3D effect:

Where is the image? Hover to reveal it!

An effect that we can combine with @starting-style to create a nice entry animation:

And why not that famous screen loader with a single image element:

You make sure the intrinsic dimension of the image is smaller than the CSS dimension, you set object-fit: none, then you animate object-position.

img {
  object-fit: none;
  object-position: 0% 0%;  
  animation: 
    x 2.1s infinite linear alternate,
    y 3.3s infinite linear alternate;
  animation-composition: add;
}
@keyframes x {
  to {object-position: 100% 0}
}
@keyframes y {
  to {object-position: 0 100%}
}Code language: CSS (css)

The animation-composition: add allows me to animate each axis individually and have an additive effect of both. You can learn more about it here: “How to Control Infinite CSS Animations

Let’s end with some fancy decoration powered by corner-shape (Chrome-only for now).

Worth noting that all the demos can be created with common techniques that are more intuitive. I am not here to push to use those obscure techniques, but the main advantage is that I don’t have to rely on additional elements or pseudo-elements. If you are in a situation where you cannot control the HTML structure, then those tricks can be handy.

Conclusion

Do you still think the image is a simple element? Even old, well-known stuff can hide strange mechanisms we can turn into fancy CSS tricks. Now go impress your colleagues and friends with this: “Hey, do you know that an image can overflow itself? Let me show you!”

Want a last trick before we end? Check this: How to style a broken image. It’s probably another feature you don’t know about images!

Looking for a complete course on getting into web development?

Leave a Reply

Your email address will not be published. Required fields are marked *

$966,000

Master.dev donates to open source projects through thanks.dev and Open Collective, as well as donates to non-profits like The Last Mile, Annie Canons, and Vets Who Code.