What are responsive images?

“Responsive images” is a term used to describe an image (on a website or app) that has multiple sources of the same image in different sizes and thus allows the browser to display the best image to the end user based on the device they are using and their network speed.

What is the “srcset” attribute?

The “srcset” is a relatively new (first specified in 2012 and updated on 2014) HTML attribute that can be used in an <img> tag to specify different file sources of varying sizes for the same image asset.
By declaring multiple sources for an image we can allow the browser to choose the most appropriate image file to load for the user based on his devices’ screen size, pixel ratio and network connection speed which translates to a better user experience

What is the “sizes” attribute?

The “sizes” HTML attribute is used to specify the pixel dimensions in which the image will be displayed in diffrerent media queries.
This allows the browser to figure out which image asset is the most suitable to load for the user.

Why do we need responsive images?

Let’s assume we want to display an high quality detailed image that will extend the full width of the screen both on mobile and desktop devices.

For a large desktop device (lets take a 15″ MacBook Pro for example) we would need an image whose width is 3360px.

For a mobile device (lets take an iPhone X for example) we would need an image whose width is 1125px.

So, In-Order to supply a high quality image to both devices i would need to use an image whose width is 3360px.
Loading that image asset on an iPhone X will be reductant since the device would automatically resize the image to fit its screen at a 1125px width.

Desktop and mobile - Different screen widths and pixel densities
Desktop and mobile – Different screen widths and pixel densities

Obviously the 3360px width image would weight a lot more than its 1125px counterpart and there’s no sense in loading such a big heavy asset on a mobile device who will automatically down size it.

It would make much more sense to load an appropriately sized image that weights less and will load faster while supply the user with the same visual experience in less time.

Responsive image – a simple how to

Let’s assume we want to display a high quality image that would span the entire width of the websites’ content wrapper, Both on mobile, tablet and desktop devices.
For this example we’ll assume the websites’ content wrapper has a width of 1200px on desktop devices, a 768px width on tablet devices and a 100% width on mobile devices.

Using a single asset <img> tag would look something like this:

See the Pen Single source <img tag> by Webra (@Webra) on CodePen.

On all devices the 3360px image would be loaded.
For devices that has a smaller viewport size the image will be automatically downsized to fit the screen.

That would mean on devices whose viewport is smaller than 3360px we’ve forced the user to download a large, heavy weight image he doesn’t need.

This of course has a impact on the page’s loading speed, The users data plan usage and the overall user experience.

Using responsive images “srcset” and “sizes” attributes we can define multiple sources and display sizes for the image as follows:

See the Pen Responsive image demo by Webra (@Webra) on CodePen.

In the “srcset” attribute we are specifying all the available resources for the image and their size in pixel units.
The asset url is separated from the images size with a space and after the size we add the letter “w” to denote the dimension specified is referring to the images width.
The sources are separated from one another using a comma (“,”).

The sizes specified in the “srcset” attribute should reflect the images actual dimensions.

In the “sizes” attribute we specify the dimensions in the which the image will be displayed in different media queries.

For devices with a viewport width of 1200px or more – the image will be displayed at 1200px width.

For devices with a viewport width of 768px to 1199px – the image will be displayed in at 768px.

And, For devices with a viewport width of 767px or less – the image will be displayed at a 100% of the viewport width.

Once we provide the browser with all this extra data it can decide automatically which image asset is best to load for the current user.

Important note: it’s recommended to still include the good old “src” attribute as fallback for browser that don’t yet support responsive images and the “srcset” / “sizes” attributes.

As for the code example above, Below is a illustration that shows which image file will be loaded on each device (assuming flawless high speed network connection).

Desktop & Mobile viewport sizes and what image asset would load on each device when using responsive images
Desktop & Mobile viewport sizes and what image asset would load on each device when using responsive images

On the MacBook Pro, whose viewport width is 3360px – the highest available image source will be loaded: 3000px × 1786px.

On the iPhone X, whose viewport width is 1125px – the closest image source will be loaded: 1200px × 714px.

You could only imagine how much data is saved when dealing with high quality detailed images.

What is CSS Pixel Ratio and how it affects responsive images?

“CSS Pixel Ratio”, A.K.A “Device Pixel Ratio” is a property that determines how Should a device screen resolution be interpreted by CSS.

Basically, “CSS Pixel Ratio” is the ratio between the physical pixels (sometimes reffered to as “Physical Pixels”) in a devices screen and CSS Pixels (sometimes reffered to as “Logical Pixels”).

The “Pixel Ratio” property is set by a device’s manufacturer.

For example: an iPhone 11 Pro screen has 1125 × 2436 Physical pixels and its logical pixels are set to 375 × 812.
That means it’s CSS Pixels Ratio is 3.
On an iPhone 11 Pro each CSS Pixel will be displayed using 3 physical pixels.

CSS will function as if the screen has a pixel width of 375px and media queries will also behave as if the screen has a 375 pixel width.
Rendered elements on the screen (fonts, images, gradient backgrounds, etc) will be 3 times as sharp as an actual 375px × 812px screen.

Browser support for responsive images

You must be asking yourself how well supported are responsive images using the “srcset” / “sizes” attributes.

According to www.CanIUse.com, as of today (February 27th, 2020) this feature is supported on 94.03% of global users’ browsers.

Since the “srcset” and “sizes” are optional, As long as you also use the “src” attribute your html will be backwards compatible with all browsers.

Responsive images and browser caching

As mentioned before, Once we specify the browser with all the necessary data, The browser will figure out automatically what image asset is best to load for the current user.

I noticed on Chrome the browser will prefer to use a cached image over downloading a new image – Even if the cached image is larger than the devices screen and in other circumstances the browser would prefer a different image source.

For instance lets assume we have a blog post that has a large featured image at 1200px × 700px on the post page.

And lets assume we also have a blog index page that displays a list of all the posts with their respective images at 600px × 350px.

Assuming we defined a “srcset” & “sizes” attributes on both image and assuming we applied a caching policy for images (and we really should have!).

Now assume a user that landed on a post page with the 1200px image and later on navigated to the blog index page, In which case the same image is display at 600px – The browser may prefer to load the cached version of image over downloading the smaller, More appropriate image.

I’ve seen some developers try to use responsive images a way to display different images on desktop and mobile devices.
Although that is technically possible, That is definitely not what responsive images are for and if you attempt to use them in this manner prepare for it to backfire on certain scenarios.

Are there other ways to improve page speed via image optimization?

I’m glad you asked and yes! of course there are more ways you could improve your pages loading speed and general user experience via image optimisation.

I have an in depth post about progressive jpegs which in my opinion significantly improves UX.

I strongly recommend you read that next.