Responsive Images - Serve Scaled Images
Responsive image techniques, such as the srcset
, sizes
, and media
HTML attributes, allow different scaled images to be delivered based on the size and resolution of the accessing device. This allows you to further optimize your image delivery to improve the overall performance of your website or application.
Instead of taking a single image and only making it responsive with CSS, which is then delivered to all devices, you can deliver completely different images based on the requesting device. This is advantageous because of the significant performance improvements that can be gained. As you may recall from our Image CDN article, images take up 51% of the average web page size, which means serving scaled images is critical to reduce your web page sizes.
What are the srcset
, sizes
, and media
attributes?
The srcset
, sizes
, and media
attributes allow the <img>
and <source>
elements to be extended by offering the browser additional information, such as different image sources as well as different display sizes and media conditions. This offers browsers the ability to display a specific image when a rule is met.
The srcset
attribute allows image sources to be defined. This can be done by defining the absolute or relative path to the images and optionally the pixel density descriptors (e.g. 1x
, 2x
, and 3x
). This attribute can be used in the <img>
and <source>
elements.
Both the sizes
and media
attributes are nearly identical. Both allow different display sizes to be defined through various media conditions. However, the sizes
attribute allows an image size to defined either alone or in relation to a media condition. The sizes
attribute can be used in the <img>
and <source>
elements, whereas the media
attribute can be used in the <source>
element but not the <img>
element.
In all cases the <source>
element needs to be a direct child of the <picture>
element.
How to use the srcset
, sizes
, and media
attributes
To cover the basics, all that is actually required to insert an image is the <img>
tag and src
attribute, for example:
<img src="/img/blog/responsive-images.png">
The src
attribute will let the browser know where to make the image request. If an absolute path is defined, as shown above, the browser will make a request using the scheme and hostname of website where the element is placed.
However, it is highly recommended to add the alt
attribute as this attribute is important for search engines and screen readers. The width
and height
attributes can define <img>
src
size, but this could lead to an image larger than the device viewing it. That is why it is common to see the class
attribute to style the image instead, for example:
<img src="/img/blog/responsive-images.png" alt="responsive images" class="img-fluid rounded">
The problem with using the <img>
element above is that it will result in a single image being delivered across all devices. While using CSS to scale the image to fit across all devices does make the image responsive, which in our case is accomplished by using the img-fluid
class, this would lead to a significant amount of unnecessary data being delivered. Serving an unscaled image will slow performance, increase the overall page size, and waste bandwidth. This is where the responsive srcset
, sizes
, and media
attributes come to the rescue.
srcset
The srcset
attribute can be used in the <img>
and <source>
elements. We simply add the width of the images after the file name, such as 730w, 610w, and 350w. However the problem with this method is that you are relying solely on the size of the viewport to tell the browser which image to load, for example:
<img srcset="/img/blog/responsive-images-lg.png 730w,
/img/blog/responsive-images-md.png 610w,
/img/blog/responsive-images-sm.png 350w"
src="/img/blog/reponsive-images.png"
alt="responsive images">
<picture>
<source srcset="/img/blog/responsive-images-lg.png 730w">
<source srcset="/img/blog/responsive-images-md.png 610w">
<source srcset="/img/blog/responsive-images-sm.png 350w">
<img src="/img/blog/reponsive-images.png" alt="responsive images" class="img-fluid rounded">
</picture>
Luckily for us, this is where the sizes
and media
attributes comes into play.
sizes
The sizes
attribute tells the browser exactly what size the image will be in relation to the size of the viewport through media conditions, which are similar to media queries. This can be used in conjunction with the srcset
, for example:
<img sizes="(min-width: 1200px) 730w,
(max-width: 1199px) 610w,
(max-width: 380px) 350w"
srcset="/img/blog/responsive-images-lg.png 730w,
/img/blog/responsive-images-md.png 610w,
/img/blog/responsive-images-sm.png 350w"
src="/img/blog/reponsive-images.png"
alt="responsive images">
<picture>
<source sizes="(min-width: 1200px) 730w" srcset="/img/blog/responsive-images-lg.png 730w">
<source sizes="(max-width: 1199px) 610w" srcset="/img/blog/responsive-images-md.png 610w">
<source sizes="(max-width: 380px) 350w" srcset="/img/blog/responsive-images-sm.png 350w">
<img src="/img/blog/reponsive-images.png" alt="responsive images" class="img-fluid rounded">
</picture>
The sizes
attribute is very helpful when using the <img>
element, however, if you are using the <source>
element it is often makes more sense to use the media
attribute instead.
media
The media
attribute allows a media condition to be defined. This can be used in the <source>
element if its a direct child of the <picture>
element. If the condition is true that <source>
element is used, if false it is skipped, for example:
<picture>
<source media="(min-width: 1200px)" srcset="/img/blog/responsive-images-lg.png">
<source media="(max-width: 1199px)" srcset="/img/blog/responsive-images-md.png">
<source media="(max-width: 380px)" srcset="/img/blog/responsive-images-sm.png">
<img src="/img/blog/reponsive-images.png" alt="responsive images" class="img-fluid rounded">
</picture>
In addition to being able to define what image is used based on the viewport size, it is also possible to define what image is used based on the pixel density of the display.
Pixel density descriptors
The pixel density descriptors, also referred to as display or screen density descriptors, are an extremely helpful way of displaying high resolution images on high resolution displays. These descriptors are defined using 1x
, 2x
, and 3x
. They allow an image to be displayed that is either two or three times larger than the original while retaining the same dimensions as the original image, for example:
<img sizes="(min-width: 1200px),
(max-width: 1199px),
(max-width: 380px)"
srcset="/img/blog/responsive-images-lg.png 1x,
/img/blog/responsive-images-lg@2x.png 2x,
/img/blog/responsive-images-md.png 1x,
/img/blog/responsive-images-md@2x.png 2x,
/img/blog/responsive-images-sm.png 1x,
/img/blog/responsive-images-sm@2x.png 2x"
src="/img/blog/reponsive-images.png"
alt="responsive images">
<picture>
<source media="(min-width: 1200px)" srcset="/img/blog/responsive-images-lg.png 1x, /img/blog/responsive-images-lg@2x.png 2x">
<source media="(max-width: 1199px)" srcset="/img/blog/responsive-images-md.png 1x, /img/blog/responsive-images-md@2x.png 2x">
<source media="(max-width: 380px)" srcset="/img/blog/responsive-images-sm.png 1x, /img/blog/responsive-images-sm@2x.png 2x">
<img src="/img/blog/reponsive-images.png" alt="responsive images" class="img-fluid rounded">
</picture>
The sizes
or media
attributes are not required when using the pixel density descriptors, however, the actual 2x
or 3x
image does need to be two or three times larger. You can reduce the size of the scaled images even further by using the next generation image format, WebP.
WebP format
Lastly, let us not forget about the WebP format. WebP formatted images are on average 26% smaller than PNG formatted images and 25-34% smaller than JPEG formatted images. This means just converting your images to WebP can decrease the size of your pages by about 25%. However, WebP formatted images are not accepted by every browser, which is where the type
attribute becomes useful in the <source>
element, for example:
<picture>
<source type="image/webp" media="(min-width: 1200px)" srcset="/img/blog/responsive-images-lg.webp 1x, /img/blog/responsive-images-lg@2x.webp 2x">
<source type="image/webp" media="(max-width: 1199px)" srcset="/img/blog/responsive-images-md.webp 1x, /img/blog/responsive-images-md@2x.webp 2x">
<source type="image/webp" media="(max-width: 380px)" srcset="/img/blog/responsive-images-sm.webp 1x, /img/blog/responsive-images-sm@2x.webp 2x">
<source type="image/png" media="(min-width: 1200px)" srcset="/img/blog/responsive-images-lg.png 1x, /img/blog/responsive-images-lg@2x.png 2x">
<source type="image/png" media="(max-width: 1199px)" srcset="/img/blog/responsive-images-md.png 1x, /img/blog/responsive-images-md@2x.png 2x">
<source type="image/png" media="(max-width: 380px)" srcset="/img/blog/responsive-images-sm.png 1x, /img/blog/responsive-images-sm@2x.png 2x">
<img src="/img/blog/reponsive-images.png" alt="responsive images" class="img-fluid rounded">
</picture>
As we already know, the <source>
will only be used if the condition is true, which means in our example above WebP images will be used where accepted, PNG images will be used where WebP images are not accepted, and if all else fails the <img>
element will be used. The class applied to the image used in the <source>
element will be pulled from class
attribute in the <img>
element.
Browser support
Most modern web browsers support srcset
, except Internet Explorer and Opera Mini. However, Microsoft did add support for this attribute in the Edge browser. If the browser does not support this attribute, the browser will simply fallback to the original image. If using the <img>
tag the fallback image is defined in the src
attribute. If using the <picture>
element the fallback image is defined in the <img>
element. This means there really is no disadvantage to using the attributes from a browser perspective.
Why are responsive images important?
The reason responsive images are so important all comes down to file sizes. On smaller devices, there is no reason to download an image that is 1460 x 730 pixels. It is a waste of bandwidth and resources. How much of a waste? We can take a look at the image sizes we used in the examples above, for example:
File Name | Size |
---|---|
responsive-images.jpg | 30.7 KB |
responsive-images-lg.jpg | 24.1 KB |
responsive-images-md.jpg | 19.7 KB |
responsive-images-sm.jpg | 10.6 KB |
If a small device, such as a phone, has a display size of 375 pixels, serving the scaled responsive-images-sm.jpg
image would be 10.6 KB. If we compare that to the original unscaled responsive-images.jpg
image (which CSS would have to scale down) at 30.7 KB, that is a decrease of 65.47%! This will vary depending on whether or not pixel density descriptors are used, however, serving scaled images will always reduce the overall page weight.
With more complex and higher resolution images you would likely have an even higher decrease. Furthermore, over time this can save quite a bit of bandwidth from your hosting or CDN provider, which in turn saves you money.
Summary
As you can see, it is more important than ever for web developers to implement these responsive image techniques as they will ensure faster download times for mobile users and over time save bandwidth.