sr-only does not hide a <table>'s <caption> in Firefox
Maintainers usually reply within 1 day
@Pythe1337N is already working on this.
Since Sep 24, 2026.
Assessment
- Difficulty
- 2/5
- Estimated time
- Half a day
- Newbie friendliness
- 72/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- css
- Domain
- accessibility, frontend
Research direction
Start at the sr-only utility and compare its structure with the child-selector patterns used by space-x-* and divide-*. Reproduce the Play URL in Firefox, then verify that a table's caption is hidden while its accessible name remains intact and that Chrome and Safari behavior is unchanged.
Written by the indexing model from the issue text.
Description
What version of Tailwind CSS are you using?
v4.3.3
What build tool (or framework if it abstracts the build tool) are you using?
Vite 8.2.2 with @tailwindcss/vite 4.3.3. The Play link below reproduces it too, so the
build tool is not involved.
What version of Node.js are you using?
v24.15.0
What browser are you using?
Firefox 156.0.1 (aarch64) is affected. Chrome 153.0.8010.53 (Official Build) (arm64) and Safari
27.0 (22625.1.29.11.27) are not.
What operating system are you using?
macOS 27.0
Reproduction URL
https://play.tailwindcss.com/DM34RFq0Bv
Open it in Firefox and the caption text is visible. In Chrome and Safari, nothing is
visible.
Describe your issue
sr-only on a <table> hides the table's rows but not its <caption> in Firefox. The
caption text is painted on the page, on top of whatever is underneath it. I expected the
caption to be hidden as well, since it is part of the table.
This comes up whenever a data table is put behind sr-only as the accessible version of a
chart, which is a common pattern.
Cause. Firefox renders this differently from Chrome and Safari. A table generates two
boxes: an outer table-wrapper box, which holds the <caption>, and an inner table grid
box, which holds the rows. The css-tables-3 draft
(section 3.6.1) says
clip-path is used on the outer box, and Chrome and Safari do that. Firefox uses it on the
inner box, which matches the older CSS 2.1 rule, so the caption is not clipped.
The other declarations in sr-only do not help on a table: a table cannot be narrower
than its content, so width: 1px and height: 1px have no effect, and then nothing
overflows, so overflow: hidden clips nothing. That leaves clip-path as the only
declaration that hides anything.
Firefox has the same difference for opacity, reported as
bug 1998269. It was filed on
2025-11-04 and is still open, and a Mozilla engineer notes there that it reproduces in
builds from 2016. So I do not expect a Firefox fix soon.
Possible fix in Tailwind. Clip the caption directly, so it no longer matters which box
Firefox picks. space-x-* and divide-* already use & > ... child selectors in the same
way:
.sr-only > caption {
clip-path: inset(50%);
}
The caption stays in place, so the table's accessible name does not change. I am happy to
open a PR if you want this.
Workaround for anyone who finds this issue: put sr-only on a wrapping <div> and
leave the table unstyled. A <div> has only one box, so the problem does not happen.
<div class="sr-only">
<table>
<caption>This text is correctly hidden</caption>
<tr><td>row</td></tr>
</table>
</div>
- Dominant language
- TypeScript
- Stars
- 97.9k
- Forks
- 8.3k
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 24
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from tailwindlabs/tailwindcss
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
tailwindlabs/tailwindcss#20491 · 1 reaction ·
Maintainers usually reply within 1 day
-
Scanner `globs` walks gitignored directories (files pass respects .gitignore, globs pass does not)May be free again @akasakariko claimed this 17 days ago, and no pull request is open. Open
Difficulty 3/5 1-2 days Newbie friendliness 58/100
tailwindlabs/tailwindcss#20533 · 3 comments ·
Maintainers usually reply within 1 day
-
Source detection ignores `core.excludesFile`, so globally-ignored directories are scanned (reproduction for #19801)Possibly taken @Lukecele claimed this 22 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 65/100
tailwindlabs/tailwindcss#20509 ·
Maintainers usually reply within 1 day
-
@tailwindcss/vite: cached Root.compiler pins the build's plugin context, keeping the finished bundle alive (multi-GB RSS in Astro SSG)Possibly taken @lazerg claimed this 28 days ago. Open
Difficulty 4/5 3-5 days Newbie friendliness 68/100
tailwindlabs/tailwindcss#20501 · 4 comments ·
Maintainers usually reply within 1 day
-
Oxide 4.3.3: Windows access violation after scanning in a Node worker and unloading the addonPossibly taken @bompus claimed this 40 days ago. Open
Difficulty 4/5 3-5 days Newbie friendliness 25/100
tailwindlabs/tailwindcss#20470 ·
Maintainers usually reply within 1 day
All issues in tailwindlabs/tailwindcss
Similar issues
-
"Contains" page watch never matches when its text has a trailing spacePossibly taken @RaphaelFakhri claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
CopilotKit/openmuse#184 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
bootstrap-vue-next/bootstrap-vue-next#3357 ·
Maintainers usually reply within 1 day
-
[quality] tide.ts: six mutation survivors in the merge-queue gate, draft refusal, fork-403 workflow-file diagnosis and getPull's fork flag are unpinned by any testPossibly taken @hivecommons-hive claimed this today. Openagent/quality needs-kind stage/040-covered-by-pr testing
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
cncf/prow-github-actions#517 · 1 comment ·
Maintainers usually reply within 2 days
-
Unsampled pageload span is profiled when profileLifecycle is 'trace' (browser UI profiling)Possibly taken @Jxxunnn claimed this today. OpenBrowser Waiting for: Product Owner
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
getsentry/sentry-javascript#25497 · 1 comment ·
Maintainers usually reply within 1 day