How to srcset – responsive images

In most latest browsers it is now possible to deliver different images for different devices by only one image element, using the srcset attribute. This is important for preventing small devices loading unnecessarily large images, but still having sharp big images on large (retina) devices.

Using srcset

Multiple image sources can be suggested to a browser by size or by the device pixel ratio of the browser.

Using the x unit (device pixel ratio of the browser)

On retina screens with a device pixel ratio of 2, the image will show the source with width of 1000px.

Using the w unit (size of the image source)

Using w tells the browser the width of the image source. The browser can decide which width matches best for the device.
The choice depends not only on the browsers viewport, but can depend on bandwidth and device hardware too.

How to tell the browser what source it should choose, depending on size AND device ratio?

Telling the browser how large an image source is by defining the size in w, is not enough for a browser to choose the best source, when the image is styled with CSS to, for example, 200px.
In this case we use the size attribute, together with the srcset.

Because now we tell the browser what the size will be, after applying CSS styling, and we specify the width of each source, the browser can choose the best image. The image will always be displayed with a width of 200px, but a retina device will choose the source with 400w and a non-retina device will choose the 200w source.

What is exactly the problem?

The problem is that images are preloaded by the browser. This is at the moment the DOM is not even build yet. So the browser has no knowledge about the CSS styling which is calculated after the DOM has been build. So we have to give the browser some clue what the size of the image will be, after fully rendered and styled with CSS, for the browser to be able to pick the most suitable source from a list of sources with different widths.

The sizes attribute is not the same as the width attribute. The difference lies in the responsive possibilities of the sizes attribute.

Responsive fluid design

For a responsive and/or fluid design a fixed size of, for example, 200px, does not suffice. A fluid design has sizes relative to the parent element. Which is not known when images are being preloaded, by the browser, before the DOM is ready and the view is rendered with CSS styling. However there is a unit that is known, before CSS is calculated. It is the view width. With the view width we can define a fluid (relative) size of the image.

Media queries

It is even possible to use media queries in the sizes attribute. This is needed when, for example, we have an image that has a width of 33% of the viewport, but on small devices a full width of 100%.

Here the sizes attribute is interpreted as the image being 33% of the viewport when the viewport is larger than 768px, otherwise it is 100%.

What is going on?

When we resize the browser window when viewing this page in Chrome we see in the next example that the breakpoint is a little surprising.

When starting with a browser width of 150px on a retina device, Chrome chooses the 400w source as expected.
But it switches to the 800w source at a browser width of 283px, which I find rather unexpected! I would have expected the breakpoint earlier.
Another inexplicable thing happens at 388px viewport width, switching to the 1200w source. I would have expected it to happen later.

I would expect the browser to switch source at viewport widths 200 and 400px. Because, to be able to render a sharp retina image at 201px viewport width, the browser needs an image larger than 400px.
The same applies to the 1200w image, which is only needed for a viewport with a width from 401px.

So what is going on here?

Tweet about this on TwitterShare on LinkedIn


Het e-mailadres wordt niet gepubliceerd.