Responsive Images: srcset, sizes, picture

    Lesson 27 โ€ข Advanced Track

    What You'll Learn

    Use srcset and sizes to serve resolution-appropriate images
    Implement art direction with the <picture> element
    Serve modern formats (WebP, AVIF) with fallbacks
    Apply lazy loading for performance with loading='lazy'
    Control image rendering with object-fit and object-position
    Use the aspect-ratio property to prevent layout shift

    ๐Ÿ’ก 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/ElementUse CaseKey SyntaxPerformance Impact
    srcsetMultiple resolutionsimg.jpg 400w, img-lg.jpg 800wSaves bandwidth on small screens
    sizesViewport-relative widths(max-width: 600px) 100vw, 50vwHelps 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-ratioReserve spaceaspect-ratio: 16 / 9Prevents 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.

    Code Preview
    <!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

    Try it Yourself ยป
    Code Preview
    <!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

    Try it Yourself ยป
    Code Preview
    <!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

    Try it Yourself ยป
    Code Preview
    <!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 and x (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 width and height on <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-fit only 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: cover prevents distorted images in fixed containers
    • โœ… aspect-ratio reserves 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.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy Policy โ€ข Terms of Service