Skip to content

Commit 16ca450

Browse files
committed
docs: document deliberate spec deviation on valueless aria-hidden
Move the explanation of valueless / empty-string aria-hidden handling from the PR body into the published rule docs. The rule deviates from WAI-ARIA 1.2 §aria-hidden (which resolves valueless aria-hidden to the default 'undefined', not 'true') in order to favor fewer false positives for this specific check. Also document the 'opposite-direction' split with template-no-aria-hidden-on-focusable / template-anchor-has-content (where spec-literal interpretation applies), and the unambiguous cases that always follow the spec.
1 parent f1a7b30 commit 16ca450

1 file changed

Lines changed: 15 additions & 0 deletions

File tree

docs/rules/template-no-empty-headings.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ This rule **allows** the following:
5050

5151
If violations are found, remediation should be planned to ensure text content is present and visible and/or screen-reader accessible. Setting `aria-hidden="false"` or removing `hidden` attributes from the element(s) containing heading text may serve as a quickfix.
5252

53+
## Notes on `aria-hidden` semantics
54+
55+
This rule treats valueless / empty-string `aria-hidden` (`<h1 aria-hidden>` or `<h1 aria-hidden="">`) as exempting the heading from the empty-content check — those forms count as "hidden" for this rule.
56+
57+
**This is a deliberate deviation from [WAI-ARIA 1.2 §`aria-hidden`](https://www.w3.org/TR/wai-aria-1.2/#aria-hidden)**, which resolves valueless / empty-string `aria-hidden` to the default value `undefined` — not `true` — and therefore does not hide the element per spec. The spec-literal reading would say "valueless `aria-hidden` doesn't hide, so the empty heading is still a violation."
58+
59+
We lean toward fewer false positives here: if the author wrote `aria-hidden` at all, they signaled an intent to hide, and flagging the empty heading on top of what is already a malformed `aria-hidden` usage layers a second-order complaint on a first-order problem. Axe-core and the W3C ACT rules consistently treat this shape as INCOMPLETE (needs manual review) rather than a definitive failure, which is consistent with leaning away from a hard flag here.
60+
61+
For rules that ask the _opposite_ question ("is this element authoritatively hidden?"), the spec-literal reading applies — see e.g. `template-no-aria-hidden-on-focusable` and `template-anchor-has-content`, which treat valueless `aria-hidden` as **not** hidden. This split is applied per-rule, picking the interpretation that produces the fewest false positives for each specific check.
62+
63+
Unambiguous forms always follow the spec:
64+
65+
- `aria-hidden="true"` / `aria-hidden={{true}}` / `aria-hidden={{"true"}}` (any case) → hidden, exempts the heading.
66+
- `aria-hidden="false"` / `aria-hidden={{false}}` / `aria-hidden={{"false"}}` → not hidden, the empty-content check still applies.
67+
5368
## References
5469

5570
- [WCAG SC 2.4.6 Headings and Labels](https://www.w3.org/TR/UNDERSTANDING-WCAG20/navigation-mechanisms-descriptive.html)

0 commit comments

Comments
 (0)