Responsive Images
"Responsive images" covers two genuinely different problems that are easy to conflate: making an image fit its container correctly with CSS, and serving the right file for a given screen with HTML. This page focuses on the CSS side — sizing, cropping, and preventing layout shift — and clarifies where the HTML-side mechanism takes over.
The Classic Baseline Fix: max-width: 100%
Without any CSS, an <img> renders at its natural pixel dimensions, happily overflowing a narrower container. The single most important responsive-image rule fixes that in one line:
img {
max-width: 100%;
height: auto; /* preserves aspect ratio as width shrinks */
display: block; /* removes inline-element whitespace gaps */
}max-width: 100% lets the image shrink to fit a narrow container while never exceeding its own natural size — it won't stretch a small image larger than it actually is. height: auto is essential alongside it; without it, the image's height stays fixed while its width shrinks, distorting the aspect ratio.
object-fit & object-position
Once an image has to fill a container with a fixed size or aspect ratio (a thumbnail grid, a hero banner), max-width: 100% alone isn't enough — you need control over how the image crops or letterboxes. See the full breakdown on the object-fit & object-position page; the short version:
.thumbnail {
width: 100%;
height: 200px; /* a fixed box the image must fill */
object-fit: cover; /* crop to fill, preserving aspect ratio */
object-position: center; /* which part of the image stays visible */
}aspect-ratio: Preventing Layout Shift
Images that load asynchronously collapse to zero height until they arrive, then suddenly push the rest of the page down — a major contributor to poor Cumulative Layout Shift scores. Recap: aspect-ratio reserves the image's final space immediately, before the file has even downloaded.
img.hero {
width: 100%;
aspect-ratio: 16 / 9; /* space is reserved instantly, no layout shift */
object-fit: cover;
}<img class="hero" src="banner.jpg" width="1600" height="900" alt="Descriptive text" />
Setting width and height attributes in the HTML (even though CSS overrides the rendered size) gives the browser the image's intrinsic aspect ratio before any CSS or the image file itself has loaded — modern browsers use these attributes to compute a default aspect-ratio automatically, which is a good belt-and-suspenders habit even when you also set aspect-ratio explicitly in CSS.
What srcset / sizes Handle Instead
<img src="photo-800.jpg" srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w" sizes="(min-width: 1024px) 50vw, 100vw" alt="Descriptive text" style="max-width: 100%; height: auto;" />
Putting It Together
max-width: 100%; height: auto;— the non-negotiable baseline for any inline image that should never overflow its container.object-fit/object-position— when the image must fill a fixed-size box exactly, with controlled cropping.aspect-ratio(plus HTMLwidth/height) — reserve layout space before the image loads, avoiding shift.srcset/sizes— a separate, HTML-level optimization for serving the right file size, orthogonal to how CSS lays the chosen image out.