Difficulty: Beginner
How do you implement responsive images? What are modern image formats?
Responsive images serve the right image size for the user's device/viewport.
Techniques: 1. srcset + sizes: browser picks the best resolution 2. picture element: art direction (different crops/formats) 3. CSS object-fit: control how images fill containers 4. loading='lazy': defer offscreen images 5. fetchpriority='high': prioritize above-fold images
Modern formats: - WebP: 25-35% smaller than JPEG, supports transparency - AVIF: 50% smaller than JPEG, excellent quality - SVG: vector graphics, infinite scaling - Use picture element for format fallbacks.
<!-- Resolution switching: same image, different sizes -->
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w,
photo-800.jpg 800w,
photo-1200.jpg 1200w,
photo-1600.jpg 1600w"
sizes="(min-width: 1024px) 33vw,
(min-width: 768px) 50vw,
100vw"
alt="Responsive photo"
loading="lazy"
decoding="async"
/>
<!-- sizes tells browser how wide the image will display:
- On desktop (1024px+): 33% of viewport
- On tablet (768px+): 50% of viewport
- On mobile: 100% of viewport
Browser calculates: viewport * size * devicePixelRatio
and picks the best srcset image -->
<!-- Retina display (density switching) -->
<img
src="logo.png"
srcset="logo.png 1x, logo@2x.png 2x, logo@3x.png 3x"
alt="Logo"
/>
The browser uses srcset + sizes to automatically pick the optimal image file. This saves bandwidth on mobile and looks sharp on retina displays.
<!-- Art direction: different crops per breakpoint -->
<picture>
<source media="(min-width: 1024px)"
srcset="hero-wide.jpg" />
<source media="(min-width: 768px)"
srcset="hero-medium.jpg" />
<img src="hero-mobile.jpg" alt="Hero" />
</picture>
<!-- Format fallback: modern -> legacy -->
<picture>
<source type="image/avif" srcset="photo.avif" />
<source type="image/webp" srcset="photo.webp" />
<img src="photo.jpg" alt="Photo" />
</picture>
<!-- Combined: format + responsive -->
<picture>
<source type="image/avif"
srcset="photo-400.avif 400w,
photo-800.avif 800w"
sizes="100vw" />
<source type="image/webp"
srcset="photo-400.webp 400w,
photo-800.webp 800w"
sizes="100vw" />
<img src="photo-800.jpg"
alt="Photo"
loading="lazy" />
</picture>
picture element gives full control: serve AVIF to modern browsers, WebP as fallback, JPEG for legacy. Browser picks the first supported source.
/* object-fit: control how image fills container */
.avatar {
width: 64px;
height: 64px;
border-radius: 50%;
object-fit: cover; /* crop to fill, keep ratio */
}
.thumbnail {
width: 100%;
height: 200px;
object-fit: cover;
object-position: center top; /* focus on top */
}
.contain-image {
object-fit: contain; /* fit inside, may letterbox */
}
/* Lazy loading */
img[loading="lazy"] {
/* Placeholder while loading */
background: #f3f4f6;
}
/* Aspect ratio for CLS prevention */
.image-wrapper {
aspect-ratio: 16 / 9;
overflow: hidden;
}
.image-wrapper img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* Background image responsive */
.hero {
background-image: url('hero-mobile.jpg');
background-size: cover;
background-position: center;
}
@media (min-width: 768px) {
.hero {
background-image: url('hero-desktop.jpg');
}
}
object-fit: cover is the most common - it fills the container while maintaining aspect ratio, cropping edges if needed. Like background-size: cover for img elements.
Images, Responsive Images, srcset, Picture Element, Lazy Loading, WebP/AVIF