Responsive Images: srcset, sizes, picture
Lesson 27 โข Advanced Track
What You'll Learn
๐ก Think of It Like This
Imagine a restaurant with small, medium, and large portion sizes. You wouldn't serve a large plate to someone who ordered small. Similarly, srcset lets the browser order the right-sized image โ a phone gets a 400px image, while a 4K monitor gets 2000px. Everyone gets a perfect portion, and you don't waste bandwidth delivering oversized files.
Understanding Responsive Images
Images are typically the largest files on any web page โ often 60-80% of total page weight. Serving a single high-resolution image to all devices wastes bandwidth on mobile and slows down page load. Responsive images solve this by letting the browser choose the best image for the user's device, viewport size, and network conditions.
There are two distinct problems responsive images solve: resolution switching (same image, different file sizes) and art direction (completely different images for different viewports โ e.g., a wide landscape hero on desktop but a tight square crop on mobile). The srcset/sizes attributes handle resolution switching, while the <picture> element handles art direction.
Modern CSS also provides object-fit to control how images fill their containers (like background-size: cover but for <img> tags), and aspect-ratio to reserve space before images load, preventing the dreaded layout shift.
Quick Reference
| Attribute/Element | Use Case | Key Syntax | Performance Impact |
|---|---|---|---|
| srcset | Multiple resolutions | img.jpg 400w, img-lg.jpg 800w | Saves bandwidth on small screens |
| sizes | Viewport-relative widths | (max-width: 600px) 100vw, 50vw | Helps browser pick optimal size |
| <picture> | Art direction / formats | <source media="..." srcset="..."> | Different crops per viewport |
| loading="lazy" | Deferred loading | <img loading="lazy" ...> | Reduces initial page weight |
| aspect-ratio | Reserve space | aspect-ratio: 16 / 9 | Prevents layout shift (CLS) |
srcset & sizes โ Resolution Switching
The srcset attribute lists image files with their widths (using the w descriptor). The sizes attribute tells the browser how wide the image will be displayed at various viewport widths. The browser combines this information with the device pixel ratio to choose the optimal file.
srcset & sizes
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: system-ui, sans-serif; padding: 20px; max-width: 800px; margin: 0 auto; }
img { width: 100%; height: auto; border-radius: 8px; display: block; }
.info { background: #E3F2FD; padding: 16px; border-radius: 8px; margin: 16px 0; }
.info code { background: #BBDEFB; padding: 2px 6px; border-radius: 4px; }
.demo-section { margin: 24px 0; border: 1px solid #ddd; padding: 16px; border-radius: 8px; }
...The <picture> Element โ Art Direction
While srcset serves the same image at different sizes, <picture> lets you serve completely different images. This is called art direction โ a landscape hero on desktop, a tightly cropped portrait on mobile. You can also use it to serve WebP/AVIF with JPEG fallbacks using the type attribute.
<picture> Element
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: system-ui, sans-serif; padding: 20px; }
img { width: 100%; height: auto; border-radius: 8px; }
.card { border: 1px solid #ddd; border-radius: 12px; overflow: hidden; max-width: 600px; margin: 16px 0; }
.card-body { padding: 16px; }
h2 { color: #1565C0; margin-top: 0; }
.code-block {
background: #263238;
color: #EEFFFF;
padding: 16px;
border
...Lazy Loading & object-fit
Adding loading="lazy" defers image loading until the user scrolls near them โ critical for pages with many images. Meanwhile, object-fit: cover ensures images fill their containers without distortion, cropping overflow instead of stretching.
Lazy Loading & object-fit
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: system-ui, sans-serif; padding: 20px; max-width: 600px; margin: 0 auto; }
.gallery { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.gallery img {
width: 100%;
height: 200px;
object-fit: cover;
border-radius: 8px;
background: #f0f0f0;
}
.tip { background: #FFF3E0; padding: 16px; border-radius: 8px; border-left: 4px s
...aspect-ratio โ Preventing Layout Shift
The aspect-ratio CSS property lets you define a box's preferred aspect ratio. When applied to image containers, it reserves the correct amount of vertical space before the image loads, preventing the page from "jumping" as images appear. This directly improves your Cumulative Layout Shift (CLS) score.
aspect-ratio & Image Containers
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: system-ui, sans-serif; padding: 20px; max-width: 700px; margin: 0 auto; }
.ratio-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
margin: 24px 0;
}
.ratio-card {
border: 1px solid #e0e0e0;
border-radius: 8px;
overflow: hidden;
}
.ratio-card img {
...When to Use What
- srcset + sizes โ Use for every content image where you have multiple resolutions (most common case).
- <picture> โ Use when you need different crops for mobile vs desktop, or to serve WebP with JPEG fallbacks.
- loading="lazy" โ Use for all images below the fold. Never lazy-load your hero/above-the-fold image.
- aspect-ratio โ Use on any image container to prevent layout shift during loading.
- object-fit: cover โ Use whenever images need to fill a fixed-size container without distortion.
โ ๏ธ Common Mistakes
- Missing the fallback <img> โ The
<picture>element always needs an<img>as the last child; browsers that don't support <source> use it. - Wrong srcset descriptor โ Use
w(width) for resolution switching andx(density) only for fixed-size images like icons. - Lazy-loading above-the-fold images โ Don't lazy-load your hero image; it delays Largest Contentful Paint (LCP) and hurts your Core Web Vitals.
- Forgetting width/height attributes โ Without explicit
widthandheighton<img>, browsers can't calculate aspect ratio before download, causing layout shift. - Serving only WebP without fallback โ Some older browsers don't support WebP. Always include a JPEG/PNG
<source>or<img>fallback. - Using object-fit without a fixed container โ
object-fitonly works when the image has explicit width and height constraints.
๐ Lesson Complete
- โ
srcset+sizes= resolution switching (same image, right size) - โ
<picture>= art direction (different image for different contexts) - โ
loading="lazy"boosts performance by deferring off-screen images - โ
object-fit: coverprevents distorted images in fixed containers - โ
aspect-ratioreserves space to prevent layout shift (CLS) - โ Always provide width/height attributes for proper space reservation
- โ Serve modern formats (WebP, AVIF) with fallbacks for older browsers
- โ Never lazy-load above-the-fold images โ it hurts LCP scores
Sign up for free to track which lessons you've completed and get learning reminders.