CSS Academy · Lesson

Responsive Images and the Picture Element

Serve appropriately sized images with srcset, sizes, and the HTML picture element.

Lesson 4 of 413 steps

Responsive Images and the Picture Element is a free CSS Academy lesson on CoddyKit. This is lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the CSS Academy learning path, and your progress syncs across the web and the CoddyKit app. The CSS Academy course includes 4 lessons in total.

Responsive Image Challenges

A full-resolution desktop image downloaded on a mobile device wastes bandwidth and slows load time. Responsive images serve the right image at the right size for the device.

max-width: 100% Baseline

The minimum responsive image rule: prevent images from overflowing their container while preserving aspect ratio.

<img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1200' height='700'><rect width='1200' height='700' fill='%234f8cff'/><circle cx='600' cy='350' r='260' fill='%23ffb84d'/></svg>" alt="wide landscape" />

srcset for Different Resolutions

The srcset attribute provides multiple image sources. The browser picks the most appropriate based on device pixel ratio (DPR):

<img
  src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='800' height='500'><rect width='800' height='500' fill='%234f8cff'/><circle cx='400' cy='250' r='180' fill='%237ee787'/></svg>"
  srcset="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='800' height='500'><rect width='800' height='500' fill='%234f8cff'/><circle cx='400' cy='250' r='180' fill='%237ee787'/></svg> 1x, data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1600' height='1000'><rect width='1600' height='1000' fill='%234f8cff'/><circle cx='800' cy='500' r='360' fill='%237ee787'/></svg> 2x"
  alt="A beautiful landscape"
  style="max-width:100%;height:auto;display:block;"
>

srcset with Width Descriptors

Use w descriptors to tell the browser the actual pixel width of each image file:

<img
  src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='800' height='500'><rect width='800' height='500' fill='%23ffb84d'/></svg>"
  srcset="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='250'><rect width='400' height='250' fill='%23ffb84d'/></svg> 400w,
          data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='800' height='500'><rect width='800' height='500' fill='%23ffb84d'/></svg> 800w,
          data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1600' height='1000'><rect width='1600' height='1000' fill='%23ffb84d'/></svg> 1600w"
  alt="Hero image"
  style="max-width:100%;height:auto;display:block;"
>

sizes Attribute

The sizes attribute tells the browser how wide the image will appear at different viewport sizes, helping it pick the right source from srcset.

<img
  srcset="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='250'><rect width='400' height='250' fill='%23ffb84d'/></svg> 400w, data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='800' height='500'><rect width='800' height='500' fill='%23ffb84d'/></svg> 800w"
  sizes="(max-width: 600px) 100vw, 50vw"
  src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='800' height='500'><rect width='800' height='500' fill='%23ffb84d'/></svg>"
  alt="Product photo"
  style="max-width:100%;height:auto;display:block;"
>

The picture Element

The <picture> element gives full control over which image file is served using <source> elements with media conditions. The browser uses the first matching source.

<picture>
  <source media="(min-width: 1024px)" srcset="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1200' height='400'><rect width='1200' height='400' fill='%234f8cff'/><text x='30' y='220' font-size='40' fill='white'>hero-large</text></svg>">
  <source media="(min-width: 600px)"  srcset="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='800' height='400'><rect width='800' height='400' fill='%237ee787'/><text x='30' y='220' font-size='36' fill='white'>hero-medium</text></svg>">
  <img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='500' height='500'><rect width='500' height='500' fill='%23ffb84d'/><text x='20' y='260' font-size='30' fill='white'>hero-small</text></svg>" alt="Hero image" style="max-width:100%;height:auto;display:block;">
</picture>

Art Direction with picture

Art direction serves a different crop or composition for different screen sizes — not just a smaller version of the same image.

<picture>
  <!-- Wide crop for desktop -->
  <source media="(min-width: 768px)" srcset="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1200' height='300'><rect width='1200' height='300' fill='%23b57bff'/><text x='30' y='170' font-size='34' fill='white'>banner-wide (desktop crop)</text></svg>">
  <!-- Square crop for mobile (this preview is narrow, so this is what renders) -->
  <img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='500' height='500'><rect width='500' height='500' fill='%23b57bff'/><text x='20' y='260' font-size='26' fill='white'>banner-square (mobile crop)</text></svg>" alt="Banner" style="max-width:100%;height:auto;display:block;">
</picture>

Modern Image Formats: WebP and AVIF

The <picture> element enables format selection. Serve modern formats with fallback:

<picture>
  <source type="image/avif" srcset="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='600' height='400'><rect width='600' height='400' fill='%233fd0c9'/><text x='20' y='210' font-size='28' fill='white'>photo</text></svg>">
  <source type="image/webp" srcset="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='600' height='400'><rect width='600' height='400' fill='%233fd0c9'/><text x='20' y='210' font-size='28' fill='white'>photo</text></svg>">
  <img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='600' height='400'><rect width='600' height='400' fill='%233fd0c9'/><text x='20' y='210' font-size='28' fill='white'>photo</text></svg>" alt="Photo" style="max-width:100%;height:auto;display:block;">
</picture>

loading="lazy" for Performance

The loading="lazy" attribute defers off-screen image loading until the user scrolls near them:

<img
  src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='500' height='500'><rect width='500' height='500' fill='%23ff6b6b'/><text x='20' y='260' font-size='26' fill='white'>product</text></svg>"
  loading="lazy"
  decoding="async"
  alt="Product"
  style="max-width:100%;height:auto;display:block;"
>

width and height Attributes

Always include width and height attributes on images. They allow the browser to reserve layout space before the image loads, preventing layout shift (CLS).

<img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='800' height='600'><rect width='800' height='600' fill='%234f8cff'/><circle cx='400' cy='300' r='200' fill='%23ffd700'/></svg>" width="800" height="600" loading="lazy" alt="Photo" style="max-width:100%;height:auto;">

object-fit for Images in Containers

When an image is in a fixed-size container, use object-fit to control how it fills the space:

<img class="thumbnail" src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='800' height='300'><rect width='800' height='300' fill='%23b57bff'/><text x='20' y='170' font-size='30' fill='white'>wide source photo</text></svg>" alt="thumbnail" />

Quick Check

Which HTML attribute works alongside srcset to tell the browser the image's display width at various viewport sizes?

Recap

Responsive images use srcset and sizes to serve appropriately sized images. The <picture> element enables art direction and format selection. Always use loading="lazy", width/height attributes, and object-fit for containerized images.

Free to start

Learn CSS with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
40
Lessons
159

Frequently Asked Questions

Is the “Responsive Images and the Picture Element” lesson free?

Yes — the full text of “Responsive Images and the Picture Element” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the CSS Academy course, upgrade to CoddyKit PRO. The CSS Academy course includes 4 lessons in total.

What will I learn in “Responsive Images and the Picture Element”?

Serve appropriately sized images with srcset, sizes, and the HTML picture element. You practise CSS Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start CSS Academy?

No prior experience is required. CSS Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.

How long does the “Responsive Images and the Picture Element” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this CSS Academy lesson?

Yes. Every CSS Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Mobile-First vs Desktop-First Approach
  2. Fluid Widths with Percentages
  3. Min-Width and Max-Width Patterns
  4. Responsive Images and the Picture Element
← Back to CSS Academy