Skip to content

fix(a11y): mark decorative star rating symbols aria-hidden (WCAG 1.4.3) - #13028

Merged
lokesh merged 2 commits into
masterfrom
a11y/star-ratings-aria-hidden
Jul 3, 2026
Merged

fix(a11y): mark decorative star rating symbols aria-hidden (WCAG 1.4.3)#13028
lokesh merged 2 commits into
masterfrom
a11y/star-ratings-aria-hidden

Conversation

@mekarpeles

Copy link
Copy Markdown
Member

Summary

Star symbols (★) in StarRatingsComponent.html were not marked as decorative, causing two problems:

  1. Accessibility semantics: Screen readers would announce "star star star" before the numeric rating, creating redundant/confusing output. The rating value is always in the adjacent <span itemprop="ratingValue"> (e.g. "4.2 (120 ratings)").

  2. pa11y WCAG 1.4.3 violations: Gold text (hsl(50, 100%, 50%)) on white = ~1.4:1 contrast. pa11y reported 79 errors on search results pages and ~14 on other pages. WCAG 1.4.3 exempts purely decorative text, and HTMLCS honors aria-hidden="true" for contrast checks.

Fix: add aria-hidden="true" to both the full star spans and the half-star span. The gold color is preserved — it's intentional for sighted users and doesn't need to change once the element is correctly marked decorative.

- $:('<span class="star {}">★</span>'.format(small) * int(ratings_average))
+ $:('<span class="star {}" aria-hidden="true">★</span>'.format(small) * int(ratings_average))

- <span class="star star--half $small">★</span>
+ <span class="star star--half $small" aria-hidden="true">★</span>

Why not darken the gold color?

The star gold is a visual design choice (--gold token). Darkening it enough to reach 4.5:1 on white would require near-amber (#7a5c00 range), which significantly changes the look. Since the stars are correctly decorative, aria-hidden is the WCAG-compliant solution without a design regression.

Test plan

  • Run npm run test:a11y — the jest-axe tests for OlPopover, OlOptionsPopover, and OlToast should remain passing (unrelated components)
  • Pa11y audit before/after: expect ~93 contrast errors to drop by ~79 once deployed

Playwright regression test will be added in #12998 once the fix is verified deployed.

Related

…4.3)

Star symbols (★) in StarRatingsComponent are purely decorative — the rating
value is always conveyed by the adjacent text span (e.g. "4.2 (120 ratings)").
Marking them aria-hidden="true":

1. Correctly removes them from the accessibility tree (AT users hear the
   numeric rating, not a sequence of "star star star" characters)
2. Fixes pa11y WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail violations —
   HTMLCS skips aria-hidden elements for contrast checks (79 errors on search
   results pages, 14 on other pages)

The gold color (--gold: hsl(50, 100%, 50%)) is intentionally preserved for
sighted users. Changing it would require a design review.

Applies to both full-size stars (book page) and small stars (search results,
author pages). Applies to full stars and half-star.
@mekarpeles mekarpeles added the Theme: Accessibility Work related to disability accessibility. [managed] label Jun 24, 2026
Resolve StarRatingsComponent.html conflict: master rewrote the macro to the
aggregateRating/schema.org structure. Re-applied this PR's sole change
(aria-hidden="true" on the decorative star spans) onto master's version.

@lokesh lokesh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Another narrow a11y fix, LGTM.

@lokesh
lokesh merged commit fc70516 into master Jul 3, 2026
8 checks passed
@lokesh
lokesh deleted the a11y/star-ratings-aria-hidden branch August 11, 2026 21:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Theme: Accessibility Work related to disability accessibility. [managed]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants