ScreenshotNeo

BlogHow-to

HTML Picture Element: How to Serve Responsive Images

Learn when to use <picture>, when <img srcset> is enough, and how to choose image candidates with accurate sizing and a reliable fallback.

By the ScreenshotNeo team4 October 20268 min read

Use <picture> when a browser may need a different image composition for a condition, such as a tighter crop on a narrow screen, or when you want to offer alternative image formats. Use <img srcset> when the composition stays the same and the browser should choose among different resolutions. In either pattern, the <img> is essential: it supplies the fallback, alternative text, and dimensions.

The browser considers <source> candidates inside <picture> and uses the first suitable one. If none applies or can be used, it falls back to the child <img>. MDN’s picture reference describes the element and its source-selection role.

1. Choose the right responsive image pattern

What changes? Use Why
Only the required pixel resolution changes; the image content and crop stay the same. <img srcset> with width candidates and sizes, or density candidates for a fixed rendered size. This tells the browser it can choose a suitable resolution of the same image.
The composition or crop should change for a display condition. <picture> with media-conditioned <source> elements. Each condition can select a deliberately different image.
You want to offer different encoded formats of the same visual. <picture> with sources that declare a format using type. A browser can skip a format it does not support and use a later source or the fallback.

You can combine art direction and format choices when the assets and conditions call for it. Keep the source order intentional: put narrow or otherwise specific media conditions before broad defaults, and put the fallback <img> last.

2. Resolution switching with srcset and sizes

For a fluid image whose composition stays the same, provide width candidates. The w number describes each file’s intrinsic width in pixels; sizes describes the image’s expected rendered slot width in the layout.

<img
  src="landscape-800.jpg"
  srcset="landscape-480.jpg 480w,
          landscape-800.jpg 800w,
          landscape-1200.jpg 1200w"
  sizes="(max-width: 600px) 100vw,
         800px"
  width="1200"
  height="800"
  alt="A kayaker crossing a lake at sunrise">

Replace the example breakpoint and 800px slot with values that match your page’s real CSS layout. For example, if the image occupies half a content column on desktop, claiming 100vw at that size can make the browser choose a larger candidate than the slot needs. The browser uses sizes together with the width candidates to make its choice; it can also account for the device’s display density.

Include a useful src fallback for clients that do not use srcset. Set width and height to the image’s intrinsic dimensions so the browser can reserve its aspect ratio while the image loads. CSS can still make it fluid, for example max-width: 100%; height: auto.

3. Art direction with picture

Use a media condition when the image should tell the same story with a different composition at a particular layout size. The example below uses a portrait crop on narrow screens and a wide image otherwise.

<picture>
  <source
    media="(max-width: 600px)"
    srcset="portrait-crop.jpg">
  <img
    src="wide-landscape.jpg"
    width="1200"
    height="800"
    alt="A kayaker crossing a lake at sunrise">
</picture>

Use the same alternative text if both assets communicate the same information. Write alt text for the image’s purpose, not to explain that the crop changed. If a crop changes what information matters, make sure the alternative text still describes the information conveyed by the selected image.

For several art direction conditions, list specific conditions first and leave the broad/default image to the <img>. Keep media conditions aligned with the breakpoints where your layout actually changes.

4. Offer modern formats with a fallback

Use a type attribute to identify the encoded format of a source. The browser can skip a format it does not support, consider the next source, and ultimately use the <img> fallback.

<picture>
  <source srcset="scene.avif" type="image/avif">
  <source srcset="scene.webp" type="image/webp">
  <img
    src="scene.jpg"
    width="1200"
    height="800"
    alt="A kayaker crossing a lake at sunrise">
</picture>

Serve each file with a matching content type, such as image/avif, image/webp, or image/jpeg, and make sure the file really is encoded in the declared format. A source’s type is a selection hint, not a conversion: it does not turn one file format into another. Keep the fallback asset available.

5. Use density candidates for fixed-size images

When an image is displayed at a fixed CSS size and you only need variants for different display densities, density descriptors such as 1x and 2x can be simpler than width candidates.

<img
  src="avatar-1x.jpg"
  srcset="avatar-1x.jpg 1x,
          avatar-2x.jpg 2x"
  width="160"
  height="160"
  alt="Portrait of Jordan Lee">

Use either width descriptors such as 480w or density descriptors such as 2x within a single srcset list; do not mix the two kinds. sizes participates in selection with width candidates. It is not a control for x density candidates.

6. Build and publish an image set

  1. Decide whether the composition changes. If it does not, start with srcset. If you need a different crop or composition for a condition, use <picture>.
  2. Prepare candidates that serve a real layout. For width switching, create the same composition at several useful intrinsic widths. For art direction, create the alternate crop deliberately.
  3. Write the selection rules. Use width descriptors and a realistic sizes value for fluid layouts, media conditions for composition changes, or density descriptors for fixed CSS dimensions.
  4. Add the fallback and semantics. Keep an <img> child with a valid src, appropriate alt, and intrinsic width and height.
  5. Check delivery. Confirm candidate URLs resolve, file formats match declared types, and the server sends appropriate MIME types.
  6. Review at real breakpoints. Check the image slot against the rendered CSS layout and confirm each intended crop appears at the conditions you specified.

The browser chooses from the candidates you provide; markup cannot compensate for missing, mislabeled, or poorly sized source files.

7. Debug selection and common mistakes

Symptom Likely cause Fix
The image looks soft on a high-density display. The candidate set lacks a sufficiently large source, or the displayed slot is larger than expected. Check the intrinsic widths and rendered slot. Add an appropriately sized candidate and ensure sizes matches the layout.
The browser downloads an unexpectedly large image. A width-based sizes expression overstates the slot, or the available candidates are much larger than needed. Measure the actual CSS slot at the relevant conditions. Update sizes and review candidate widths.
The narrow-screen crop never appears. The media condition does not match the viewport, a preceding source is suitable first, or the source URL fails. Check the condition at the actual breakpoint, source order, and network response. Keep the intended default in the <img>.
A modern format source is skipped or fails to display. The browser does not support the declared type, the file is mislabeled, the URL is unavailable, or delivery headers are wrong. Verify the encoded file and response MIME type, then test the later source and <img> fallback.
The markup does not validate or selection is unpredictable. Width and density descriptors were mixed in a list, or the <picture> lacks its required <img>. Use one descriptor kind per srcset and retain the final <img> child.
The page shifts as images load. Intrinsic dimensions or a stable aspect ratio are missing. Set accurate width and height on the image and ensure CSS preserves the intended ratio.
The wrong information is available to assistive technology. Alt text describes file variants or mechanics, or a meaningful image has empty/missing alt text. Write alternative text for the image’s purpose. Use empty alt text only when the image is decorative.

When diagnosing a choice, inspect the actual viewport, computed CSS width, candidate URLs, and network requests. The browser may make a different candidate choice as its conditions change, so check the page at the relevant layout sizes and display densities rather than assuming one fixed choice.

8. Performance, reliability, and cost

Responsive selection can reduce unnecessary image transfer when the browser can choose a candidate suited to the rendered slot and device. The result depends on your source assets, layout, network, and browser choice; there is no universal file-size or speed gain. Accurate sizes, appropriate candidate widths, and a useful fallback make the selection more predictable.

For reliability, keep the fallback URL valid, verify every candidate after deployment, and serve correct content types. Reserve layout space with dimensions to avoid image-driven layout movement. If you change a source file or its format, check that the URL, encoding, and server response still agree.

There is no special browser or image service required to author <picture>. Your cost depends on how you create and serve the image assets and on your hosting arrangement; the markup itself does not prescribe a provider or price.

9. Capture responsive image states for review

To review your implementation, capture the page at viewport widths around the media conditions and compare the resulting crop and layout. A screenshot shows the rendered state; it does not replace checking candidate requests, file dimensions, or accessibility text.

For an automated check, capture the same page at the viewport sizes you use for review and compare the output. If you are documenting multiple art direction states, use consistent dimensions so the crops are easy to inspect.

Or skip the browser setup

If you need screenshots of your responsive image states without setting up browser automation, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a screenshot as PNG, JPEG, or WebP, or a PDF. See the ScreenshotNeo API docs for the supported options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Set the page viewport to the dimensions you want to inspect using the documented options. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for free.

FAQ

Does picture replace img?

No. A <picture> needs an <img> child, which provides the fallback and carries alt text and dimensions.

Should every responsive image use picture?

No. For the same composition at different resolutions, use srcset on <img>. Use <picture> when selecting a different composition or offering format alternatives.

Does sizes set the image’s CSS width?

No. CSS controls the rendered layout. With width descriptors, sizes tells the browser the expected slot width to use when selecting a candidate.

Can I put more than one source inside picture?

Yes. The browser considers source candidates in order; keep conditions and format alternatives ordered so the intended suitable source is considered first, with <img> as the fallback.

References