The three jobs
Pictures raise three layout problems on responsive pages:
- Fit: the image must never be wider than its container.
- Shape: cards in a row need images of the same shape, even when the originals differ.
- Stability: the page should not jump when images finish loading.
CSS has a clean answer to each.
1. Fit: max-width
img { max-width: 100%; height: auto; }This is the first line of CSS for images on almost every site. max-width: 100% lets the picture shrink to fit but never grow past its natural size; height: auto keeps the proportions. It works with width and height attributes in the HTML (which reserve space before loading), because height: auto makes the browser use the ratio.
If you want an image to also grow to fill its container, use width: 100% instead.
2. Shape: aspect-ratio and object-fit
Cards look tidy when every thumbnail has the same shape. But photos arrive as portrait, landscape and square. The pair aspect-ratio and object-fit normalises them:
<style>
.thumb {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
border-radius: 8px;
display: block;
background: #cbd5e1;
}
.row { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
</style>
<div class="row">
<img class="thumb" alt="Tall placeholder" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='400'%3E%3Crect width='200' height='400' fill='%2393c5fd'/%3E%3Ccircle cx='100' cy='100' r='50' fill='%23f59e0b'/%3E%3C/svg%3E">
<img class="thumb" alt="Wide placeholder" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='150'%3E%3Crect width='400' height='150' fill='%23a7f3d0'/%3E%3Ccircle cx='300' cy='75' r='50' fill='%23f43f5e'/%3E%3C/svg%3E">
</div>Both images, one tall and one wide, fill identical 16:9 boxes.
aspect-ratio: 16 / 9sets the box shape. Other usual values are4 / 3,1 / 1(square) and3 / 4(portrait).object-fitsays how the picture fills its box:cover: fill the box, cropping what overflows (no distortion). Best for photos.contain: show the whole image, leaving empty bands. Best for logos and product shots.fill(default): stretch to fit, which distorts. Rarely wanted.noneandscale-down: use the natural size.
Choosing what stays visible
Cropping is centred by default. When the important part (a face, a product) is elsewhere, use object-position:
.avatar { object-fit: cover; object-position: 50% 20%; } /* keep the upper part */Round avatars
.avatar { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; }3. Stability: no layout jumps
When an image has no declared size, the browser does not know how much room it needs until the file arrives, and content below it jumps down. This hurts reading and the Cumulative Layout Shift score that search engines look at. Two fixes, and they work together:
- Put
widthandheightattributes on theimgtag, matching the file's real size. - Or set
aspect-ratioin CSS.
Either way the space is reserved from the start.
Background images
CSS can also paint an image behind an element:
.hero {
background-image: url("hero.jpg");
background-size: cover;
background-position: center;
min-height: 50vh;
}background-size: cover behaves like object-fit: cover. The image-set() function lets you supply 1x and 2x versions for sharper screens.
The crucial difference: a background image has no alt text and no meaning for assistive technology. Use backgrounds for decoration, such as textures, gradients and mood, and img with alt for anything the reader needs.
Backgrounds also do not appear when printing by default, and are not found by image search.
Choosing img or background
Use img |
Use a background |
|---|---|
| Photos, products, diagrams | Patterns, textures, gradients |
| Anything with meaning | Purely decorative art |
| Anything that should print | Layering behind text |
Performance reminders
Fitting an image to its box does not make the file smaller. A 4000-pixel photo in a 400-pixel card still downloads fully. Pair these CSS techniques with right-sized files, srcset, modern formats and loading="lazy" for images below the fold (the HTML images lessons covered these).
Common mistakes
- Setting both width and height on an image so it stretches.
- Using a background image for a photo that needs alt text.
- No reserved space, so the page jumps.
- Relying on CSS to shrink huge files.
- Cropping out the subject because
object-positionwas left at its default.
Exercise
Make a row of square avatars, 80px, rounded as circles, cropped to fill, with the face area (top 25%) preferred.
Show one possible answer
<style>
.avatars { display: flex; gap: 12px; }
.avatars img {
width: 80px; height: 80px;
border-radius: 50%;
object-fit: cover;
object-position: 50% 25%;
background: #e2e8f0;
}
</style>
<div class="avatars">
<img alt="Photo of Asha" src="asha.jpg">
<img alt="Photo of Kabir" src="kabir.jpg">
</div>Key points
- max-width 100 percent with height auto stops an image from overflowing and keeps its proportions.
- aspect-ratio reserves a shape for an image or box so the layout does not jump while it loads.
- object-fit cover fills a box by cropping, and contain shows the whole image with empty space around it.
- object-position chooses which part of a cropped image stays visible.
- Content images belong in img with alt text; use CSS backgrounds only for decoration.