diff --git a/packages/tailwindcss/src/utilities.test.ts b/packages/tailwindcss/src/utilities.test.ts index 66b051d57961..7d8d80e347a3 100644 --- a/packages/tailwindcss/src/utilities.test.ts +++ b/packages/tailwindcss/src/utilities.test.ts @@ -19,6 +19,10 @@ test('sr-only', async () => { position: absolute; overflow: hidden; } + + .sr-only > caption { + clip-path: inset(50%); + } " `) expect(await run(['-sr-only', 'sr-only-[var(--value)]', 'sr-only/foo'])).toEqual('') @@ -37,6 +41,10 @@ test('not-sr-only', async () => { position: static; overflow: visible; } + + .not-sr-only > caption { + clip-path: none; + } " `) expect(await run(['-not-sr-only', 'not-sr-only-[var(--value)]', 'not-sr-only/foo'])).toEqual('') diff --git a/packages/tailwindcss/src/utilities.ts b/packages/tailwindcss/src/utilities.ts index 477559d7ea67..b4a254aa4cd0 100644 --- a/packages/tailwindcss/src/utilities.ts +++ b/packages/tailwindcss/src/utilities.ts @@ -599,6 +599,10 @@ export function createUtilities(theme: Theme) { ['clip-path', 'inset(50%)'], ['white-space', 'nowrap'], ['border-width', '0'], + // Firefox applies the `clip-path` of a `` to its inner grid box, so + // a `
` (which lives in the outer table wrapper box) is not clipped + // and stays visible. Clip the caption itself to cover that case. + () => styleRule('& > caption', [decl('clip-path', 'inset(50%)')]), ]) staticUtility('not-sr-only', [ ['position', 'static'], @@ -609,6 +613,8 @@ export function createUtilities(theme: Theme) { ['overflow', 'visible'], ['clip-path', 'none'], ['white-space', 'normal'], + // `sr-only` also clips the caption of a table, so undo that here + () => styleRule('& > caption', [decl('clip-path', 'none')]), ]) /** diff --git a/packages/tailwindcss/tests/ui.spec.ts b/packages/tailwindcss/tests/ui.spec.ts index e5da091d8ce4..5e2629b216b7 100644 --- a/packages/tailwindcss/tests/ui.spec.ts +++ b/packages/tailwindcss/tests/ui.spec.ts @@ -1513,6 +1513,58 @@ test.skip("::file-selector-button can receive a border with just the 'border' ut ) }) +test('sr-only also hides the caption of a table', async ({ page }) => { + let { getPropertyValue } = await render( + page, + html` + + + + + + + +
+ Caption +
Cell
+ `, + ) + + // Firefox applies the `clip-path` of the `` to its inner grid box, and + // a `
` is rendered in the outer table wrapper box, so the caption is + // not clipped by the table itself and must be clipped explicitly. Asserting + // the rule that does it is all that can run here: the bug only reproduces in + // Firefox, which is not available in this environment. + expect(await getPropertyValue('#caption', 'clip-path')).toEqual('inset(50%)') +}) + +test('not-sr-only also unclips the caption of a table', async ({ page }) => { + let { getPropertyValue } = await render( + page, + html` + + + + + + + +
+ Caption +
Cell
+ `, + ) + + // the caption must become visible again together with the table it reveals, + // so the responsive reset has to win over the base `sr-only` rule + await page.setViewportSize({ width: 640, height: 768 }) + expect(await getPropertyValue('#caption', 'clip-path')).toEqual('inset(50%)') + + await page.setViewportSize({ width: 1024, height: 768 }) + expect(await getPropertyValue('#table', 'clip-path')).toEqual('none') + expect(await getPropertyValue('#caption', 'clip-path')).toEqual('none') +}) + test('composing shadow, inset shadow, ring, and inset ring', async ({ page }) => { let { getPropertyList } = await render( page,