Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add docs for responsive images #12429

Merged
merged 6 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
54 changes: 44 additions & 10 deletions packages/astro/src/assets/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,26 +157,60 @@ type ImageSharedProps<T> = T & {
* ```
*/
quality?: ImageQuality;

layout?: ImageLayout;

fit?: ImageFit;

position?: string;
} & (
| {
/**
* The layout type for responsive images. Overrides any default set in the Astro config.
* Requires the `experimental.responsiveImages` flag to be enabled.
* The layout type for responsive images. Requires the `experimental.responsiveImages` flag to be enabled in the Astro config.
*
* Allowed values are `responsive`, `fixed`, `full-width` or `none`. Defaults to value of `image.experimentalLayout`.
*
* - `responsive` - The image will scale to fit the container, maintaining its aspect ratio, but will not exceed the specified dimensions.
* - `fixed` - The image will maintain its original dimensions.
* - `full-width` - The image will scale to fit the container, maintaining its aspect ratio.
* - `full-width` - The image will scale to fit the container, maintaining its aspect ratio, even if that means the image will exceed its original dimensions.
*
* **Example**:
* ```astro
* <Image src={...} layout="responsive" alt="..." />
* ```
*/

layout?: ImageLayout;
fit?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down' | (string & {});

/**
* Defines how the image should be cropped if the aspect ratio is changed. Requires the `experimental.responsiveImages` flag to be enabled in the Astro config.
*
* Default is `cover`. Allowed values are `fill`, `contain`, `cover`, `none` or `scale-down`. These behave like the equivalent CSS `object-fit` values. Other values may be passed if supported by the image service.
*
* **Example**:
* ```astro
* <Image src={...} fit="contain" alt="..." />
* ```
*/

fit?: ImageFit;

/**
* Defines the position of the image when cropping. Requires the `experimental.responsiveImages` flag to be enabled in the Astro config.
*
* The value is a string that specifies the position of the image, which matches the CSS `object-position` property. Other values may be passed if supported by the image service.
*
* **Example**:
* ```astro
* <Image src={...} position="center top" alt="..." />
* ```
*/

position?: string;
/**
* If true, the image will be loaded with a higher priority. This can be useful for images that are visible above the fold. There should usually be only one image with `priority` set to `true` per page.
* All other images will be lazy-loaded according to when they are in the viewport.
* **Example**:
* ```astro
* <Image src={...} priority alt="..." />
* ```
*/
priority?: boolean;

/**
* A list of widths to generate images for. The value of this property will be used to assign the `srcset` property on the final `img` element.
*
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/assets/utils/imageAttributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function applyResponsiveAttributes<
layout,
image,
props,
additionalAttributes
additionalAttributes,
}: {
layout: Exclude<ImageLayout, 'none'>;
image: GetImageResult;
Expand Down
99 changes: 93 additions & 6 deletions packages/astro/src/types/public/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1743,27 +1743,114 @@ export interface ViteUserConfig extends OriginalViteUserConfig {
* @version 5.0.0
* @description
*
* Enables and configures automatic responsive image options for images in your project. Set to `true` (for no default option passed to your images) or an object with default responsive image configuration options.
* Enables automatic responsive images in your project.
*
* ```js
* {
* experimental: {
* responsiveImages: {
* layout: 'responsive',
* experimental: {
* responsiveImages: true,
* },
* }
* ```
*
* Then, you can add a `layout` option to any `<Image />` component when needed to override your default configuration: `responsive`, `fixed`, `full-width`, or `none`. This attribute is required to transform your images if `responsiveImages.layout` is not configured. Images with a layout value of `undefined` or `none` will not be transformed.
* When enabled, you can pass a `layout` props to any `<Image /> or `<Picture />` to enable automatic responsive images. When a layout is set, 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* When enabled, you can pass a `layout` props to any `<Image /> or `<Picture />` to enable automatic responsive images. When a layout is set, 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 enabled, you can pass a `layout` props to any `<Image /> or `<Picture />` component to create a responsive image. When a layout is set, 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.

just tiny language thing (trying to stick to singular) and also, "automatic" feels a bit out of place here when this is manually defining how your image should be responsive. I think maybe saving "automatic" for the case where the image. experimental setting is configured further emphasizes that THAT is when stuff happens more "automatically" for you?

*
* ```astro
* ---
* import { Image, Picture } from 'astro:assets';
* import myImage from '../assets/my_image.png';
* ---
* <Image src={myImage} alt="A description of my image." layout='responsive' width={800} height={600} />
* <Picture src={myImage} alt="A description of my image." layout='full-width' formats={['avif', 'webp', 'jpeg']} />
* ```
*
* ```html
* <!-- Output -->
*
* <img
* src="/_astro/my_image.hash3.webp"
* srcset="/_astro/my_image.hash1.webp 640w,
* /_astro/my_image.hash2.webp 750w,
* /_astro/my_image.hash3.webp 800w,
* /_astro/my_image.hash4.webp 828w,
* /_astro/my_image.hash5.webp 1080w,
* /_astro/my_image.hash6.webp 1280w,
* /_astro/my_image.hash7.webp 1600w"
* alt="A description of my image"
* sizes="(min-width: 800px) 800px, 100vw"
* loading="lazy"
* decoding="async"
* fetchpriority="auto"
* width="800"
* height="600"
* style="--w: 800; --h: 600; --fit: cover; --pos: center;"
* data-astro-image="responsive"
* >
* ```
*
* The following styles are applied to ensure the images resize correctly:
*
* ```css
* [data-astro-image] {
* width: 100%;
* height: auto;
* object-fit: var(--fit);
* object-position: var(--pos);
* aspect-ratio: var(--w) / var(--h)
* }
*
* [data-astro-image=responsive] {
* max-width: calc(var(--w) * 1px);
* max-height: calc(var(--h) * 1px)
* }
*
* [data-astro-image=fixed] {
* width: calc(var(--w) * 1px);
* height: calc(var(--h) * 1px)
* }
* ```
* You can enable responsive images for all `<Image />` and `<Picture />` components by setting `image.experimentalLayout` with a default value. This can be overridden by the `layout` prop on each component.
*
* **Example:**
* ```js
* {
* image: {
* // Used for all `<Image />` and `<Picture />` components unless overridden
* experimentalLayout: 'responsive',
* },
* experimental: {
* responsiveImages: true,
* },
* }
* ```
*
* ```astro
* ---
* import { Image } from 'astro:assets';
* import myImage from '../assets/my_image.png';
* ---
* <Image src={myImage} alt="A description of my image." layout='fixed' />
*
* <Image src={myImage} alt="This will use responsive layout" width={800} height={600} />
*
* <Image src={myImage} alt="This will use full-width layout" layout="full-width" />
*
* <Image src={myImage} alt="This will disable responsive images" layout="none" />
* ```
*
* ### Responsive image properties
*
* 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 value of `image.experimentalLayout`.
* - `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` 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` 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 following `<Image />` component properties should not be used with responsive images as these are automatically generated:
*
* - `densities`
* - `widths`
* - `sizes`
*/

responsiveImages?: boolean;
Expand Down
Loading