komal.nakrani
Browse Themes
ThemesCategoriesDocsBlogTips & Tricks
Performance••By Komal Nakrani

Astro Responsive Images with widths and sizes

Make Astro responsive images with the layout prop or explicit widths and sizes on Image and Picture, so phones download small files and retina screens stay sharp.

#Astro#Images#Performance#astro:assets

For responsive images in Astro, set a layout on <Image /> or <Picture /> from astro:assets. With layout="constrained" or layout="full-width", Astro generates a srcset with several widths and a matching sizes attribute, so each device downloads an appropriately sized file. When you need exact control, such as for a three-column grid, pass widths and sizes yourself.

Key Takeaways

  • layout="constrained": scales down with its container, never above width.
  • layout="full-width": always fills the container width.
  • Set image.layout in config to apply a default everywhere.
  • For grids and sidebars, pass explicit widths and a sizes that matches your CSS.

The layout prop

---
import { Image } from 'astro:assets';
import photo from '../assets/studio.jpg';
---
<Image src={photo} alt="Studio interior" width={1200} height={800} layout="constrained" />

Astro outputs an <img> with a srcset covering a range of widths up to 2× the requested size (capped at the original), plus sizes="(min-width: 1200px) 1200px, 100vw". A phone downloads a small version; a retina laptop downloads a large one.

Layout srcset Typical use
constrained Several widths up to 2× width Content images, cards
full-width Widths up to the original Heroes, banners
fixed 1× and 2× of width Avatars, logos, icons
none None Opt out

Set a project default

// astro.config.mjs
export default defineConfig({
  image: {
    layout: 'constrained',
    responsiveStyles: true,
  },
});

responsiveStyles adds a few CSS rules (width: 100%, height: auto, object-fit) so images scale correctly without your own CSS. If your global styles already handle images, leave it off to avoid conflicts.

Explicit widths and sizes for grids

The default sizes assumes the image can be as wide as the viewport, which isn’t true in a grid. A card image in a three-column layout is a third of the container at most. Tell the browser:

<Image
  src={photo}
  alt="Project thumbnail"
  widths={[320, 480, 640, 960]}
  sizes="(min-width: 1024px) 33vw, (min-width: 640px) 50vw, 100vw"
/>

sizes should mirror your CSS breakpoints. Here: three columns from 1024px, two from 640px, one below. With an accurate sizes, a desktop browser picks the 480 or 640 file instead of downloading a full-width image for a small card.

widths can’t be combined with densities, and densities can’t be combined with layout. Pick widths (with or without a layout) for fluid images, densities for fixed-size ones.

Picture for modern formats

<Picture /> takes the same props and adds formats:

---
import { Picture } from 'astro:assets';
---
<Picture
  src={photo}
  alt="Studio interior"
  formats={['avif', 'webp']}
  layout="full-width"
/>

The browser takes the first format it supports. AVIF files are usually smaller than WebP at similar quality, but take longer to encode, so builds slow down with many images.

Above the fold

Responsive sizes don’t change loading priority. For the hero or LCP image, add priority:

<Image src={hero} alt="..." layout="full-width" priority />

That sets eager loading and high fetch priority. Use it on one image per page, and leave the rest lazy; offscreen images below the fold behave like islands with client:visible, loading only when needed.

Images in Markdown

Markdown images using relative paths (![alt](./photo.jpg)) are optimised automatically. To get a layout on them, set image.layout in config; it applies to Markdown images too. For full control inside content, use MDX and the <Image /> component directly.

Check what the browser picked

In DevTools, select the image and look at currentSrc in the Properties panel, or hover the src in the Elements panel. Resize the window and reload to see the selection change. If a 300px-wide card is loading a 1600px file, your sizes is too generous.

For the rest of the image pipeline (remote images, formats and the Picture component), see the Astro performance guide. Image processing is the most common reason builds get slower; faster Astro builds in CI shows how to cache it. The Astro images guide documents every prop.

FAQ

Does the Astro Image component create a srcset?

Yes, when you set a layout (other than none), pass widths, or pass densities. Without any of them, it outputs a single resized image.

Why are images in my public folder not optimised?

Astro only processes images you import from src/ (or remote images on allowed domains). Files in public/ are copied as-is.