Skip to content

Created:

Last modified:

Why Responsive Images

The internet is full of images. And relatively speaking, they're kinda large. Especially if they're not optimised at all.

This can cause sites to:

  • load slowly
  • shift around after loading as images suddenly appear
  • use up an excess amount of bandwidth

All of these issues mean a worse experience for the user. No one wants to spend their precious time waiting for a site to slowly load, only for it to suddenly shift around once it has. Plus a lot of energy is wasted when unoptimised images are loaded. The internet is pretty terrible for the environment to start with, and this just makes things worse.

What are responsive images?

For the sake of website building, responsive images are images which load differently depending on the end users device and browser. We want to use the most efficient image type possible, and while some (most) browsers accept a more efficient (meaning smaller, faster, but still looking great) image type called WebP, others (though the list is getting smaller) don't. Also the size of the image needed on a mobile can be drastically different than the image size needed for a desktop with a 4k monitor.

We want responsive images so that the end user receives the best quality image, for the lowest cost (in terms of time, energy, space etc). It's what's best for everyone.

I will say, I dragged my feet on this topic for a long time. I know the importance of it, and I've tweaked my work bit by bit, but without really understanding the full picture. I'm not sure why. It's just one of those mildly daunting tasks. Like washing the dishes, or unpacking the boxes from when you moved in 5 years ago...

How we achieve responsive images

In a basic breakdown we need a picture element with:

  • source element with the following properties:
    • srcset - a comma separated string with the url to the image and the intrinsic size of the image. This intrinsic size is then referred to in the img's 'sizes' prop.
    • type - tells the server what the image type is of those in the srcset so it can decide whether to bother loading them or not
  • img which holds
    • src - the url for the default image if none of the other given parameters work, or if the browser doesn't support options
    • alt -
    • srcset - same as the source srcset, but in the most commonly used image type
    • sizes - a comma separated string of (at least in my case) a media query (min/max-width/height) and corresponding intrinsic size wanting to load for this rule. Last value shouldn't have a media query, just the last size.
    • height - if can, height of image to stop layoutshifting
<picture>
	<source
		srcset="
			/assets/img/profile-picture-6f24e2d0d4157b76-425-319.webp   425w,
			/assets/img/profile-picture-dd053b66cafb8899-501-376.webp   501w,
			/assets/img/profile-picture-558f069b4f792748-768-576.webp   768w,
			/assets/img/profile-picture-b6a86b67dd8c7e7f-1280-959.webp 1280w
		"
		type="image/webp"
	/>
	<img
		src="/assets/img/profile-picture-091dfd8065a8f717-1889-1416.jpg"
		alt="image of female, smiling, with green hair"
		srcset="
			/assets/img/profile-picture-739eae1c1eccbf7d-425-319.jpg   425w,
			/assets/img/profile-picture-41c515beced3d26b-501-376.jpg   501w,
			/assets/img/profile-picture-54dcbad49af6989b-768-576.jpg   768w,
			/assets/img/profile-picture-c361e01e64ee376e-1280-959.jpg 1280w
		"
		sizes="max-width(425px) 425px, max-width(501px) 501px, max-width(768px) 768px, 1280px"
		height="auto"
		width="425"
	/>
</picture>
Example of picture with source and img elements

Don't forget the type prop

This is a good point from Mozilla

If the type attribute isn't specified, the media's type is retrieved from the server and checked to see if the user agent can handle it; if it can't be rendered, the next source is checked. If the type attribute is specified, it's compared against the types the user agent can present, and if it's not recognized, the server doesn't even get queried; instead, the next source element is checked at once.

With type we're given the opportunity to make things fractionally easier and faster for the server to decide what to do. While it might seem like such a small thing, if this is done as the standard and it becomes second nature, you're automatically saving resources bit by bit. Imagine this also on a page with a huge amount of images. The savings will add up.