From f36fddfa5040a85b26fc70433354fdf6b95bd57a Mon Sep 17 00:00:00 2001 From: fkatsuhiro Date: Mon, 6 Apr 2026 23:07:26 +0900 Subject: [PATCH 1/8] feat: test of astro image position prop bug --- .../astro/test/units/assets/getImage.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/astro/test/units/assets/getImage.test.ts b/packages/astro/test/units/assets/getImage.test.ts index d2b95b490e6f..6ebc15d86b92 100644 --- a/packages/astro/test/units/assets/getImage.test.ts +++ b/packages/astro/test/units/assets/getImage.test.ts @@ -277,6 +277,22 @@ describe('getImage', () => { assert.equal(result.attributes.fit, undefined); assert.equal(result.attributes.position, undefined); }); + + it('includes object-position in style attribute when position is provided', async () => { + const result = await renderImage({ + src: 'https://example.com/photo.jpg', + width: 300, + height: 400, + alt: 'Position test', + layout: 'constrained', + position: 'left top', + }); + + assert.match( + result.attributes.style, + /object-position:\s*left top/ + ); + }); }); describe('format', () => { From 04fe6fcfeba2d2613b2896c836573aa032ac776f Mon Sep 17 00:00:00 2001 From: fkatsuhiro Date: Mon, 6 Apr 2026 23:10:46 +0900 Subject: [PATCH 2/8] fix: logic of getItem function --- packages/astro/src/assets/internal.ts | 21 ++++++++++++++++++++- pnpm-lock.yaml | 2 ++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/assets/internal.ts b/packages/astro/src/assets/internal.ts index f8798ad50cfe..9a39f905de36 100644 --- a/packages/astro/src/assets/internal.ts +++ b/packages/astro/src/assets/internal.ts @@ -171,7 +171,26 @@ export async function getImage( if (resolvedOptions.position) { // Normalize position value for data attribute (spaces to dashes) - resolvedOptions['data-astro-image-pos'] = resolvedOptions.position.replace(/\s+/g, '-'); + //resolvedOptions['data-astro-image-pos'] = resolvedOptions.position.replace(/\s+/g, '-'); + // Apply object-position as inline style since position values are arbitrary + // and cannot be pre-enumerated in a static stylesheet like fit values can. + if (typeof resolvedOptions.style === 'object' && resolvedOptions.style !== null) { + if (!('objectPosition' in resolvedOptions.style)) { + resolvedOptions.style = { + ...resolvedOptions.style, + objectPosition: resolvedOptions.position, + }; + } + } else { + const existingStyle = + typeof resolvedOptions.style === 'string' ? resolvedOptions.style : ''; + if (!existingStyle.includes('object-position')) { + const positionStyle = `object-position: ${resolvedOptions.position}`; + resolvedOptions.style = existingStyle + ? existingStyle.replace(/;?\s*$/, '; ') + positionStyle + : positionStyle; + } + } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d50f0d8b24b4..11d8b516650f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1901,6 +1901,8 @@ importers: specifier: workspace:* version: link:../../.. + packages/astro/test/fixtures/actions-middleware-context: {} + packages/astro/test/fixtures/alias: dependencies: '@astrojs/svelte': From 8c9335a0a11638870519cf63056cb86e344d9b77 Mon Sep 17 00:00:00 2001 From: fkatsuhiro Date: Mon, 6 Apr 2026 23:19:35 +0900 Subject: [PATCH 3/8] feat: changeset file --- .changeset/three-cities-obey.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/three-cities-obey.md diff --git a/.changeset/three-cities-obey.md b/.changeset/three-cities-obey.md new file mode 100644 index 000000000000..a8c41babe0a4 --- /dev/null +++ b/.changeset/three-cities-obey.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Added position prop to Astro Image with safe style merging to preserve existing user styles. From 233e9e4a068b07289d9773f28698b7b4fa9e2076 Mon Sep 17 00:00:00 2001 From: fkatsuhiro Date: Wed, 8 Apr 2026 00:46:24 +0900 Subject: [PATCH 4/8] fix: create data-astro-image-pos attribute all time for path csp unit test --- packages/astro/src/assets/internal.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/astro/src/assets/internal.ts b/packages/astro/src/assets/internal.ts index 9a39f905de36..459182c98e8d 100644 --- a/packages/astro/src/assets/internal.ts +++ b/packages/astro/src/assets/internal.ts @@ -169,6 +169,11 @@ export async function getImage( resolvedOptions['data-astro-image-fit'] = resolvedOptions.fit; } + // Always output 'data-astro-image-pos', defaulting to 'center' if unspecified. + // This ensures compatibility with existing CSP tests and allows consistent CSS control. + const currentPosition = resolvedOptions.position || 'center'; + resolvedOptions['data-astro-image-pos'] = currentPosition.replace(/\s+/g, '-'); + if (resolvedOptions.position) { // Normalize position value for data attribute (spaces to dashes) //resolvedOptions['data-astro-image-pos'] = resolvedOptions.position.replace(/\s+/g, '-'); From 5fe47cb137cf971c518953122195f59beacb2c08 Mon Sep 17 00:00:00 2001 From: fkatsuhiro Date: Wed, 8 Apr 2026 00:47:06 +0900 Subject: [PATCH 5/8] feat: another test of getImage function --- packages/astro/src/assets/internal.ts | 3 +- .../astro/test/units/assets/getImage.test.ts | 45 +++++++++++++------ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/packages/astro/src/assets/internal.ts b/packages/astro/src/assets/internal.ts index 459182c98e8d..dd4e4f632091 100644 --- a/packages/astro/src/assets/internal.ts +++ b/packages/astro/src/assets/internal.ts @@ -172,11 +172,10 @@ export async function getImage( // Always output 'data-astro-image-pos', defaulting to 'center' if unspecified. // This ensures compatibility with existing CSP tests and allows consistent CSS control. const currentPosition = resolvedOptions.position || 'center'; - resolvedOptions['data-astro-image-pos'] = currentPosition.replace(/\s+/g, '-'); + resolvedOptions['data-astro-image-pos'] = currentPosition.replace(/\s+/g, '-'); if (resolvedOptions.position) { // Normalize position value for data attribute (spaces to dashes) - //resolvedOptions['data-astro-image-pos'] = resolvedOptions.position.replace(/\s+/g, '-'); // Apply object-position as inline style since position values are arbitrary // and cannot be pre-enumerated in a static stylesheet like fit values can. if (typeof resolvedOptions.style === 'object' && resolvedOptions.style !== null) { diff --git a/packages/astro/test/units/assets/getImage.test.ts b/packages/astro/test/units/assets/getImage.test.ts index 6ebc15d86b92..2c401ee9d909 100644 --- a/packages/astro/test/units/assets/getImage.test.ts +++ b/packages/astro/test/units/assets/getImage.test.ts @@ -279,20 +279,37 @@ describe('getImage', () => { }); it('includes object-position in style attribute when position is provided', async () => { - const result = await renderImage({ - src: 'https://example.com/photo.jpg', - width: 300, - height: 400, - alt: 'Position test', - layout: 'constrained', - position: 'left top', - }); - - assert.match( - result.attributes.style, - /object-position:\s*left top/ - ); - }); + const result = await renderImage({ + src: 'https://example.com/photo.jpg', + width: 300, + height: 400, + alt: 'Position test', + layout: 'constrained', + position: 'left top', + }); + + assert.match( + result.attributes.style, + /object-position:\s*left top/ + ); + }); + + it('merges position into existing style object without overwriting', async () => { + const result = await renderImage({ + src: 'https://example.com/photo.jpg', + width: 300, + height: 400, + alt: 'Merge test', + layout: 'constrained', + position: 'top right', + style: { color: 'red' }, + }); + + assert.deepStrictEqual(result.attributes.style, { + color: 'red', + objectPosition: 'top right' + }); + }); }); describe('format', () => { From e3f2df45ccba6adf87164de63a2e1ce8a9f58450 Mon Sep 17 00:00:00 2001 From: fkatsuhiro Date: Sat, 18 Apr 2026 11:28:33 +0900 Subject: [PATCH 6/8] fix: change set explanetion more clealy for users --- .changeset/three-cities-obey.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.changeset/three-cities-obey.md b/.changeset/three-cities-obey.md index a8c41babe0a4..a514c399125d 100644 --- a/.changeset/three-cities-obey.md +++ b/.changeset/three-cities-obey.md @@ -2,4 +2,8 @@ 'astro': patch --- -Added position prop to Astro Image with safe style merging to preserve existing user styles. +Fixed the `position` prop in `` and `` to correctly apply `object-position` styles. + +Before fixing, providing a `position` prop only added `data-astro-image-pos` attribute to the HTML, but the corresponding CSS was not generated. + +This fix ensures the `position` value is applied inline `object-position` style directly. From b6f401967cbbf5fb8b9f1d036bae374049ba2838 Mon Sep 17 00:00:00 2001 From: fkatsuhiro Date: Thu, 23 Apr 2026 23:34:13 +0900 Subject: [PATCH 7/8] Add: yaml file --- pnpm-lock.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11d8b516650f..d50f0d8b24b4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1901,8 +1901,6 @@ importers: specifier: workspace:* version: link:../../.. - packages/astro/test/fixtures/actions-middleware-context: {} - packages/astro/test/fixtures/alias: dependencies: '@astrojs/svelte': From 1e3be6d91b8efeb68502c247f7cc80ffe09a99d3 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Fri, 1 May 2026 11:16:46 -0400 Subject: [PATCH 8/8] chore: clean up changeset --- .changeset/three-cities-obey.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.changeset/three-cities-obey.md b/.changeset/three-cities-obey.md index a514c399125d..73b6c3a26049 100644 --- a/.changeset/three-cities-obey.md +++ b/.changeset/three-cities-obey.md @@ -2,8 +2,4 @@ 'astro': patch --- -Fixed the `position` prop in `` and `` to correctly apply `object-position` styles. - -Before fixing, providing a `position` prop only added `data-astro-image-pos` attribute to the HTML, but the corresponding CSS was not generated. - -This fix ensures the `position` value is applied inline `object-position` style directly. +Fixes the `position` prop on `` and `` components to correctly apply `object-position` styles