Skip to content

[badge] Add aria-hidden to badge content and polish docs demos#48471

Open
mj12albert wants to merge 6 commits into
mui:masterfrom
mj12albert:fix-badge-a11y
Open

[badge] Add aria-hidden to badge content and polish docs demos#48471
mj12albert wants to merge 6 commits into
mui:masterfrom
mj12albert:fix-badge-a11y

Conversation

@mj12albert
Copy link
Copy Markdown
Member

@mj12albert mj12albert commented May 4, 2026

Preview: https://deploy-preview-48471--material-ui.netlify.app/material-ui/react-badge/

Add aria-hidden since the raw text content (e.g. 99+) doesn't indicate any (UI) context and creates noise for SRs, removing it should be an improvement.

Added explicit guidance to the docs about providing a descriptive aria-label e.g. over "99 unread messages" and updated demos accordingly.

@mj12albert mj12albert added this to the Material UI v9.x milestone May 4, 2026
@mj12albert mj12albert added accessibility a11y scope: badge Changes related to the badge. priority: important This change can make a difference. labels May 4, 2026
@code-infra-dashboard
Copy link
Copy Markdown

code-infra-dashboard Bot commented May 4, 2026

Deploy preview

Bundle size

Bundle Parsed size Gzip size
@mui/material 🔺+35B(+0.01%) ▼-1B(0.00%)
@mui/lab 0B(0.00%) 0B(0.00%)
@mui/private-theming 0B(0.00%) 0B(0.00%)
@mui/system 0B(0.00%) 0B(0.00%)
@mui/utils 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@mj12albert mj12albert force-pushed the fix-badge-a11y branch 2 times, most recently from b7f5157 to 5044297 Compare May 4, 2026 18:19
@mj12albert mj12albert marked this pull request as ready for review May 4, 2026 18:37
Comment on lines +8 to +13
<Badge
color="secondary"
badgeContent={0}
role="img"
aria-label="no unread messages"
>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If this is not related to aria-hidden, please update the PR title to include fixing docs.

Copy link
Copy Markdown
Member

@siriwatknp siriwatknp left a comment

Choose a reason for hiding this comment

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

LGTM. Leave this to @silviuaavram if he wants to split the PR or not.

Minor suggestion to add bullets as summary on the changes in the PR. I was surprise that a lot of demos are changed at first after reading the PR title.

@mj12albert mj12albert changed the title [badge] Add aria-hidden to badge content [badge] Add aria-hidden to badge content and polish docs demos May 5, 2026
@mj12albert
Copy link
Copy Markdown
Member Author

I was surprise that a lot of demos are changed at first after reading the PR title.

The demo changes are related since the aria-hidden change is about ensuring the badged element/component has a meaningful text label, so the demos needed to be updated to follow the updated guidance

Comment thread docs/data/material/components/badges/BadgeAlignment.js
- **Use badges for supplemental status**: Badges work best for short counts or compact
states attached to another element, such as unread messages on an inbox button. Don't use
a badge as the only place where important status appears.
- **Label the element that owns the badge**: Badge content is hidden from assistive
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

in the examples we are also labelling the badges themselves. maybe we should also mention this.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think it would better to make the demos more realistic, in real UIs I think almost all the time badged elements are interactive/clickable (the presence of the badge invites you to touch/click it)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

hmm might be, might be not. for example, a badge might be used to show if user is online. that element is not necessarily interactive. in this case, should we only add aria-label to the interactive examples in the docs?

image

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The Slack sidebar online indicator example is similar to the new demo with ListItemButton – the badge and avatar aren't interactive, but they're all part of a ListItemButton-like component that should have aria-label describing the name + status indicated by the badge

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

export default function BadgeOverlap() {
return (
<Stack spacing={3} direction="row">
<Stack spacing={3} direction="row" aria-hidden>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why did we go with aria-hidden instead of aria-label attributes on the badges?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think the badge itself is just a visual affordance, usually in UIs the badged element is the labelable element like IconButton/ListItemButton in the demos

<IconButton aria-label="show 4 unread messages">
  <Badge badgeContent={4}>
    <MailIcon />
  </Badge>
</IconButton>

If the badge itself also needed aria-label, it could cause odd announcements or duplicate content with the badged element's own label

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

so, we should decide if we want to add aria-label to the interactive elements only.

in any case, since we are adding aria-hidden to badge content, in the component itself, why add aria-hidden to the stack as well?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This one is a bit odd because it's an "abstract" demo just to show positioning and not meant to be realistic, it was to avoid reading anything from it but not needed anyway

@ZeeshanTamboli
Copy link
Copy Markdown
Member

Has this been tested with screen reader? That is all the demos?

@mj12albert
Copy link
Copy Markdown
Member Author

Has this been tested with screen reader? That is all the demos?

Yeah all the demos generally involve aria-label that includes the badge meaning set on a button component

@mj12albert mj12albert requested a review from silviuaavram May 11, 2026 23:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

accessibility a11y priority: important This change can make a difference. scope: badge Changes related to the badge.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants