Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,15 @@ import Since from '~/components/Since.astro'
<Since v="5.0.0" />
</p>

Enables support for automatic responsive images in your project.
Enables support for automatic responsive images in your project.

The term [responsive images](https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Responsive_images) refers images that work well on different devices. This particularly applies to images that resize to fit their container, and that can be served in different sizes depending on the device's screen size and resolution.

There are a number of additional properties that can be set to control how the image is displayed, but these can be complicated to handle manually. Incorrect handling of these properties can lead to images that are slow to download or that are not displayed correctly. This is one of the most common causes of poor Core Web Vitals and Lighthouse performance scores.

When this flag is enabled, Astro can automatically generate the required `srcset` and `sizes` values for images, and apply the correct styles to ensure they resize correctly. This behavior can be configured globally or on a per-image basis.

To enable the feature, first add the `responsiveImages` flag to your `astro.config.mjs` file:

```js title="astro.config.mjs"
{
Expand All @@ -24,7 +32,9 @@ Enables support for automatic responsive images in your project.
}
```

With this flag enabled, you have access to additional [`image` configuration settings](#responsive-image-configuration-settings) for controlling the default behavior of all images processed and optimized by Astro:
Enabling this flag will not change anything by default, but responsive images can then be configured by setting the [image layout](#image-layout) either globally or per image.

To do this, you have access to additional [`image` configuration settings](#configuration-settings) for controlling the default behavior of all images processed and optimized by Astro:

- Local and remote images using [the Markdown `![]()` syntax](/en/guides/images/#images-in-markdown-files).
- The [`<Image />`](/en/guides/images/#display-optimized-images-with-the-image--component) and [`<Picture />`](/en/guides/images/#create-responsive-images-with-the-picture--component) components.
Expand All @@ -33,22 +43,39 @@ Additionally, Astro's image components can receive [responsive image props](#res

Images in your `public/` folder are never optimized, and responsive images are not supported.

## Responsive image configuration settings
:::note
Enabling responsive images will generate additional image sizes for all affected images. For prerendered pages this happens during the build so may increase the build time of your project, especially if you have a large number of images.

For pages rendered on-demand the images are generated as-needed, so this has no impact on build times but may increase the number of transformations performed. Depending on your image service this may incur additional costs.
:::

## Image layout

In order to generate the correct `srcset` and `sizes` attributes, the `<Image />` and `<Picture />` components need to know how the image should resize when its container changes size. This is done by setting the `layout` prop, or `image.experimentalLayout` default. The supported values are:

- `constrained` - The image will scale down to fit the container, maintaining its aspect ratio, but will not scale up beyond the specified `width` and `height`, or the image's original dimensions. Use this if you want the image to display at the requested size where possible, but shrink to fit smaller screens. This matches the default behavior for images when using Tailwind. If you're not sure, this is probably the layout you should choose.
- `full-width` - The image will scale to fit the width of the container, maintaining its aspect ratio. Use this for hero images or other images that should take up the full width of the page.
- `fixed` - The image will maintain the requested dimensions and not resize. It will generate a `srcset` to support high density displays, but not for different screen sizes. Use this if the image will not resize, for example icons or logos smaller than any screen width, or other images in a fixed-width container.
- `none` - The image will not be responsive. No `srcset` or `sizes` will be automatically generated, and no styles will be applied. This is useful if you have enabled a default layout, but want to disable it for a specific image.

Set [`image.experimentalLayout`](/en/reference/configuration-reference/#imageexperimentallayout) with a default value (`responsive`, `fixed`, or `full-width`) to enable responsive images throughout your project.
The chosen `layout` will be used to generate the correct `srcset` and `sizes` attributes for the image, and will define the default styles applied to that `<img>` tag.

## Configuration settings

Set [`image.experimentalLayout`](/en/reference/configuration-reference/#imageexperimentallayout) with a default value to enable responsive images throughout your project.

If this value is not configured, you can still pass a `layout` prop to any `<Image />` or `<Picture />` component to create a responsive image. However, Markdown images will not be responsive.

Optionally, you can configure [`image.experimentalObjectFit`](/en/reference/configuration-reference/#imageexperimentalobjectfit) and [`image.experimentalObjectPosition`](/en/reference/configuration-reference/#imageexperimentalobjectposition) which will apply to all processed images by default.

Each of these settings can be overridden on any individual `<Image />` or `<Picture />` component with a prop, but all Markdown images will always use the default settings.
Each of these settings can be overridden on any individual `<Image />` or `<Picture />` component with a prop, but Markdown images will always use the default settings.

```js title="astro.config.mjs"
{
image: {
// Used for all Markdown images; not configurable per-image
// Used for all `<Image />` and `<Picture />` components unless overridden with a prop
experimentalLayout: 'responsive',
experimentalLayout: 'constrained',
},
experimental: {
responsiveImages: true,
Expand All @@ -60,17 +87,17 @@ Each of these settings can be overridden on any individual `<Image />` or `<Pict

These are additional properties available to the `<Image />` and `<Picture />` components when responsive images are enabled:

- `layout`: The layout type for the image. Can be `responsive`, `fixed`, `full-width`, or `none`. Defaults to the value of [`image.experimentalLayout`](/en/reference/configuration-reference/#imageexperimentallayout).
- `layout`: The [layout type](#image-layout) for the image. Can be `constrained`, `fixed`, `full-width`, or `none`. If set to `none`, responsive behavior is disabled for this image and all other options are ignored. Defaults to `none`, or the value of [`image.experimentalLayout`](/en/reference/configuration-reference/#imageexperimentallayout) if set.
- `fit`: Defines how the image should be cropped if the aspect ratio is changed. Values match those of CSS `object-fit`. Defaults to `cover`, or the value of [`image.experimentalObjectFit`](/en/reference/configuration-reference/#imageexperimentalobjectfit) if set.
- `position`: Defines the position of the image crop if the aspect ratio is changed. Values match those of CSS `object-position`. Defaults to `center`, or the value of [`image.experimentalObjectPosition`](/en/reference/configuration-reference/#imageexperimentalobjectposition) if set.
- `priority`: If set, eagerly loads the image. Otherwise, images will be lazy-loaded. Use this for your largest above-the-fold image. Defaults to `false`.

The `widths` and `sizes` attributes are automatically generated based on the image's dimensions and the layout type, and in most cases should not be set manually. The generated `sizes` attribute for `responsive` and `full-width` images
The `widths` and `sizes` attributes are automatically generated based on the image's dimensions and the layout type, and in most cases should not be set manually. The generated `sizes` attribute for `constrained` and `full-width` images
is based on the assumption that the image is displayed at close to the full width of the screen when the viewport is smaller than the image's width. If it is significantly different (e.g. if it's in a multi-column layout on small screens) you may need to adjust the `sizes` attribute manually for best results.

The `densities` attribute is not compatible with responsive images and will be ignored if set.

For example, with `responsive` set as the default layout, you can override any individual image's `layout` property:
For example, with `constrained` set as the default layout, you can override any individual image's `layout` property:

```astro
---
Expand All @@ -84,7 +111,7 @@ import myImage from '../assets/my_image.png';

## Generated HTML output for responsive images

When a layout is set, either by default or on an individual component, images have automatically generated `srcset` and `sizes` attributes based on the image's dimensions and the layout type. Images with `responsive` and `full-width` layouts will have styles applied to ensure they resize according to their container.
When a layout is set, either by default or on an individual component, images have automatically generated `srcset` and `sizes` attributes based on the image's dimensions and the layout type. Images with `constrained` and `full-width` layouts will have styles applied to ensure they resize according to their container.

```astro title=MyComponent.astro
---
Expand Down Expand Up @@ -114,31 +141,32 @@ This `<Image />` component will generate the following HTML output:
fetchpriority="auto"
width="800"
height="600"
style="--w: 800; --h: 600; --fit: cover; --pos: center;"
data-astro-image="responsive"
style="--fit: cover; --pos: center;"
data-astro-image="constrained"
>
```

The following styles are applied to ensure the images resize correctly:
## Overriding image styles

The responsive image component applies a small number of styles to ensure they resize correctly. The applied styles depend on the layout type, and are designed to give the best behavior for the generated `srcset` and `sizes` attributes. These are the default styles:

```css title="Responsive Image Styles"
[data-astro-image] {
width: 100%;
height: auto;
object-fit: var(--fit);
object-position: var(--pos);
aspect-ratio: var(--w) / var(--h)
:where([data-astro-image]) {
object-fit: var(--fit);
object-position: var(--pos);
}

[data-astro-image=responsive] {
max-width: calc(var(--w) * 1px);
max-height: calc(var(--h) * 1px)
:where([data-astro-image='full-width']) {
width: 100%;
}

[data-astro-image=fixed] {
width: calc(var(--w) * 1px);
height: calc(var(--h) * 1px)
:where([data-astro-image='constrained']) {
max-width: 100%;
}
```

For a complete overview, and to give feedback on this experimental API, see the [Responsive Images RFC](https://github.com/withastro/roadmap/blob/responsive-images/proposals/0053-responsive-images.md).
You can override the `object-fit` and `object-position` styles by setting the `fit` and `position` props on the `<Image />` or `<Picture />` component.

The styles use the [`:where()` pseudo-class](https://developer.mozilla.org/en-US/docs/Web/CSS/:where), which has a [specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity) of 0, meaning that it is easy to override with your own styles. Any class or tag name will have a higher specificity than `:where()`, so you can easily override the styles by adding your own class or tag name to the image.

Tailwind 4 is a special case, because it uses [cascade layers](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer), meaning the Tailwind rules are always lower specificity than rules that don't use layers. Astro supports browsers that do not support cascade layers, so it cannot use them for images. This means that if you need to override the styles using Tailwind 4, you must use [the `!important` modifier](https://tailwindcss.com/docs/styling-with-utility-classes#using-the-important-modifier).

For a complete overview, and to give feedback on this experimental API, see the [Responsive Images RFC](https://github.com/withastro/roadmap/blob/responsive-images/proposals/0053-responsive-images.md).