Responsive Images
A photo prepared for a wide monitor can be ten times the file size a phone needs, and the phone downloads every byte of it before shrinking it to fit a small screen. On a slow connection, that is seconds of waiting for detail nobody can see. HTML lets you offer several sizes of the same image and have the browser pick the one that suits the screen, offer newer formats with a fallback, and let images far down the page wait until they are needed.
Ordering a print of a photo is the same choice. You ask for the size that fits the frame on your wall, not the largest poster the shop can make. A responsive image is a list of print sizes, and the browser orders the one that fits.
Images That Fit
An image is shown at its natural size unless something says otherwise, so a 1600-pixel photo is 1600 pixels wide even on a phone, and the page scrolls sideways. One rule, placed near the top of the site's stylesheet, prevents that for every image.
img {
max-width: 100%;
height: auto;
}
max-width: 100% lets an image be as large as its natural size but never wider than the space it is in, so on a phone it shrinks to the width of the screen. height: auto keeps its proportions as it shrinks. Without that second line, the height attribute from Chapter 2 would hold the image at its full height while its width shrank, and the photo would appear squashed.
srcset and sizes
The fitting rule makes an image look right, but the file is as heavy as before. The fix is to save the photo at several widths and list them all. One term first. The pixel density of a screen is how many of its physical dots make up one CSS pixel: most laptops have 1 or 2, and many phones have 2 or 3, which is what makes them sharp. A 375-pixel-wide phone at density 2 needs a 750-pixel image to look crisp.
<img src="images/soup-800.jpg" srcset="images/soup-400.jpg 400w, images/soup-800.jpg 800w, images/soup-1200.jpg 1200w, images/soup-1600.jpg 1600w" sizes="(min-width: 60rem) 60rem, 100vw" alt="A bowl of tomato soup with basil leaves on a wooden table" width="1600" height="1067">
The srcset attribute lists the four files, each with its real width followed by the letter w. The sizes attribute tells the browser how wide the image will be shown, before any CSS has loaded. Read it as a sentence: if the window is at least 60 rem wide, the image is shown 60 rem wide, like the main column from the last topic; otherwise, it fills the whole width of the window. The src is the fallback for any browser that ignores the other two.
From those two facts, the browser works out how many real pixels it needs and downloads one file, typically the smallest that is at least that wide. A phone 375 pixels wide at density 2 needs 750, and gets the 800 file. A laptop at density 1 showing the image 60 rem wide, 960 pixels, gets the 1200 file. A sharp wide monitor gets the 1600 file. The browser has the final say, and it may keep using a larger file it already has in its cache rather than download a smaller one.
To watch it choose, open device mode, pick a phone, and open the Network panel with the Img filter and the Disable cache box ticked. Reload, and the list shows the one file that was downloaded. Pick a wider screen, reload again, and a different file appears. The page looks the same both times; only the weight changes.
picture: Newer Formats and Different Crops
Chapter 2 introduced the newer image formats, AVIF and WebP, which give the same picture in a smaller file than JPEG. All current major browsers show both. The picture element lets you offer them first and keep a JPEG for anything older.
<picture> <source srcset="images/soup.avif" type="image/avif"> <source srcset="images/soup.webp" type="image/webp"> <img src="images/soup.jpg" alt="A bowl of tomato soup with basil leaves on a wooden table" width="1600" height="1067"> </picture>
The browser reads the source elements in order and uses the first one whose format it understands; a current browser downloads only the AVIF file. The img inside is required. It is the element actually shown, it carries the alt text, width and height, and its src is the JPEG fallback. Visitors see the same soup whatever file arrives.
A source can also carry a media attribute with a media query. That is how a narrow screen gets a different crop, such as a square close-up of the bowl instead of the wide table scene. Use picture when the choice is between formats or crops; use srcset on its own when the choice is only between sizes of the same image.
Lazy Loading
By default the browser downloads every image on the page straight away, including ones at the very bottom that the visitor may never scroll to. The loading attribute set to lazy tells it to wait until the image is getting close to the visible part of the page.
<img src="images/garden.jpg" alt="Tomato plants growing against a sunny wall" width="800" height="533" loading="lazy">
On a long page, with this image well below the first screen, it is not requested when the page loads. The Network panel shows it appearing only as you scroll down towards it. Chrome starts the download early, while the image is still a screen or so away, so to see the effect, try it with the image several screens down. The width and height matter even more here: they reserve the image's space, so the text does not jump when the file arrives late.
Never lazy-load the first large image at the top of the page. It is the one the visitor is waiting to see, and telling the browser to delay it makes the page feel slower, which Chapter 13 measures.
- "
srcsetmakes the browser download every size." It downloads one: the file it picks for this screen. The others are never requested. - "Lazy-load everything to be safe." The first large image should load straight away, or the most important part of the page arrives last.
- "Shrinking an image with CSS makes it lighter." CSS changes how big it looks, not the file. A 3000-pixel photo shown 300 pixels wide still downloads all 3000 pixels.
- Images are usually the largest part of a page's weight, so this is the biggest single speed improvement in the book. Chapter 13 measures it.
- Visitors on phones and slow connections pay for every byte, in time and often in money. Sending them the right size is a courtesy they notice.
Knowledge Check
An img lists four widths in srcset. What does the browser download?
- All four files, then it shows the best one
- One file, chosen for this screen's needs
- Only the largest file, to be safe on any screen
- Only the file in src; srcset is a note to editors
Which image should not have loading="lazy"?
- A photo near the bottom of a long article
- The twentieth photo in a long scrolling gallery
- The large photo at the very top of the page
- A small image in the footer at the page's end
When is picture the right tool rather than srcset alone?
- When you only have the same photo in several sizes
- When the image needs alt text for screen readers
- When the image should wait until it is scrolled to
- When you offer different formats or different crops
A 3000-pixel-wide photo is shown 300 pixels wide by CSS. What does the visitor download?
- The whole 3000-pixel file, however small it looks
- A 300-pixel version the server makes for the visitor
- Only the part of the file needed for 300 pixels
- A compressed copy that the browser asks for itself
You got correct