The Picture Element
Open the lesson folder
In our starter files, open the index.html page from this lessons folder:
> 4.The-picture-element
Included images
In this lesson's folder you will find the index.html file and also some images to use:
The extra image attributes we looked at previously provide a great way to switch image sizes based on the device width, and pixel density. If this is all you need, then that is great. These included both the srcset and sizes attributes.
Using the picture element
There is also another way to switch image sizes by using the picture element.
The picture element provides more flexibility by giving us access to the full power of media queries to select our image. This is a more manual way of telling the browser which image to choose, rather than letting the browser decide.
The picture element is a wrapper like many other HTML elements:
<picture></picture>
This element does not provide any images on its own, we need to place content inside.
<picture>
<img src="images/lake-640.jpg" />
</picture>
This works just as with adding a regular <img> element. However, we can also provide multiple image sources.
The source element
To provide alternative images, place in one or more source elements:
<picture>
<source>
<img src="images/lake-640.jpg" />
</picture>
The source element only has an opening tag since we add the data as attributes. It is used to provide media resources for not only this picture element, but you can also use it with the audio or video elements too.
When using inside the picture element, the src attribute will be ignored:
<source src=""/>
This is not needed because we already have the <img> fallback set, instead, we use srcset:
<source srcset=""/>
Providing the images we want to use, followed by a size:
<source srcset="images/sun-640.jpg 640w, images/sun-1280.jpg 1280w" />
These images are different to the src attribute so we can clearly see what is being used in the browser.
As previously discovered, we can also use a pixel density such as 2x or 4x, rather than the width here if you prefer.
Test this in the browsers developer tools, under the network panel.
Combining with media queries
This leaves us in the same position as just using the <img> element and srcset, but the difference is we can also introduce media queries. Rather than letting the browser decide, we set up some conditions of our own.
We can use any media query, just like we would with CSS. A common choice is to only display an image if the viewport is a minimum or maximum width:
<picture>
<source media="(min-width: 640px)" srcset="images/sun-640.jpg 640w" />
<img src="images/lake-640.jpg" />
</picture>
The above example uses two different images to test. When the viewport width exceeds 640px, show the sun image. Below this, the <img> element will be used rendering the lake image.
Multiple source attributes can be included:
<picture>
<source media="(max-width: 599px)" srcset="images/sun-640.jpg 640w" />
<source media="(min-width: 600px)" srcset="images/sun-1280.jpg 1280w" />
<img src="images/lake-640.jpg" />
</picture>
Test this in the browsers developer tools, under the network panel.
Multiple images can also be provided for each media query. This can be useful for conditions such as device orientation. For example, a large tablet and a small phone, both in landscape mode, may require different image sizes to suit:
<source
media="(orientation: landscape)"
srcset="images/sun-1280.jpg 1280w, images/sun-2400.jpg 2400w"
/>
<source
media="(orientation: portrait)"
srcset="images/sun-320.jpg 320w, images/sun-640.jpg 640w"
/>
This provides our larger image options when the device is landscape, and smaller images during portrait orientation.
The sizes attribute
We can also use the sizes attribute with source. Remember, if no sizes attribute is included, it is assumed we want all images to be the full width of the viewport. In the landscape view, we may want images to be only 50% of the viewport:
<picture>
<source
media="(orientation: landscape)"
srcset="images/sun-1280.jpg 1280w, images/sun-2400.jpg 2400w"
sizes="(max-width: 1280px) 100vw, 50vw"
/>
<source
media="(orientation: portrait)"
srcset="images/sun-320.jpg 320w, images/sun-640.jpg 640w"
/>
<img src="images/lake-640.jpg" />
</picture>
This means our images up to 1280px are full width, and larger screens will reduce to 50% wide. Also note that the sizes attribute is only available when using pixel sizes (w), rather than pixel density such as 2x.