Making images responsive
On the design side, you need to ensure that your images scale responsively, depending on the screen width or height. For example, if the user’s screen is 1,024 pixels wide, an image that’s 800 pixels wide will fit no problem, but that same image will overflow a 400-pixel-wide screen. You create responsive images with the following CSS rule:<em>image</em> { max-width: 100%; height: auto; }Here, image is a selector that references the image or images you want to be responsive. Setting
max-width: 100%
enables the image width to scale smaller or larger as the screen (or the image's container) changes size, but also mandates that the image can’t scale larger than its original width. Setting height: auto
cajoles the browser into maintaining the image’s original aspect ratio by calculating the height automatically based on the image’s current width.
Occasionally, you’ll want the image height to be responsive instead of its width. To do that, you use the following variation on the preceding rule:
<em>image</em> { max-height: 100%; width: auto; }
Delivering images responsively
On the user side, delivering images that are far larger than the screen size can be a major problem. Sure, you can make the images responsive, but you’re still sending a massive file down the tubes, which won’t be appreciated by those mobile surfers using slow connections with limited data plans.Instead, you need to deliver to the user a version of the image file that’s appropriately sized for the device screen. For example, you might deliver the full-size image to desktop users, a medium-sized version to tablet folk, and a small-sized version to smartphone users. That sounds like a complex bit of business, but HTML5 lets you handle everything from the comfort of the <img>
tag. The secret? The sizes
and srcset
attributes.
The sizes
attribute is a collection of expression-width pairs:
- The expression part specifies a screen feature, such as a minimum or maximum width, surrounded by parentheses.
- The width part specifies how wide you want the image displayed on screens that match the expression.
90vw
, you'd use the following expression-width pair:
(max-width: 600px) 90vwA typical
sizes
attribute is a collection of expression-width pairs, separated by commas. Here’s the general syntax to use:
sizes="(<em>expression1</em>) <em>width1</em>, (<em>expression2</em>) <em>width2</em>, etc., <em>widthN</em>"Notice that the last item doesn’t specify an expression. This tells the web browser that the specified width applies to any screen that doesn’t match any of the expressions.
Here’s an example:
sizes="(max-width: 600px) 90vw, (max-width: 1000px) 60vw, 30vw"The
srcset
attribute is a comma-separated list of image file locations, each followed by the image width and letter w
. Here's the general syntax:
srcset="<em>location1</em> <em>width1</em>w, <em>location2</em> <em>width2</em>w, etc.">This gives the browser a choice of image sizes, and it picks the best one based on the current device screen dimensions and the preferred widths you specify in the
sizes
attribute. Here's a full example:
<img src="/images/img-small.jpg" sizes="(max-width: 600px) 90vw, (max-width: 1000px) 60vw, 30vw" srcset="/images/img-small.png 450w, /images/img-medium.png 900w, /images/img-large.png 1350w">
The sizes
and srcset
attributes don't always work the way you might expect. For example, if the browser finds that, say, the large version of the image is already stored in its cache, then it will usually decide that it’s faster and easier on the bandwidth to just grab the image from the cache and scale it, instead of going back to the server to download a more appropriately sized file for the current screen.