Overview
Search is one of the most common ways users find content on a site, yet search inputs are frequently inaccessible. A search field without a label forces screen reader users to guess its purpose. Without a search landmark, users cannot jump directly to the search form. And when live results appear dynamically, screen reader users are never told that results have loaded unless a live region announces the change.
WCAG Criteria:
- 2.4.1 Bypass Blocks — search landmarks allow users to jump directly to search
- 1.3.1 Info and Relationships — labels must be programmatically associated with inputs
- 4.1.3 Status Messages — status updates (like result counts) must be announced without moving focus
Key requirements:
- Every search input must have a visible or visually-hidden
<label> - Wrap the search form in a
<search>element (or<form role="search">) to create a search landmark - Use
type="search"on the input for native clear button and semantics - Announce live result counts with
role="status"so screen readers report changes without moving focus - Debounce live result announcements to avoid overwhelming screen reader users with rapid-fire updates
Search Field
Unlabeled Search vs. Accessible Search with Live Region
Inaccessible
<!-- No label, no landmark, no live region -->
<div>
<div class="search-box">
<svg><!-- magnifying glass icon --></svg>
<input type="text" placeholder="Search..." />
</div>
<div class="results">
<p>5 results found</p>
<ul>
<li>Getting started guide</li>
<li>API reference</li>
</ul>
</div>
</div>Live Preview
5 results found
- Getting started guide
- API reference
- Search best practices
Accessible
<search>
<form role="search">
<svg aria-hidden="true"><!-- icon --></svg>
<label for="search-good-input" class="sr-only">
Search
</label>
<input
id="search-good-input"
type="search"
placeholder="Search..."
/>
</form>
<div class="results">
<p role="status">5 results found</p>
<ul>
<li>Getting started guide</li>
<li>API reference</li>
</ul>
</div>
</search>
<style>
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
border: 0;
}
</style>Live Preview
5 results found
- Getting started guide
- API reference
- Search best practices
What’s wrong with the unlabeled search?
- The input has no
<label>— a screen reader announces only “edit text” with no indication this is a search field - The magnifying glass SVG is decorative but not hidden with
aria-hidden="true", potentially creating confusing announcements - The container is a plain
<div>, not a search landmark — users cannot jump to it via landmark navigation - When results load dynamically, the “5 results found” text is never announced to screen reader users
type="text"instead oftype="search"loses the native clear button and search semantics
What the screen reader announces:
| Version | Announcement |
|---|---|
| Inaccessible (no label) | “edit text” — no context that this is search |
| Accessible (labeled + landmark) | “search landmark, Search, search text” — full context |
| Results update (no live region) | Nothing — user must manually navigate to see results |
Results update (with role="status") | “5 results found” — announced automatically |