Himanshu SharmaCOBOX Technologies
Let’s talk

HTML · Lesson 12 of 31

Image sizes and formats

Serve the right image to every screen with srcset, sizes and the picture element, and offer modern formats such as WebP and AVIF with a safe fallback.

13 minImages and mediaUpdated 16 October 2026

By the end of this lessonWrite an img with srcset and sizes so phones download small files and large screens get sharp images, and use picture to offer modern formats.

One image, many screens

A photo that fills a desktop monitor might be 1600 pixels wide. On a phone the same photo is shown about 400 pixels wide. If every visitor downloads the big version, phone users wait longer and use more mobile data for detail they cannot see.

HTML lets you offer several versions of one image and leave the choice to the browser, which knows the screen size, the pixel density and sometimes even the network speed.

srcset with width descriptors

First create a few copies of the image at different widths, for example 480, 800 and 1600 pixels. Then list them in srcset, each followed by its real width and a w:

html
<img
  src="market-800.jpg"
  srcset="market-480.jpg 480w, market-800.jpg 800w, market-1600.jpg 1600w"
  sizes="(max-width: 700px) 100vw, 700px"
  alt="Vegetable stalls at a busy morning market"
  width="1600" height="1067">
  • src is the fallback for very old browsers, and the default choice.
  • srcset lists the candidates. 480w means "this file is 480 pixels wide", not "show it at 480 pixels".
  • sizes tells the browser how wide the image will be displayed. Here: on screens up to 700 pixels wide it fills the viewport width (100vw); otherwise it is shown at 700 pixels.

Why does the browser need sizes? It starts downloading images very early, before the CSS has worked out the page layout. Without sizes it assumes the image is as wide as the whole screen and may download a file that is far too large.

The browser then does the maths. On a phone 400 pixels wide with a 2× screen, the image is shown at 400 CSS pixels, which needs about 800 real pixels, so it picks market-800.jpg. On a desktop it needs 700 CSS pixels; on a 2× screen that is 1400 pixels, so it picks the 1600 version. You never have to write that logic yourself.

srcset with density descriptors

For images that are always shown at the same size, such as a logo or an avatar, density descriptors are simpler:

html
<img src="avatar-96.png" srcset="avatar-96.png 1x, avatar-192.png 2x" alt="Asha Rao" width="96" height="96">

A normal screen gets the 96-pixel file; a high-density "retina" screen gets the sharper 192-pixel one. No sizes is needed, because the display size never changes.

picture: modern formats with a fallback

AVIF and WebP files are usually much smaller than JPEG at the same quality. Every current major browser supports WebP, and AVIF support is very wide too, but the picture element lets you offer them safely to everyone:

html
<picture>
  <source type="image/avif" srcset="market-800.avif">
  <source type="image/webp" srcset="market-800.webp">
  <img src="market-800.jpg" alt="Vegetable stalls at a busy morning market" width="800" height="533">
</picture>

The browser reads the source elements in order and uses the first one whose type it supports. If none match, it uses the img. The img is not optional: it is the element that actually displays the picture, it carries the alt text and the size, and source elements only change which file it loads. You can combine this with srcset and sizes on each source for several widths in several formats.

picture for art direction

Sometimes a phone needs a different crop, not just a smaller file: a wide landscape banner may be unreadable on a narrow screen. source can take a media condition:

html
<picture>
  <source media="(max-width: 600px)" srcset="team-portrait.jpg">
  <img src="team-wide.jpg" alt="Our team of five at the office" width="1600" height="600">
</picture>

Narrow screens get the portrait crop; everything else gets the wide one. With media, the browser must follow your condition. With srcset alone it is free to choose, which is what you want for plain resizing.

Making the files

You do not need special software. Export a few widths from any photo editor, or use the free Image Compressor on this site to resize and convert to WebP in your browser. Many hosting platforms and frameworks can generate the sizes automatically as well.

A practical starting set for content images is three widths, roughly 480, 800 and 1200 to 1600 pixels. More versions give diminishing returns.

Common mistakes

  • Treating 800w as a display size. It is the file's width; display size comes from sizes and CSS.
  • Leaving out sizes with width descriptors, so the browser assumes full-screen width and downloads too much.
  • Putting alt on a source. source has no alt; it belongs on the img.
  • Forgetting width and height, which causes layout shift no matter how clever the srcset is.
  • Using picture for simple resizing. An img with srcset and sizes is enough; keep picture for formats and art direction.

Exercise

You have hero-600.webp, hero-1200.webp, hero-600.jpg and hero-1200.jpg. The hero image is shown at full screen width on phones and at 900 pixels on wider screens (from 900px up). Write a picture element that offers WebP with a JPEG fallback, both in two widths, with correct sizes, alt text, width and height (the large files are 1200 × 675).

Show one possible answer
html
<picture>
  <source type="image/webp"
          srcset="hero-600.webp 600w, hero-1200.webp 1200w"
          sizes="(min-width: 900px) 900px, 100vw">
  <img src="hero-1200.jpg"
       srcset="hero-600.jpg 600w, hero-1200.jpg 1200w"
       sizes="(min-width: 900px) 900px, 100vw"
       alt="Students working together at a long wooden table"
       width="1200" height="675">
</picture>

Key points

  • srcset lists several versions of the same image; the browser picks the best one for the screen.
  • Width descriptors (480w) plus a sizes attribute tell the browser how wide the image will be displayed.
  • Density descriptors (1x, 2x) are simpler and suit images that always display at one fixed size.
  • picture with source elements offers modern formats (AVIF, WebP) with a JPEG or PNG fallback in the img.
  • The img inside picture is still required and still needs alt, width and height.

Check yourself

1. What does the 800w in srcset="photo-800.jpg 800w" mean?
2. Why does the browser need the sizes attribute?
3. In <picture>, what happens in a browser that does not support AVIF?

Free tools for this lesson