Skip to content

[a11y] Follow-ups from the Wave 1 component assessments #49477

Open

Description

@michelengelen

Context

This issue collects the follow-ups that the Wave 1 assessments find. Each item is out of scope for the assessment PR that found it. Tracking issue: #49260.

When an item becomes large, move it to its own issue and link it here.

Follow-ups

From IconButton (#49405)

  • Button report, 2.2.2 Pause, Stop, Hide. The not-applicable reason says the spinner is user-triggered and the button is disabled. Neither is the WCAG test, and the application can set loading without user input. The IconButton report now rates the same spinner ⚠️ Partially Supports, like LinearProgress. Align Button with it.
  • Button report, 4.1.2 manual steps. The steps tell the tester to press Tab to disabled and loading buttons. These are not in the tab order. Use the screen-reader cursor instead (arrow keys in NVDA, VO+Right Arrow in VoiceOver).
  • Button report, 1.4.11 known gap. The gap still says that icon contrast is untested. Measure the focus ripple, as in the IconButton report: about 1.45:1 against white for the default color.
  • Focus loss when loading is set. When loading disables a focused Button or IconButton, Chromium moves focus to <body> (jsdom keeps it, so unit tests miss it). The IconButton report rates 2.4.3 ⚠️ for this. Possible fix: useButtonBase already supports focusableWhenDisabled; pass it while loading. Then re-rate 2.4.3 in both reports. In progress in [material-ui][Button][IconButton] Keep focus when loading is set while focused #49540.
  • Hover contrast of warning icons. The 4% hover tint drops a warning IconButton icon to about 2.98:1, below the 3:1 minimum for 1.4.11.
  • Loading spinner contrast. The IconButton spinner uses action.disabled, about 1.88:1 against white. Decide if the exemption for inactive components applies.
  • Docs demo IconButtonColors. Two buttons have the same icon and the same label ("fingerprint"), and only their color differs. This conflicts with 1.4.1, 2.4.6, and 3.2.4.
  • Docs demo LoadingIconButton. The Tooltip title "Click to see loading" becomes the accessible name. It is an instruction, not an action (2.4.6).

From the IconButton deep review and Fab (#49406)

  • Button report, focus and press contrast. The ripple paints contrastText at 30% over a contained label. On keyboard focus and on press, every palette color is then less than 4.5:1. The Fab report documents this under 1.4.3; Button does not.
  • Fab component, fixed height. The extended Fab sets height, so a label that wraps spills out (1.4.4, 1.4.10, 1.4.12). Replace height with minHeight and vertical padding in the component, then re-rate the Fab report. ([fab] Let an extended Fab grow to fit a wrapping label #49529)
  • Text-only resize rule. The Avatar report treats text-only resize as out of scope for 1.4.4. The layout suite and the Fab report test 1.4.4 with text-only resize. Choose one rule for the library and re-rate the outlier.
  • Scorecard: demo lists in two places. Shared slugs now need the demo list in demoMeta.ts and in axeDemos. Consider putting the component on each A11Y_RULES entry and deriving axeDemos from it.

From ButtonGroup (#49407)

  • SplitButton demo, Escape. The menu does not close on Escape. The [a11y][ButtonGroup] Assess WCAG 2.2 conformance #49407 PR fixes its aria-expanded, but not this.
  • ButtonGroup docs demos, group names. Every demo names its group " button group", which describes the component, not the purpose (2.4.6).
  • Inherited ratings follow the defaults, not the parent. A group that keys a criterion starts from the library default, not from the parent rating. If Button re-rates 1.4.11, ButtonGroup does not follow. Consider resolving keyed criteria from the parent rating.

From Link (#49413)

  • Link in dark mode. Without an underline, no palette color except error reaches 3:1 against body text in dark mode, so underline="hover" cannot pass 1.4.1. Consider a non-color cue that stays in dark mode.
  • Button report, 2.4.11 steps. Step 2 says to scroll and "press Tab to it again", which moves focus to the next element. Use Shift+Tab, then Tab, as the IconButton and Link reports now do.

From Chip (#49414)

  • Disabled delete-only chip. Chip.js passes disabled only when the chip is clickable, and its keyup handler does not check disabled. A disabled chip with only onDelete stays focusable, has no aria-disabled, and Backspace still calls onDelete.
  • Delete icon. It is hidden from assistive technology, 16 or 22 px, and 1.86:1 by default. Give it a 24 px target, 3:1 contrast, and expose the delete action, for example with a description.
  • Label wrapping. The label never wraps, so a label that fits at 100% is truncated at 200% text, at 320 px, and with WCAG text spacing. Consider wrapping by default, or a prop.
  • ChipsArray demo. After a keyboard deletion, focus moves to the page body. Move focus to the next chip.
  • Scorecard: shared axe files. [test] Count only a component's own demos when axe results are shared #49526 checks unclaimed demos only when every sharing report sets axeDemos. It does not catch a sharer without axeDemos (which then reads the other component's demos), or a demo claimed by two reports. The earlier IconButton branch had both checks; propose them as a small follow-up.

From FormLabel, FormHelperText, and FormGroup (#49410, #49411, #49412)

  • Required state of groups. Only InputBase-based fields take required from FormControl. Checkbox, Radio, and Switch do not, and RadioGroup has no required prop. A required group legend shows an aria-hidden asterisk, so assistive technology gets no required state. Decide on a component fix, or document required on each control and aria-required on RadioGroup.
  • TextField report, focused label. It lists only warning for the focused label. InputLabel uses the FormLabel styles, so a focused info label (3.86:1) fails too.
  • Dark mode elevation overlay. The Paper overlay lightens the surface, so the error color (#f44336) drops to about 3.7:1 in a Menu and 3.1:1 in a Dialog. This affects error text in any component inside an elevated Paper.
  • Checkbox and Switch error state. In a FormControl with error, the checkboxes get no aria-invalid, and FormControl does not connect a FormHelperText to the group.
  • Docs demos. The two FormControlLabelPosition demos put aria-label on a FormGroup with no role. In the CheckboxesGroup demo, the helper text says "You can display an error" in both states, so only the color changes.
  • Docs pages. checkboxes.md and switches.md should say that a group needs a fieldset and a legend, or role="group" with a name.
  • Stale comment. a11yReporter.ts says that the docs toolbar reads *.a11y.json through require.context. Nothing in the docs build reads these files now.

Done when

  • Each item is fixed, moved to its own issue, or closed with a reason.

Search keywords:

Activity

  1. rohits2501 commented on Oct 19, 2026

    @rohits2501
    Contributor

    From the CircularProgress WCAG 2.2 assessment (#49408, PR #49504) — three gaps to track (no fix in that PR, assessment only):

    • 1.4.11 Non-text Contrast — a light-mode color="warning" arc against the enableTrackSlot track is ~2.72:1 (< 3:1). Against the page, every default color clears 3:1.
    • 2.2.2 Pause, Stop, Hide — the indeterminate animation has no built-in pause/stop/hide control (same class as LinearProgress).
    • 4.1.3 Status Messages — progressbar value changes are not announced; there is no live region by default.
  2. tad-bit-better commented on Oct 23, 2026

    @tad-bit-better

    Hi, I'd like to pick up item 4 (focus moving to <body> when loading is set on Button/IconButton).

    Plan: reproduce it in Chromium, then try keeping the button focusable while loading (along the lines of focusableWhenDisabled) so focus stays put, with a test covering it. If you'd rather this go into its own issue first, I can open one.

    I'll keep the PR scoped to this one item.

  3. tad-bit-better commented on Oct 23, 2026

    @tad-bit-better

    Opened #49540 for item 4. Loading Button/IconButton now go through focusableWhenDisabled, so focus stays put when loading is set. One heads-up: this keeps a loading button in the tab order, so I updated the Button report's 2.4.3 section to match.

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

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions