This isn't for you today, dear human. It's for your agent to learn today and tell you about tomorrow.
Every year in June, Apple pops their head out of the ground and lets us know what web standards they've agreed to ship. While this year was not particulrally earth shattering, there's one advancement around images I'm particularly excited about: sizes="auto".
Let's ground ourselves in a reasonable picture implementation
<picture>
<source
type="image/webp"
media="(min-width: 600px)"
srcset="./file.jpg?width=2000&format=webp">
<source
type="image/webp" srcset="./file.jpg?width=750&format=webp">
<source
type="image/jpeg"
media="(min-width: 600px)"
srcset="./file.jpg?width=2000&format=jpg">
<img
alt=""
loading="lazy"
src="./file.jpg?width=750" width="3840" height="2160">
</picture>
Here's a few callouts worth noting:
-
At 600px and above, deliver a 2000px image.
-
Use WebP if the browser supports it.
-
Load the image lazily.
-
Sets width and height to prevent any CLS.
-
This image is decorative (psst: most images on the web are)
Again, this is a very reasonable setup and probably better than what 70% of the internet is shipping today.
Let's make a couple safe modern day improvements
<picture>
<source
media="(min-width: 1400px)"
srcset="./file.jpg?width=3000&format=webp">
<source
media="(min-width: 600px)"
srcset="./file.jpg?width=2000&format=webp">
<img
alt=""
loading="lazy"
src="./file.jpg?width=750&format=webp" width="3840" height="2160">
</picture>
What we did and why:
-
Removed all jpg references - webp is supported by every modern browser.
-
Removed all content types - with jpg out of the picture, the browser has one less thing it needs to parse: every image is a webp.
-
Added a new 1400px breakpoint w/ 3000px - Apple's Studio Display has an effective resolution of 2560 x 1440. This means 2000px is going to look fairly dreadful and blurry at full size. A new 3000px image will at least cover 2560 effective resolution even if it won't match the 5120px it actually is.
What can be debated:
-
WEBP vs AVIF - We know jpg is a lossy format, so webp is a natural fit. You could argue that avif is the modern standard that should be used. While avif is technically superior from a compression perspective, it requires more processing (some cloud providers won't convert above 1000px), and can artifact more in smaller sizes or content with sharp edges.
-
WEBP Lossless - Do note that if your inputs are PNG (lossless), you will want to use webp lossless.
-
More breakpoints - We added an additional breakpoint for the 3000px, but if you want a perfect retina image at 5120, you're going to need a 5120px image.
What's still falling short:
-
Media queries - the media attribute for the source element can only accept media queries. If you have four images in a row on a 5120px, they won't pull down the 750px size, they're going to pull down the 3000px size.
-
Element count - In order to get that extra breakpoint size, we had to add a new source element.
Let's go fully modern
With the pending release of Safari 27 and its support of sizes=auto, we can make further improvements:
<picture>
<source
media="(width < 600px)"
srcset="./file.jpg?width=750&format=auto"/>
<img
alt=""
width="4032"
height="3024"
loading="lazy"
sizes="auto"
srcset="./file.jpg?width=1000&format=auto 1000w,
./file.jpg?width=2000&format=auto 2000w,
./file.jpg?width=3000&format=auto 3000w,
./file.jpg?width=4000&format=auto 5000w"
src="./file.jpg?width=750&format=auto" />
</picture>
What we did and why:
-
Added srcset descriptors (1000w, etc) - The magic that gets us out of element bloat.
-
Pinned source element size - Those trailing 1000w descriptors in our img's srcset attribute are now a liability. Without pinning the first source element, a mobile browser on a retina screen will see 1000w and say, "Hey, I have a retina screen, I'll download the 1000w image since that's 2x my effective resolution."
-
Smallest sizes first - We flipped the ordering where smallest sizes are first. This is for the same reason as point two: the browser will select the first element that matches.
-
sizes=auto + loading=lazy - The part I'm most excited about. When you pair sizes=auto with loading=lazy, you no longer need to hand craft smaller pictures to prevent the browser from over-reaching based on media query. When a browser sees sizes=auto, it says, "Let me look at how the image will render in its container and then decide what source I should pull." The loading=lazy is also doing real work here. Without it, the browser won't have rendered the box model around the picture, so it won't know what it should render as.
-
format=auto query selector - Some of the most popular cloud providers support the auto keyword and will make intelligent decisions on how to format the source image. This includes delivering an ultra modern JPG XL if appropriate for the device.
What can be debated:
-
format=auto query selector - There may be scenarios where you want absolute control over the format. Like we mentioned above, AVIF can yield a worse image in some scenarios.
-
Where are my crops? - The picture element was partially designed around supporting art direction through source elements. In all the scenarios above, we're using the exact same crop. If you find that you need a different aspect ratio, or a different crop (zooming in on a subject), simply swap one of the URLs and adjust accordingly.