The <picture>
element gives us the control to switch over images based on the screen pixel density, viewport size, image format, and other factors. Thus it helps to load images that are best suited for the current view or device. For example, we can load smaller-sized versions of an image on mobile devices and larger sizes on desktops for a better user experience.
The <picture>
element should contain one or more <source>
elements and one <img>
element. We can define the different image paths with their configuration in each <source>
tag and a default image path in the <img>
tag to act as a fallback.
The browser checks each <source>
element one by one and chooses the one that is best suited for the current view. If no matches are found, or the browser doesn’t support the picture element, the image defined with the <img>
element is selected.
<picture> <source media="(min-width: 1024px)" srcset="banner-large.jpg" /> <source media="(min-width: 700px)" srcset="banner-medium.jpg" /> <source media="(max-width: 699px)" srcset="banner-small.jpg" /> <img src="default-banner.jpg" alt="Banner image"/> </picture>
The media
attribute specifies a media condition similar to the media query in CSS.
The srcset
attribute is used to specify a single or list of images based on width descriptor (followed by a w
) or pixel density (followed by an x
).
The type
attribute specifies the MIME type of the image, e.g. image/jpeg, image/webp, etc.
Here the browser chooses the image based on its viewport size. Thus on a smaller screen, we can save a lot of bandwidth and load the page faster by rendering a smaller-sized image file.
Try resizing the browser window to load different images below or open this page on mobile, iPad, and desktop to see the same.
We have used different images here so that you can mark the difference. In a real scenario, you can load different-sized versions of the same image.
Let’s see one example using a list of images in srcset
based on the width descriptor.
<picture> <source media="(max-width: 800px)" srcset="small.jpg 400w, medium.jpg 800w" /> <source media="(min-width: 801px)" srcset="large.jpg 1440w, extra-large.jpg 2500w" /> <img src="default.jpg" alt="Banner image"/> </picture>
We can also use the <picture>
element to use images of newer formats like WebP or AVIF that have better performance but don’t have broader historical browser support. Here, we can provide a fallback image with a commonly used format like jpeg
, jpg
, png
, etc., in case any browser doesn’t support the newer image formats.
<picture> <source srcset="banner.webp" type="image/webp" /> <source srcset="banner.avif" type="image/avif" /> <img src="banner.jpg" alt="Banner image"/> </picture>
The <picture>
element doesn’t load all the provided images initially; instead, it loads a particular image when required.
We can also use the CSS media query to show different images based on viewport size. We can define different <img>
tags and show/hide them using media queries based on viewport sizes. But with this approach, the browser will load all the images initially, even if we are not using them.
See Next
Web Developer by Profession, Blogger by Passion.
JavaScript | React | Next | Angular | Vue | HTML | CSS