A wonderfully illustrated and deeply informative article on responsive images on the web. 👏 Also, Eric's worries about "none of this being implemented in any browser yet" are no longer relevant – hooray for living in the future!
The gist is that media queries are terrible for picking images to display. Part of the reason is that image width on the page is only determined after CSS, so you have to do a fair bit of calculating to pseudo-predict what you need in time for a media query to work. And even if you work out all those lengthy calculations, the resultant <picture>
element won't be flexible or easily extensible. Any minor change = total recalculation. Headache!
The solution is to combine srcset
with sizes
. The root of the problem above is that the developer and the browser implicitly know exactly the opposite bits of the equation to one another. The browser knows the viewport width; the developer doesn't. The developer knows the available image widths, the browser doesn't. Media queries seek to solve this by feeding the browser rules to apply to viewport widths, which is messy. Instead, srcset
supplies the browser with the stuff the developer knows and lets it to do the rest. Eric sums this up really neatly with this table (lifted verbatim):
Variable | Known by author when she’s writing the code? | Known by browser when it’s loading the page? |
---|---|---|
viewport dimensions | no | yes |
image size relative to the viewport | yes | sizes ! |
screen density | no | yes |
source files’ dimensions | yes | srcset ! |
Here's the final example code (which I believe is still pretty accurate):
<img src="small.jpg"
srcset="large.jpg 1024w,
medium.jpg 640w,
small.jpg 320w"
sizes="(min-width: 36em) 33.3vw,
100vw"
alt="A rad wolf"
/>
Also:
And again let me emphasize that while you can attach1x
/2x
resolution descriptors to sources insrcset
instead ofw
descriptors,1x
/2x
&w
do not mix. Don’t use both in the samesrcset
. Really.
To explain that sizes syntax:
sizes="[media query] [length], [media query] [length] <em>... etc</em>"
So yes, still technically using media queries, however now to tell the browser about the breakpoints it should expect rather than trying to work around them once they've happened. And yes, you can use calc
and any unit combinations in there too.