Skip to content

Conversation

@anakaren-rojas
Copy link
Contributor

@anakaren-rojas anakaren-rojas commented Nov 12, 2025

Summary:

Different screen readers handle <fieldset> and <legend> elements inconsistently, causing unpredictable announcement behavior:

  • NVDA + Chrome: Announces the legend when entering the fieldset, providing context for the choices
  • VoiceOver + Safari: Often fails to announce the legend when users navigate directly to form controls, especially with certain navigation methods (arrow keys) or on mobile

This inconsistency means some users hear the critical instructions ("Choose 1 answer", "Choose 3 answers", etc.) while others miss them entirely, depending on their assistive technology and navigation method.

Solution
Add redundant role="list" and role="listitem" attributes to preserve list semantics, as some screen readers may remove the implicit list role when list-style: none is applied via CSS

Issue: LEMS-3666

Test plan:

  • ZND with aria-hidden removed
  • the initial pass through reads Choose 1 answer once, and then when reading the question again, reads instructions three times, consecutively

  • ZND with both aria-hidden and aria-labelledby removed
  • the initial pass through reads Choose 1 answer once, and then when reading the question again, reads instructions twice, consecutively

  • ZND with div instead of legend
  • initial pass through does not read Choose 1 answer, when reading the question again, instructions are read once

  • ZND with roles added
  • initial pass through does not read Choose 1 answer, when reading the question again, instructions are read once

  • ZND with old implementation
  • the initial pass through reads Choose 1 answer once, and then when reading the question again, reads instructions twice, consecutively

@github-actions
Copy link
Contributor

github-actions bot commented Nov 12, 2025

🗄️ Schema Change: No Changes ✅

@github-actions
Copy link
Contributor

github-actions bot commented Nov 12, 2025

🛠️ Item Splitting: No Changes ✅

@github-actions
Copy link
Contributor

github-actions bot commented Nov 12, 2025

Size Change: +12 B (0%)

Total Size: 498 kB

Filename Size Change
packages/perseus/dist/es/index.js 202 kB +12 B (+0.01%)
ℹ️ View Unchanged
Filename Size
packages/kas/dist/es/index.js 20.8 kB
packages/keypad-context/dist/es/index.js 1 kB
packages/kmath/dist/es/index.js 5.98 kB
packages/math-input/dist/es/index.js 99.2 kB
packages/math-input/dist/es/strings.js 1.61 kB
packages/perseus-core/dist/es/index.item-splitting.js 13.1 kB
packages/perseus-core/dist/es/index.js 22.5 kB
packages/perseus-editor/dist/es/index.js 97.9 kB
packages/perseus-linter/dist/es/index.js 8.64 kB
packages/perseus-score/dist/es/index.js 9.2 kB
packages/perseus-utils/dist/es/index.js 403 B
packages/perseus/dist/es/strings.js 7.73 kB
packages/pure-markdown/dist/es/index.js 1.39 kB
packages/simple-markdown/dist/es/index.js 6.71 kB

compressed-size-action

@anakaren-rojas anakaren-rojas force-pushed the add-missing-group-label branch from 492b657 to ad3c416 Compare November 12, 2025 23:04
@github-actions
Copy link
Contributor

github-actions bot commented Nov 12, 2025

npm Snapshot: Published

Good news!! We've packaged up the latest commit from this PR (4858faf) and published it to npm. You
can install it using the tag PR3029.

Example:

pnpm add @khanacademy/perseus@PR3029

If you are working in Khan Academy's frontend, you can run the below command.

./dev/tools/bump_perseus_version.ts -t PR3029

If you are working in Khan Academy's webapp, you can run the below command.

./dev/tools/bump_perseus_version.js -t PR3029

@anakaren-rojas anakaren-rojas changed the title fix(LEMS-3666): add list and listitem role to radio fix(LEMS-3666): Remove aria hidden from radio legend Nov 13, 2025
Copy link
Contributor

@SonicScrewdriver SonicScrewdriver left a comment

Choose a reason for hiding this comment

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

Sounds great to me, and it looks like it already passed QA! Thank you :)

@anakaren-rojas anakaren-rojas marked this pull request as draft November 19, 2025 19:13
@github-actions github-actions bot added item-splitting-change schema-change Attached to PRs when we detect Perseus Schema changes in it and removed item-splitting-change schema-change Attached to PRs when we detect Perseus Schema changes in it labels Nov 19, 2025
@anakaren-rojas anakaren-rojas changed the title fix(LEMS-3666): Remove aria hidden from radio legend fix(LEMS-3666): Adds roles to ul and li Nov 20, 2025
@anakaren-rojas anakaren-rojas marked this pull request as ready for review November 24, 2025 17:19
Copy link
Contributor

@mark-fitzgerald mark-fitzgerald left a comment

Choose a reason for hiding this comment

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

The writeup that you did for this PR is super helpful! I think it should also be added to these two files in order to explain why the redundant role information is added in the first place. That way, our future selves won't remove them (thinking we are cleaning things up).

Copy link
Contributor

@ivyolamit ivyolamit left a comment

Choose a reason for hiding this comment

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

Changes looks logical to me 👍🏼

Copy link
Contributor

@SonicScrewdriver SonicScrewdriver left a comment

Choose a reason for hiding this comment

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

Works great, thank you!

// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-noninteractive-element-interactions
<li className={classes} onClick={clickHandler}>
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/no-redundant-roles
<li className={classes} onClick={clickHandler} role="listitem">
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if some of these rules are helpful if we need to keep overriding them in our efforts to have a good a11y experience. 🤔

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants