RWD Responsive Images
The two-line CSS rule img { max-width: 100%; height: auto; } keeps images from breaking a layout, but it doesn't shrink how much data a phone actually downloads.
Why Images Don't Behave Like Text
A paragraph of text automatically reflows to fit whatever width it's given, but an <img> element carries an intrinsic size baked into the file itself. Drop a 1600-pixel-wide photo into a 320-pixel-wide phone screen with no CSS at all, and the image stays 1600 pixels wide, pushing the whole page into horizontal scrolling.
The Problem
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<img src="skyline.jpg" alt="City skyline at dusk">
/* With no CSS rule, this renders at its
native file width -- even inside a
320px-wide phone viewport. */
</body>
</html>The fix is a short rule that's worth memorizing, because you'll reach for it on nearly every project:
The Fix
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
img {
max-width: 100%;
height: auto;
display: block;
}
</style>
</head>
<body>
</body>
</html>- max-width: 100% caps the image at the width of its containing element, but still lets it be narrower.
- height: auto recalculates the height to match whatever width the browser lands on, so the original aspect ratio is preserved instead of the image stretching or squashing.
- display: block removes the few pixels of gap that inline images leave underneath them, caused by normal line-height spacing.
Fluid Images Need a Fluid Container
A responsive image rarely works in isolation -- it inherits its available width from whatever wraps it. The max-width: 100% rule only has something meaningful to respond to if its parent is itself allowed to resize, whether through percentages, a fluid grid, or a flex layout.
Image Inside a Responsive Card
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.card {
width: 100%;
max-width: 360px;
}
.card img {
max-width: 100%;
height: auto;
display: block;
}
</style>
</head>
<body>
<div class="card">
<img src="mountain.jpg" alt="Mountain range at sunrise">
<p>Mountain Range Trail</p>
</div>
</body>
</html>What max-width Doesn't Solve: File Weight
This CSS rule only ever controls how large the image is drawn on screen -- it does nothing to change how large the downloaded file is. A phone showing that photo at 343px wide still fetches the exact same 1600px-wide file a desktop monitor would, wasting data and slowing the page down on the connections that can least afford it. Solving that problem needs a different tool: the srcset attribute and the <picture> element, covered next, which let the browser choose a differently sized (or differently cropped) file for each situation instead of resizing one file with CSS alone.