CSS Responsive Images
Media queries reshaped layout when the viewport changed. Images are a separate stress point: a 4000px-wide file in a narrow column overflows, wastes bandwidth, or jumps the page while loading. This lesson covers fluid CSS, space reservation, and smarter sources — without repeating @media syntax from the previous session.
A responsive image toolkit
📊 Responsive images at a glance
| Piece | Everyday job |
|---|---|
max-width: 100% + height: auto |
Image scales down inside its column; keeps aspect ratio |
width / height on <img> or aspect-ratio in CSS |
Reserves layout space; reduces CLS while loading |
srcset + sizes |
Browser picks a file width near what the layout needs |
<picture> + <source media> |
Art direction — different crop or asset per condition |
object-fit + fixed box |
Crop or letterbox inside a known frame (see Object Fit lesson) |
| Media queries on layout | Still move columns and nav — images follow the column width |
Think in two layers: layout width (container, grid, media queries) and image behavior (CSS scaling + which file the browser downloads). Fix overflow in CSS first; add srcset when the same visual needs smaller files on phones.
Fluid images — max-width and height: auto
The classic responsive habit: let the image never exceed its container, but never stretch taller than its natural proportions.
.article img {
max-width: 100%;
height: auto;
display: block;
}
Avoid setting only width: 100% on a gigantic intrinsic image without max-width — on some layouts that still forces awkward scaling. Pair fluid rules with reasonable source files or srcset so phones are not downloading poster-sized JPEGs for a thumbnail slot.
Reserve space — dimensions and aspect-ratio
When the browser knows width and height early, content below does not jump when the image arrives. Modern CSS can express the ratio directly.
.hero__photo {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
display: block;
}
For content photos that should stay fully visible, prefer fluid max-width without forcing cover. Use aspect-ratio + object-fit: cover when the design demands a fixed frame (avatars, card thumbs) — that overlaps the Object Fit lesson; here the point is stopping layout shift while staying responsive.
Resolution switching — srcset and sizes
srcset lists candidate files; sizes tells the browser how wide the image will render in the layout (not the viewport alone). The browser picks a resource — you are not writing @media blocks for every PNG width.
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="(min-width: 48rem) 640px, 100vw"
alt="Team at a whiteboard"
width="800"
height="450"
/>
Keep sizes honest: if CSS makes the image full viewport width on mobile but half the container on desktop, say so. Wrong sizes hints make the browser download files that are too large or too soft.
Art direction with <picture>
When the crop should change — portrait hero on phones, wide banner on desktop — nest <source> elements with media (or type for format choice) and keep one fallback <img> with alt.
<picture>
<source media="(max-width: 40rem)" srcset="hero-portrait.jpg" />
<source media="(min-width: 41rem)" srcset="hero-landscape.jpg" />
<img src="hero-landscape.jpg" alt="City skyline at dusk" width="1200" height="675" />
</picture>
Use picture for art direction, not for fifty duplicate breakpoints. Often srcset alone is enough when only resolution changes. Combine with the fluid CSS above so whichever file loads still fits the column.
Fixed frames — quick object-fit reminder
Responsive fluid photos use max-width. Responsive cards with equal-height tiles still need a sized box plus object-fit: cover — the dedicated Object Fit session owns that craft; here, notice the split so you do not stretch every gallery photo with fill.
.card__thumb {
width: 100%;
height: 12rem;
object-fit: cover;
display: block;
}
Work with media queries, not against them
Queries still change grid columns and sidebar visibility; images inherit the slot width those rules create. Update sizes when a breakpoint changes how wide the <img> renders. You are not replacing media queries — you are aligning image hints with the layout they already serve.
Try it yourself
- Drop a wide
<img>in a narrow column; fix overflow withmax-width: 100%andheight: auto. - Add
width,height, oraspect-ratioon one hero and reload — watch layout shift shrink. - Write one
srcsetwith three widths and a realisticsizesstring for your practice layout. - Build a
<picture>with two crops for narrow vs wide viewports. - In a card grid, use a fixed-height thumb with
object-fit: coverand note how that differs from step 1.
Common mistakes
- Huge
srconly — nosrcset— so mobile downloads desktop poster files width: 100%withoutheight: auto(or vice versa) and distorted photossizes="100vw"everywhere while CSS actually renders a 320px sidebar imageobject-fiton an image with no constrained box — nothing to fit into- Re-teaching
@mediasyntax here instead of tying queries to slot width andsizes
Summary
- Fluid CSS (
max-width: 100%,height: auto) keeps images inside responsive columns - Reserve space with dimensions or
aspect-ratioto reduce layout jump srcset/sizesoptimize which file loads;<picture>handles art directionobject-fitis for fixed frames, not the default for every inline photo- Next: Breakpoints — naming and planning query strategy across the whole page
🧠 Test Your Knowledge
Test Your Knowledge
Challenge yourself with this interactive quiz and see how well you understand the topic
📝 Instructions
- Read each question carefully
- Select the best answer for each question
- You can retake the quiz as many times as you want
- Your progress will be shown at the top