Responsive Images Done Right

matt
Matthew Gros · Oct 25, 2025

TLDR

Use srcset for resolution switching, picture element for art direction, lazy load below the fold.

Responsive Images Done Right

Images Are Often the Biggest Files

Serve appropriate sizes to save bandwidth.

srcset for Resolution Switching

<img
    src="image-800.jpg"
    srcset="
        image-400.jpg 400w,
        image-800.jpg 800w,
        image-1200.jpg 1200w
    "
    sizes="(max-width: 600px) 100vw, 800px"
    alt="Description"
>

Browser picks the best size based on viewport and pixel density.

Picture for Art Direction

Different crops for different screens:

<picture>
    <source
        media="(min-width: 1024px)"
        srcset="hero-wide.jpg"
    >
    <source
        media="(min-width: 640px)"
        srcset="hero-medium.jpg"
    >
    <img src="hero-mobile.jpg" alt="Hero image">
</picture>

Modern Formats

<picture>
    <source srcset="image.avif" type="image/avif">
    <source srcset="image.webp" type="image/webp">
    <img src="image.jpg" alt="Description">
</picture>

AVIF > WebP > JPEG for file size.

Lazy Loading

<!-- Native lazy loading -->
<img src="image.jpg" loading="lazy" alt="Description">

<!-- Above the fold - don't lazy load -->
<img src="hero.jpg" loading="eager" alt="Hero">

Background Images

.hero {
    background-image: url('small.jpg');
}

@media (min-width: 768px) {
    .hero {
        background-image: url('large.jpg');
    }
}

Automated Processing

// Laravel with Intervention Image
$image = Image::make($upload);
$image->resize(800, null, fn($c) => $c->aspectRatio());
$image->encode('webp', 80);
Storage::put('images/resized.webp', $image);

About the Author

matt

I build and ship automation-driven products using Laravel and modern frontend stacks (Vue/React), with a focus on scalability, measurable outcomes, and tight user experience. I’m based in Toronto, have 13+ years in PHP, and I also hold a pilot’s license. I enjoy working on new tech projects and generally exploring new technology.