What this example teaches
- How empty icon buttons get accessible names.
- When visible text is better than aria-label.
- How toggle and submit buttons communicate state and purpose.
Empty icon button
Bad
<button><svg aria-hidden="true"><!-- icon --></svg></button> The button has no accessible name.
Better
<button aria-label="Search"><svg aria-hidden="true"><!-- icon --></svg></button> The icon-only button now has a clear accessible name.
Visible button text
Bad
<button aria-label="Send message">Submit</button> The visible text and accessible name do not match, which can confuse speech input users.
Better
<button type="submit">Send message</button> Visible text gives the button a clear name for everyone.
Toggle button state
Bad
<button>Show filters</button> Users may not know whether the filter panel is currently open.
Better
<button type="button" aria-expanded="false" aria-controls="filters">Show filters</button>
<section id="filters" hidden>...</section> The button exposes its relationship and expanded state.
Best after opening
<button type="button" aria-expanded="true" aria-controls="filters">Hide filters</button>
<section id="filters">...</section> The label and state update together.
Submit button clarity
Bad
<button type="submit">Go</button> Go is vague when the form action matters.
Better
<button type="submit">Request accessibility review</button> The button describes the form submission outcome.
What still needs human review
- Whether button labels match the actual action and current state.
- Whether keyboard focus, disabled states, menus, modals, and toggles behave correctly.
- Whether custom button-like elements should be native button elements instead.
Related tools
Related issue library pages
- Button has no accessible name
- Empty aria-label found
- Focusable content is hidden from assistive technology