In previous articles I’ve addressed why we need responsive images (fluid design plus screen pixel densities) and looked at the <picture>
element, while conducting investigations of the w
and x
descriptors. Today I’ll explain the sizes
attribute, the trickiest part of the new specification.
sizes
is… odd. It looks weird. It acts weird. But it is the final missing piece of the spec, the part that brings everything together, and therefore key to understanding responsive image syntax.
If there’s one thing to keep in mind about sizes
, it’s this: sizes
expresses the designer’s intentions for the image in relationship to the current layout. It does so with a little bit of math, for one reason…
By default, the browser doesn’t know the size, resolution or layout of an image. Traditionally, a browser has to load an image in order to determine anything about it, and then consult CSS for layout. We can’t expect the browser to do that if a page has a half-dozen alternatives for the same image (different widths, resolutions, and aspect ratios). The elements and attributes we’ve discussed so far address most of these concerns:
<picture>
takes care of art direction (the aspect ratio and central focus of the image(s))w
andx
address thewidth
andresolution
of the image(s), respectively
The remaining question is “how does this image work in relationship to the rest of the page?” With this missing piece of information, the browser can make the best choice from the array of possibilities provided to it.
We Don’t Need Another (Hero Image)
Let’s start with the simplest example. In the most basic layout, a banner image will always take 100% of the viewport width, i.e. 100vw.
Let’s say we have two image versions, salton-large.jpg and salton-small.jpg. The first is 1500 pixels wide, the second 750 pixels wide. We’ll define them using the w
descriptor:
<header>
<img src="salton-small.jpg"
srcset="salton-small.jpg 750w, salton-large.jpg 1500w"
alt="The sun setting on the Salton Sea">
</header>
We can use CSS to explain how the image fits inside its container:
header img { width: 100%; height: auto; }
…but that doesn’t tell the browser anything about how the image relates to the viewport, which would let it know how big the image actually is on the screen, and thus which version to use. In the simplest scenario, that’s easy: the design calls for the image to be full width of the browser window. We can define that in the sizes
attribute:
<header>
<img src="salton-small.jpg"
srcset="salton-small.jpg 750w, salton-large.jpg 1500w"
sizes="100vw" alt="The sun setting on the Salton Sea">
</header>
Now the browser has everything it needs to determine the right image in every scenario: it will read the device to determine the screen pixel density, learn the actual size of the images from the w
descriptors, and understand how the images relate to the page as a whole. It can then do its own math - possibly combined with other information, such as available bandwidth - to load the appropriate image for the current viewport size on that device.
Let’s complicate things slightly: say the hero image is inside a fluid element with a max-width
of 750px. Now the image won’t necessarily stretch across the entire browser window: on most mobile devices it will, but probably not on a maximized desktop browser. We explain that to the browser with a media condition, a form of inline media query:
<header>
<img src="salton-small.jpg"
srcset="salton-small.jpg 750w, salton-large.jpg 1500w"
sizes="(min-width: 750px) 750px, 100vw"
alt="The sun setting on the Salton Sea">
</header>
In English, the media condition values used here could be translated as: “if the viewport is at least 750 pixels wide, this image will be the same width, otherwise, the image will be 100% of the viewport width.”
Do You Need Sizes?
All of this can feel a little overwhelming, and may leave you wondering whether you need to do it at all. The sizes
attribute can feel weird and imprecise: you’re giving guidelines and hints to the browser, rather than clear declarations. In reality, HTML and CSS have always been this way, but it can be uncomfortable to confront that fact.
There are two answers to this question:
- You need to use
sizes
if you’re using thew
descriptor - it’s a required part of the spec, and the browser will likely display the image oddly without it - although it doesn’t have to be anything complicated, as shown in the first example. - You don’t need to use
sizes
for everything. Employing a new technology on every image is tempting, but the reality is that you only need to usesizes
where its needed to efficiently provide the best quality image at the right size on on a range of screens.
You can combine sizes
with both w
and the <picture>
element, examples of which I’ll leave for the final article on advanced responsive images, coming up next.
Photograph by nate2b, used under Creative Commons Attribution-NonCommercial-NoDerivs 2.0 Generic license
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.