Skip to content

fix(aria-prohibited-attr): prohibit aria-label/labelledby on body and label - #5245

Draft
chutchins25 wants to merge 1 commit into
chut/5185-section-aside-labelledbyfrom
chut/3410-body-label-prohibit
Draft

fix(aria-prohibited-attr): prohibit aria-label/labelledby on body and label#5245
chutchins25 wants to merge 1 commit into
chut/5185-section-aside-labelledbyfrom
chut/3410-body-label-prohibit

Conversation

@chutchins25

Copy link
Copy Markdown
Contributor

Prohibits aria-label / aria-labelledby on the body and label elements, per ARIA in HTML "naming prohibited".

Stacked PR — targets chut/5185-section-aside-labelledby (#5185). GitHub will auto-retarget this to develop once #5185 merges.

What & why

Per ARIA in HTML:

  • body — role generic, Naming Prohibited.
  • labelNaming Prohibited when exposed as generic / associated with a labelable element. The authoritative html-aria test fixture (tests/prohibit-names.html, authored by the spec editor) marks a bare <label aria-label> / <label aria-labelledby> as fail.

Both currently pass aria-prohibited-attr because they resolve to a non-null role (body → implicit document; label → chromium Label), so the check's "no role → prohibited" branch never runs.

Fix

Adds a new elementsProhibitedAriaLabel check option (default ["body", "label"]) and an element-level short-circuit in the evaluate: elements in this list (and not overridden via elementsAllowedAriaLabel) prohibit aria-label/aria-labelledby regardless of the role they expose. These report as "no role" since the prohibition is tied to the element, not the implicit role.

The label prohibition is unconditional (matches the html-aria test fixture and the issue), rather than attempting to detect labelable-element association.

Note: the issue originally listed a third element (rp), but the author struck it — not included.

Behavior change

<body aria-label> / <label aria-label> (and aria-labelledby) now report on aria-prohibited-attr: a violation when the element has no visible text, or needs-review (incomplete) when it does. Element-level and gated on nodeName, so no other elements are affected.

Tests

  • aria-prohibited-attr check unit — label single / plural / text-incomplete / elementsAllowedAriaLabel opt-out, plus an open Shadow DOM case.
  • aria-prohibited-attr virtual-rule — body and label violations (body can't live in the shared integration page).
  • aria-prohibited-attr integration HTML/JSON — label violation + incomplete cases.
  • doc/check-options.md — documents the new elementsProhibitedAriaLabel option.

Closes #3410

… label

The body and label elements prohibit an author-provided accessible name
per ARIA in HTML, but slip through today because they resolve to a
non-null role (body->document, label->chromium Label). Add an
element-level elementsProhibitedAriaLabel option (body, label) that
prohibits aria-label/aria-labelledby regardless of the exposed role.

Closes #3410

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@straker straker left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this solves the problem I don't think it does so in the way we want. The true issue is that axe-core does not yet support the generic role. Both body and label should be implicit role of generic, which would then prohibit aria-label and aria-labelledby. So the fix to this issue should be to have generic be fully supported in axe-core.

@chutchins25

Copy link
Copy Markdown
Contributor Author

Agree the root cause is the missing generic role (#4747) — body/label should map to implicit generic, which prohibits naming. That's a larger change (add the role, remap several elements' implicit roles, "not widely supported" reporting, broad blast radius) well beyond this PR's scope.

Options:

  1. Close this PR and fold the fix into Support role=generic #4747.
  2. Land the contained option-based fix now and supersede it when Support role=generic #4747 lands.

I lean toward (1) if #4747 is near-term. What's your preference?

@straker

straker commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Option 1 is good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants