{
    "slug": "responsive_images",
    "term": "Responsive Images",
    "category": "frontend",
    "difficulty": "intermediate",
    "short": "Serving different image sizes to different devices using srcset and sizes — preventing mobile devices from downloading desktop-sized images.",
    "long": "The srcset attribute provides multiple image sources with width descriptors (300w, 600w, 1200w). The sizes attribute tells the browser the display size at each viewport width. The browser picks the most appropriate source. The picture element enables art direction — different crops for different screens. The modern stack: generate WebP and AVIF variants, use srcset for density/size selection, and use picture for format selection with fallback. Tools: Imagemagick, sharp (Node), imgproxy, Cloudinary.",
    "aliases": [
        "srcset",
        "picture element",
        "art direction",
        "image sizes"
    ],
    "tags": [
        "frontend",
        "performance",
        "responsive"
    ],
    "misconception": "CSS max-width: 100% makes images responsive — CSS only scales the display; the browser still downloads the full-resolution image; srcset controls what gets downloaded.",
    "why_it_matters": "A mobile user downloading a 2400×1600 hero image sized 400×267 in CSS wastes 6× the bandwidth — srcset ensures they download the appropriately sized image.",
    "common_mistakes": [
        "srcset without sizes — browser assumes full viewport width and picks too large an image.",
        "No WebP/AVIF fallback in picture element — older browsers see nothing without the fallback img.",
        "Same image at different sizes without art direction — portrait images need different crops, not just scaling.",
        "Not pre-generating images server-side — on-the-fly resizing is slow; cache generated variants."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "lazy_loading_images",
        "web_vitals",
        "image_optimisation",
        "render_blocking_resources"
    ],
    "prerequisites": [
        "image_optimisation",
        "web_vitals",
        "responsive_design_patterns"
    ],
    "refs": [
        "https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images"
    ],
    "bad_code": "<!-- One large image for all devices:\n<img src=\"hero-2400w.jpg\" alt=\"Hero\" style=\"max-width:100%\">\n<!-- Mobile: downloads 2400px image, displays at 400px — 6x wasted bandwidth -->",
    "good_code": "<!-- srcset for resolution switching:\n<img\n  srcset=\"hero-400w.webp 400w, hero-800w.webp 800w, hero-1600w.webp 1600w\"\n  sizes=\"(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 800px\"\n  src=\"hero-800w.jpg\"\n  alt=\"Hero\"\n  loading=\"eager\" fetchpriority=\"high\"\n  width=\"800\" height=\"400\">\n\n<!-- picture for format + art direction:\n<picture>\n  <source media=\"(max-width:600px)\" srcset=\"hero-mobile.avif\" type=\"image/avif\">\n  <source media=\"(max-width:600px)\" srcset=\"hero-mobile.webp\" type=\"image/webp\">\n  <source srcset=\"hero-desktop.avif\" type=\"image/avif\">\n  <img src=\"hero-desktop.jpg\" alt=\"Hero\">\n</picture>",
    "quick_fix": "Use srcset with w descriptors and a sizes attribute — the browser selects the right image size for the viewport; PHP generates the multiple resized versions on upload",
    "severity": "high",
    "effort": "medium",
    "created": "2026-03-16",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/responsive_images",
        "html_url": "https://codeclaritylab.com/glossary/responsive_images",
        "json_url": "https://codeclaritylab.com/glossary/responsive_images.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Responsive Images](https://codeclaritylab.com/glossary/responsive_images) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/responsive_images"
            }
        }
    }
}