The <picture>
tag is a versatile HTML element that allows developers to provide different versions of an image to users based on their device size or resolution. By using the <source>
tag to specify different versions of the same image, we're sure to serve only the most appropriate image, potentially reducing the amount of data that needs to be downloaded, leading to improved load times and less data usage. Plus, it's much better than trying to force a one-size-fits-all approach for images.
The <source>
tag specifies multiple versions of the same image in different formats, sizes, or resolutions, and then the <picture>
tag selects the appropriate version based on the device's specifications.
Basic example
<picture>
<source srcset="example-desktop.jpg" media="(min-width: 768px)">
<source srcset="example-mobile.jpg">
<img src="example-default.jpg" alt="Example Image">
</picture>
Let's break this down: In this basic example, we have used the <picture>
element to display different images depending on the device's screen size. The first <source>
element specifies a higher-resolution image for devices with a screen width of 768 pixels or more, while the second <source>
element specifies a lower-resolution image for all other devices. Finally, the <img>
element is used as a fallback image, in case none of the <source>
elements are matched.
A more advanced example
<picture>
<!-- WebP image for supported browsers -->
<source
type="image/webp"
media="(min-width: 768px)"
sizes="(max-width: 767px) 50vw, (min-width: 768px) 100vw"
srcset="
example-l.webp 800w,
example-m.webp 500w
"
>
<!-- Fallback to JPEG for unsupported browsers -->
<source
media="(min-width: 768px)"
sizes="(max-width: 767px) 320px, (min-width: 768px) 800px"
srcset="
example-l.jpg 1x 800w,
example-l_2x.jpg 2x 800w,
example-m.jpg 1x 500w,
example-m_2x.jpg 2x 500w
"
>
<!-- Fallback to JPEG for devices with small screens -->
<source
media="(max-width: 767px)"
sizes="(max-width: 767px) 320px"
srcset="
example-s.jpg 480w,
example-xs.jpg 320w
"
>
<!-- Fallback to the highest resolution for devices that don't support the picture element -->
<img
src="example-l.jpg"
alt="example"
sizes="(max-width: 767px) 320px, (min-width: 768px) 800px"
>
</picture>
In this second example, we have used several advanced features available for the <picture>
element. We have also specified the type of image as image/webp
in the <source>
elements to take advantage of the newer, more efficient image format (an article on this topic is on the way).
Choice process
Check for browser support for the
srcset
attribute: The browser checks if it supports thesrcset
attribute, which is used to provide a list of image files with different resolutions and formats. If thesrcset
attribute is not supported, the browser will simply use thesrc
attribute to load the image file.Check for
type
attribute compatibility : then the browser looks for thetype
attribute for each source element that specifies the MIME type of the image file. If it does not support the MIME type, it will not use that source file.Check for
media
attribute: specifies a media condition that must be true in order for the associatedsource
element to be considered. It is defined like CSS media queries.Check for
sizes
attribute: it provides a size hint to the browser about the image dimensions at a certain screen width.Check for
width
attribute (descriptor: w): thewidth
attribute specifies the width of the image file in pixels. The browser selects the source with a width that matches the layout viewport's width (as defined by CSS media queries). If multiple sources have the same width, the browser selects the first matching source.Check for
pixel density
(descriptors: 1x, 2x, 3x): If no sources match the width of the layout viewport, the browser checks for thepixel density
of the screen. The browser determines the pixel density of the device (standard density, 2x density, 3x density) and selects the source element with the appropriate descriptor.Falls back to default
src
: If the browser doesn't find any image file that matches thetype
,width
, andpixel density
, It falls back to use the defaultsrc
attribute, which is the source file specified by the lastimg
element.
Final considerations
You might ask, "Why going through all of this trouble?" Well, by providing different versions of the image, we're reducing the amount of data that needs to be downloaded by our site visitors. This leads to faster load times and less bandwidth usage. The second example is honestly the most complex I can think of, but if you would give <picture> a try, even in its easier form is able to optimize quite a bit your document's performances.
So, to summarize, the <picture>
tag is a helpful tool for web developers that provides users with fast-loading, high-quality images that are appropriate for their device. Additionally, the tag improves web accessibility by allowing screen readers to understand the context of the images, thereby creating a more inclusive environment for all users. By remembering these key points when working with <picture>
, developers can improve the user experience on their website while also making the web a better place for eve