diff --git a/.changeset/open-tables-sit.md b/.changeset/open-tables-sit.md new file mode 100644 index 000000000000..a5654e9e09cb --- /dev/null +++ b/.changeset/open-tables-sit.md @@ -0,0 +1,22 @@ +--- +'astro': patch +--- + +Allows disabling default styles for responsive images + +This change adds a new `image.experimentalDefaultStyles` option that allows you to disable the default styles applied to responsive images. + +When using experimental responsive images, Astro applies default styles to ensure the images resize correctly. In most cases this is what you want – and they are applied with low specificity so your own styles override them. However in some cases you may want to disable these default styles entirely. This is particularly useful when using Tailwind 4, because it uses CSS cascade layers to apply styles, making it difficult to override the default styles. + +`image.experimentalDefaultStyles` is a boolean option that defaults to `true`, so you can change it in your Astro config file like this: + +```js +export default { + image: { + experimentalDefaultStyles: false, + }, + experimental: { + responsiveImages: true, + }, +}; +``` diff --git a/packages/astro/src/assets/vite-plugin-assets.ts b/packages/astro/src/assets/vite-plugin-assets.ts index e5cbfa9be019..7d6cd3828b09 100644 --- a/packages/astro/src/assets/vite-plugin-assets.ts +++ b/packages/astro/src/assets/vite-plugin-assets.ts @@ -109,7 +109,10 @@ export default function assets({ fs, settings, sync, logger }: Options): vite.Pl referencedImages: new Set(), }; - const imageComponentPrefix = settings.config.experimental.responsiveImages ? 'Responsive' : ''; + const imageComponentPrefix = + settings.config.experimental.responsiveImages && settings.config.image.experimentalDefaultStyles + ? 'Responsive' + : ''; return [ // Expose the components and different utilities from `astro:assets` { diff --git a/packages/astro/src/core/config/schemas/base.ts b/packages/astro/src/core/config/schemas/base.ts index 7618ff521a5e..006ccb5802d8 100644 --- a/packages/astro/src/core/config/schemas/base.ts +++ b/packages/astro/src/core/config/schemas/base.ts @@ -67,6 +67,7 @@ export const ASTRO_CONFIG_DEFAULTS = { image: { endpoint: { entrypoint: undefined, route: '/_image' }, service: { entrypoint: 'astro/assets/services/sharp', config: {} }, + experimentalDefaultStyles: true, }, devToolbar: { enabled: true, @@ -274,6 +275,9 @@ export const AstroConfigSchema = z.object({ experimentalObjectFit: z.string().optional(), experimentalObjectPosition: z.string().optional(), experimentalBreakpoints: z.array(z.number()).optional(), + experimentalDefaultStyles: z + .boolean() + .default(ASTRO_CONFIG_DEFAULTS.image.experimentalDefaultStyles), }) .default(ASTRO_CONFIG_DEFAULTS.image), devToolbar: z diff --git a/packages/astro/src/types/public/config.ts b/packages/astro/src/types/public/config.ts index 4e7acda3bd5f..7032d385a360 100644 --- a/packages/astro/src/types/public/config.ts +++ b/packages/astro/src/types/public/config.ts @@ -1367,6 +1367,16 @@ export interface ViteUserConfig extends OriginalViteUserConfig { * the more comprehensive list is used, because only the required sizes are generated. For local services, the list is shorter to reduce the number of images generated. */ experimentalBreakpoints?: number[]; + /** + * @docs + * @name experimentalDefaultStyles + * @type {boolean} + * @default `true` + * @description + * Whether to automatically add global styles to ensure that experimental images resize correctly. This is enabled by default, but can be disabled if you want to manage the styles yourself. + * This option is only used when the `experimental.responsiveImages` flag is enabled. + */ + experimentalDefaultStyles?: boolean; }; /** diff --git a/packages/astro/test/core-image-layout.test.js b/packages/astro/test/core-image-layout.test.js index 16b62b95f9c3..10e5eec487cb 100644 --- a/packages/astro/test/core-image-layout.test.js +++ b/packages/astro/test/core-image-layout.test.js @@ -584,7 +584,6 @@ describe('astro:image:layout', () => { await fixture.build(); }); - describe('basics', () => { let $; let html; @@ -684,5 +683,22 @@ describe('astro:image:layout', () => { assert.match(style, /\[data-astro-image\]/); }); }); + describe('disabling global styles', async () => { + it('allows disabling global styles', async () => { + const fixtureWithoutStyles = await loadFixture({ + root: './fixtures/core-image-layout/', + image: { + service: testImageService({ foo: 'bar' }), + domains: ['avatars.githubusercontent.com'], + experimentalDefaultStyles: false, + }, + }); + await fixtureWithoutStyles.build(); + const html = await fixtureWithoutStyles.readFile('/index.html'); + const $ = cheerio.load(html); + const style = $('style').text(); + assert.ok(!style.includes('[data-astro-image]')); + }); + }); }); });