HTMLImageElement: sizes property
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2016.
The sizes property of the HTMLImageElement interface allows you to specify the layout width of the image for each of a list of media queries, or auto for lazy-loaded images to allow the browser to automatically select an image to display based on the layout size of the element.
This allows the browser to choose between different images specified in the element srcset to match different media conditions — even images with different orientations or aspect ratios.
The sizes property reflects the <img> element's sizes content attribute.
It can only be present when srcset uses width descriptors.
Value
A string that can be the auto keyword (optionally followed by any number of source sizes), or one or more source sizes.
See the sizes attribute in the HTML <img> reference for more information.
Examples
>Selecting an image to fit window width
This example demonstrates how the browser uses the sizes attribute to select an image from srcset based on the rendered width of the image at the current viewport width.
It also allows you to see the effect of resizing the browser window on which image is loaded.
HTML
In order to demonstrate the effect of lazy loading the images need to be initially hidden from the visual viewport, and then scrolled into view.
This is achieved by having an outer scroll-container <div> that nests spacer and demo-wrap containers.
The image is contained inside the demo-wrap container, which is pushed out of the visual viewport by the height set on the spacer container.
The <img> element has the following attributes:
srcsetdefines four images and indicates that they are600px,900px,1200px, and1500pxwide.srcspecifies the image that will be used ifsrcsetis not supported or it can't be parsed. We use the largest image in thesrcsetas this will almost always downscale better than the smallest image will upscale.loadingislazy.sizesspecifies the expected rendered width of the image at a set of viewport-width breakpoints, allowing the browser to select the most appropriate image fromsrcset.
<div id="scroll-container">
Scroll down to display images
<div id="spacer"></div>
<div id="demo-wrap">
<div class="img-container" id="resizable">
<div class="img-square">
<img
loading="lazy"
sizes="(max-width: 600px) 600px, (max-width: 900px) 900px, (max-width: 1200px) 1200px, 1500px"
src="1500.png"
srcset="600.png 600w, 900.png 900w, 1200.png 1200w, 1500.png 1500w"
alt="Example image" />
</div>
<div class="label">
<strong>Container width: <span id="width-label"></span></strong>
</div>
</div>
</div>
</div>
The CSS and JavaScript are not shown (if you want to examine these, select "Play" to view the whole example in the interactive playground).
Result
The example is best viewed in its own window, so you can adjust the sizes fully, and the example is not constrained by its containing frame.
-
Scroll the frame to display the image. The label at the bottom of the image shows the current container width.
-
Resize the window — you should see the image change at the
sizesattribute's media query break points.Note that the the selected image may be larger than the container width alone suggests. Many displays, if not most, have a device pixel ratio (DPR) greater than one. In order to render a sharp image at the physical pixel density of the display, a browser will multiply the matched
sizeshint by the DPR before selecting fromsrcset. For example, on a 2× display with a viewport of ~500px, the matched hint is600px, but the browser looks for a ~1200px image and selects1200.pngas the closest available size and then scales it to fit in the available space.Note: As a result, some of the images in the
srcsetmay not be reachable on a particular display at some break points, and this may be browser dependent.
The log provides information when a load event fires for the image, and when it intersects the visible viewport.
Note that the image is lazy-loaded, so the load event should be fired just before the image enters the viewport.
Automatic image selection for lazy loaded images
This example demonstrates how setting the sizes value to auto affects the selection of the image to load from the srcset when <img> elements are lazy-loaded.
It also allows you to see the effect of changing the size of a container on the loaded image.
HTML
The HTML is similar to that in the previous example, except that it defines three near-identical <img> elements, each with a scrset indicating 3 images that are 600px, 400px, and 200px wide, and with a sizes value of auto.
These are constrained within containers that are sized to select the different images.
<div id="scroll-container">
Scroll down to display images
<div id="spacer"></div>
<div id="demo-wrap">
<div class="img-container img-container--sm" id="resizable">
<div class="img-square">
<img
loading="lazy"
sizes="auto"
src="600.png"
srcset="600.png 600w, 400.png 400w, 200.png 200w"
alt="Image in small container" />
</div>
<div class="label"><strong>Container width: 100px</strong></div>
</div>
<div class="img-container img-container--md">
<div class="img-square">
<img
loading="lazy"
sizes="auto"
src="600.png"
srcset="600.png 600w, 400.png 400w, 200.png 200w"
alt="Image in medium container" />
</div>
<div class="label"><strong>Container width: 200px</strong></div>
</div>
<div class="img-container img-container--lg">
<div class="img-square">
<img
loading="lazy"
sizes="auto"
src="600.png"
srcset="600.png 600w, 400.png 400w, 200.png 200w"
alt="Image in large container" />
</div>
<div class="label"><strong>Container width: 400px</strong></div>
</div>
</div>
</div>
CSS
Here we show the CSS classes that set the size of the different image containers.
.img-container--sm {
width: 100px;
}
.img-container--md {
width: 200px;
}
.img-container--lg {
width: 400px;
}
The remaining CSS and the JavaScript that powers the slider, logging, and so on, are not shown (if you are interested in examining these, select "Play" to view the whole example in the interactive playground).
Result
Scroll the frame to display the three images. The browser should have selected a different image for each based on the different width constraints. You can use the slider to modify the size of the container for the first image. Note that the browser may or may not select a new image to display as the size of the container changes as implementations are not required to react to dynamic changes.
The log provides information when a load event fires for each image, and when an image intersects the visible viewport.
Note that the images are lazy-loaded, so the load event should be fired just before the image enters the viewport.
Also note that the load event also fires as you modify the container size for the first image, indicating when the browser has recalculated the layout (not necessarily that a new image has been loaded).
Blog example
This example is a slightly more real-world case demonstrating how to select an image to fit a window width using source sizes.
In this example, a blog-like layout is created, displaying some text and an image for which three size points are specified, depending on the width of the window. Three versions of the image are also available, with their widths specified. The browser takes all of this information and selects an image and width that best meets the specified values.
How exactly the images are used may depend upon the browser and the pixel density of the user's display.
Buttons at the bottom of the example let you actually modify the sizes property slightly, switching the largest of the three widths for the image between 40em and 50em.
HTML
<article>
<h1>An amazing headline</h1>
<div class="test"></div>
<p>
This is even more amazing content text. It's really spectacular. And
fascinating. Oh, it's also clever and witty. Award-winning stuff, I'm sure.
</p>
<img
src="new-york-skyline-wide.jpg"
srcset="
new-york-skyline-wide.jpg 3724w,
new-york-skyline-4by3.jpg 1961w,
new-york-skyline-tall.jpg 1060w
"
sizes="(50em <= width <= 60em) 50em,
(40em <= width < 50em) 30em,
(width < 40em) 20em"
alt="The New York City skyline on a beautiful day, with the One World Trade Center building in the middle." />
<p>
Then there's even more amazing stuff to say down here. Can you believe it? I
sure can't.
</p>
<button id="break40">Last Width: 40em</button>
<button id="break50">Last Width: 50em</button>
</article>
CSS
article {
margin: 1em;
max-width: 60em;
min-width: 20em;
border: 4em solid #880e4f;
border-radius: 7em;
padding: 1.5em;
font:
16px "Open Sans",
"Verdana",
"Helvetica",
"Arial",
sans-serif;
}
article img {
display: block;
max-width: 100%;
border: 1px solid #888888;
box-shadow: 0 0.5em 0.3em #888888;
margin-bottom: 1.25em;
}
JavaScript
The JavaScript code handles the two buttons that let you toggle the third width option between 40em and 50em; this is done by handling the click event, using the JavaScript string replace() method to replace the relevant portion of the sizes string.
const image = document.querySelector("article img");
const break40 = document.getElementById("break40");
const break50 = document.getElementById("break50");
break40.addEventListener(
"click",
() => (image.sizes = image.sizes.replace(/50em,/, "40em,")),
);
break50.addEventListener(
"click",
() => (image.sizes = image.sizes.replace(/40em,/, "50em,")),
);
Result
The page is best viewed in its own window, so you can adjust the sizes fully, and the example is not constrained by its containing frame.
- Enable the developer tools and change the width of the page — you should see the image change (and jump in size) at the sizes media query break points:
640px(40em), and800px(50em). - Set the width between
50em(800px)and60em(960px`) so that the last media query is selected. Then alternately press each of the buttons and note how the layout size of the image is changed.
Specifications
| Specification |
|---|
| HTML> # dom-img-sizes> |