Between the home page and the cart lies the stretch where a purchase is actually decided: the search field, the suggestion list, facet filters, sorting and the results list. If a shopper cannot find a product here, it never reaches the cart, and even the best accessible checkout has nothing left to process. The starting position is uncomfortable: home pages in the shopping category average 71.0 errors (WebAIM Million 2026), which is 26.6 percent (WebAIM Million 2026) above the overall average across all pages analysed. At the same time, 56 percent (Baymard Institute) of the shops studied fail to adequately support their users' search needs. This article works through the stretch before the cart step by step and closes with a test routine a shop team can run without a specialist lab.
Key takeaways
- Shopping home pages average 71.0 errors (WebAIM Million 2026) per page, 26.6 percent (WebAIM Million 2026) above the overall mean; a suggestion list that keyboard users cannot reach costs the order, not just comfort.
- Search fields with suggestions follow the combobox pattern: a visible label, role=combobox, aria-expanded and aria-activedescendant, plus arrow keys, Enter, Escape and Tab behaving as expected (W3C WAI-ARIA Authoring Practices Guide).
- Every change to the result set needs one announcement from a status region that exists in the markup before it receives text; a single result count about 500 milliseconds after the last keystroke works well (WCAG 4.1.3).
- Facets are forms: multiple choice as checkboxes, mutually exclusive values as radios, both inside a named group and with the result count in the label. Clickable divs carry neither state nor keyboard operation.
- Filter chips name facet and value, meet the target size of 24 by 24 CSS pixels (WCAG 2.5.8) and pass focus to the next chip when removed, instead of letting it drop back to the top of the page.
- Search term, facets and page number belong in the URL so the back button restores the state; after every shop update a keyboard run, a screen reader sample, a zoom test at 320 CSS pixels and a zero-result query recheck the path.
Why the stretch before the cart matters
Accessibility in online shops is usually discussed at the checkout, because that is where revenue becomes visible. The funnel, however, starts much earlier. Users who submit a search query or click a facet have concrete purchase intent, which is exactly why every barrier between the search field and the product detail page counts twice. A suggestion list that cannot be reached by keyboard does not cost convenience, it costs the order.
Usability research backs this up with clear numbers. For product lists, the Baymard Institute found that 36 percent (Baymard Institute) of the shops reviewed have design flaws that actively hinder finding and selecting products, and that an average of 35 changes (Baymard Institute) per shop would be needed to bring the product list to a good level. In user tests with mediocre product lists, 67 to 90 percent (Baymard Institute) of participants abandoned the task, compared with 17 to 33 percent (Baymard Institute) on optimised lists for the identical search task.
The technical side is no friendlier. 95.9 percent (WebAIM Million 2026) of all home pages analysed had automatically detectable WCAG failures, averaging 56.1 errors (WebAIM Million 2026) per page. Automated checks only cover part of the criteria. Keyboard operation, focus handling and announcements fall almost entirely outside their reach and have to be verified manually, which for the search and filter stretch means one thing: a green automated run says almost nothing about it.
- Search field and suggestion list – input, autocomplete, announcement of the result count
- Facet groups – brand, price, size, colour, availability, rating
- Sorting – relevance, price, rating, newest, as a real selection control
- Results list – product cards, loading states, loading more, pagination
- Return paths – filter state in the URL, back navigation, zero-results page
The combobox pattern for the search field
There is no design vacuum for search fields with suggestions, there is a fully specified pattern: the combobox from the WAI-ARIA Authoring Practices Guide (W3C WAI-ARIA Authoring Practices Guide). The input carries role="combobox", points to the suggestion list via aria-controls and reports whether that list is currently visible through aria-expanded. aria-autocomplete="list" states that suggestions are displayed but not written into the field. The list itself is a listbox, and every suggestion is an option with its own identifier.
Before anything else, the field needs a visible label. Placeholder text is no substitute: it disappears on the first keystroke, often has insufficient contrast and is handled inconsistently by voice control. The scale of the problem is documented: 33.1 percent (WebAIM Million 2026) of all form inputs found were not properly labelled, and the number of form inputs per home page has risen to an average of 6.9 (WebAIM Million 2026), an increase of 36 percent (WebAIM Million 2026) within three years. If the label cannot be shown for design reasons, hide it visually rather than omitting it.
The second building block is keyboard operation. The Authoring Practices Guide defines which key triggers which behaviour, and deviating from it is worse for experienced users than a plain search without suggestions, because it breaks learned expectations (W3C WAI-ARIA Authoring Practices Guide).
- Arrow Down opens the suggestion list and moves the selection into the list.
- Arrow Up and Arrow Down move through the suggestions while keyboard focus stays in the input.
- Enter accepts the highlighted suggestion and closes the list.
- Escape closes the list and leaves the typed text in place, a second Escape clears the field.
- Tab leaves the field and closes the list without forcing a suggestion.
- Mouse and touch operation remain available in parallel, with no hover state as a prerequisite.
The technique behind this is aria-activedescendant. Keyboard focus stays in the input while the attribute points to the currently highlighted option. Screen readers then announce the option without the focus actually moving (W3C WAI-ARIA Authoring Practices Guide). Moving real focus into the list instead means the return path to the input has to be solved cleanly, and typing risks being interrupted. How roles, states and live regions interact is covered in our article on ARIA roles, states and live regions.
A visible label
The field carries visible label text that stays in place once the field is filled. A magnifier icon alone is not enough, because it provides no accessible name.
Predictable key handling
Arrow keys, Enter, Escape and Tab behave as described in the Authoring Practices Guide. Deviations cost users more than missing suggestions ever would.
States on the field
aria-expanded mirrors the state of the list, aria-activedescendant the highlighted option. Both are updated on every change, not only when the list opens.
Announce the result count instead of swapping it silently
The most common defect in suggestion lists and results lists is the silent DOM update. The list fills, the result count changes, and anyone not looking at the screen learns nothing about it. Success criterion 4.1.3 Status Messages requires at Level AA that status messages can be programmatically determined so assistive technology can present them without moving focus (WCAG 2.2).
In practice this means a region with role="status" that already exists in the markup before it receives any text. Only then can assistive technology observe it. The text is replaced on every change of the result set rather than appended, and it stays short. Wording such as “128 results for waterproof jacket” carries more than “search complete”, because it supports the decision whether scanning the list is worthwhile or whether the query should be narrowed.
Do not announce on every keystroke
The same mechanism carries every further step along the stretch: after applying a facet, after removing a chip, after changing the sort order and after paging. Each of these actions changes the result set and therefore needs feedback. How to keep status and error messages cleanly separated is described in detail in our article on accessible error and status messages.
Facet filters: real checkboxes instead of clickable divs
Facets are forms, even when the design does not look like one. A group such as “brand” with several selectable values is a multiple selection, a group such as “price” with mutually exclusive ranges is a single selection. That semantic belongs in the markup: a fieldset with a legend, or a container with role="group" and aria-labelledby, containing real checkboxes or radios with associated labels.
The difference is not cosmetic. A div styled as a filter with a click handler has no state, no accessible name and no keyboard operation. Screen reader users hear text without meaning, voice control finds no target, and the keyboard never reaches it in the first place. The result count per option belongs inside the label rather than in an adjacent element, so that it is read out: “Brand A, 128 products” instead of “Brand A” and a number somewhere beside it.
| Element | Common implementation | Implementation that holds up |
|---|---|---|
| Facet group | div with a visually bold heading | fieldset with legend or role="group" with aria-labelledby |
| Multiple selection | clickable div with a CSS tick | input type="checkbox" with an associated label |
| Single selection | button row with an active class | input type="radio" inside a named group |
| Collapsible facet | div with an arrow icon | button with aria-expanded and aria-controls |
| Result count per option | visual only, beside the label | part of the label so that it is announced |
| Reloading the list | silent replacement of results | status message with the new result count |
The second trap is auto-submit. Many shops reload the results list on every change. For users moving through a group by keyboard and shifting the selection with arrow keys, this triggers a reload on every intermediate step. Two approaches hold up: either the list reloads after each deliberate selection and reports that through a status message, or there is an explicit “apply filters” button that commits the selection. What does not hold up is a reload triggered by focus alone.
button carries aria-expanded with the actual state and aria-controls pointing at the content area. When a group with active filters is collapsed, the number of active selections stays visible in the header so that nobody has to expand it blindly to learn the state. The template-level implementation is covered by our accessible web development service.Active filters as chips and the focus question
Almost every shop displays active filters as chips above the results list, usually with a small cross for removal. The pattern is sound, its implementation rarely is. A chip is a button, and its accessible name has to be complete: “remove filter Brand A” rather than a cross without text. Empty buttons are not a fringe case; they were found on 30.6 percent (WebAIM Million 2026) of the home pages analysed.
- The chip area carries a heading or label such as “active filters” so that it can be located with a screen reader.
- Each chip names the facet and the value, not only the value: “colour: blue, remove” is clearer than “blue, remove”.
- A “clear all filters” button sits at the end of the group and is named just as explicitly.
- Chips and their removal targets meet the target size of 24 by 24 CSS pixels.
- The chips reflect the actual state, even when filters were changed in the sidebar.
- After removal, a status message reports the new result count.
The delicate part is focus. When a chip is removed, the element the focus was sitting on disappears. Without intervention, focus lands at the top of the page and keyboard users start their journey again. A fixed rule helps: focus moves to the next chip; if none remains, to the clear-all button; and if that has gone too, to the heading of the chip area or of the results list. The same principle applies to dynamically built interfaces in general, as described in our article on focus management in single page apps.
A removed filter is a removed focus. If you do not define where it goes, the browser decides, and it reliably sends it back to the top of the page.
The results list: loading states, focus and pagination
Between clicking a facet and seeing the new list there are a few hundred milliseconds at best, and often more in everyday conditions. That intermediate state needs a representation that is not purely visual. A skeleton grid without a text alternative tells screen reader users nothing. The results container therefore carries aria-busy="true" while loading, and the status region already in place reports the loading process and afterwards the outcome.
Paging brings the focus question back. If page two loads without focus being moved, focus still sits on the page number while the entire content above it has been replaced. The workable approach is to move focus deliberately to the heading of the results list, which receives tabindex="-1" for that purpose. Screen readers then announce the heading and the start of the new list, and the keyboard order resumes in the right place.
Make loading audible
aria-busy on the list container plus a short status message replace the purely visual skeleton grid. Once loading finishes, exactly one message reports the new result count.
Set focus when paging
After a page change, focus moves to the results list heading carrying tabindex="-1". That replaces the jump to the top of the page and the loss of position.
Load more via a button
A “load more products” button is more predictable than automatic loading on scroll, which pushes the footer out of reach and loses the position on return.
Automatic loading on scroll deserves a warning of its own. It pushes the footer with contact details, shipping information and legal texts ever further down, changes the document length underneath the cursor and makes returning after a visit to a product page unreliable. A visible load-more button solves all three problems at once and can additionally be paired with a status message stating how many products were added.
Product cards: unambiguous link text, price and availability
Success criterion 2.4.4 Link Purpose requires at Level A that the purpose of each link can be determined from the link text alone or from the link text together with its programmatically determined context (WCAG 2.2). In results lists this regularly fails on cards carrying three links to the same product: the image without alternative text, the heading with the product name and a link labelled “more” below. Screen reader users who call up a list of links then see a series of identical entries with nothing to tell them apart.
The numbers show how widespread this is: empty links were found on 46.3 percent (WebAIM Million 2026) of the home pages analysed. The implementation that holds up is unspectacular. The card carries exactly one link whose text is the product name. The image receives an empty alternative text where it is purely decorative next to that name, and the price sits beside it as text rather than as a graphic.
- One link per product card, with the full product name as its text.
- Prices as text in the document so they can be zoomed, announced and copied.
- Availability expressed in words rather than a traffic-light dot: “in stock” or “ships in three days” instead of a green circle.
- Reduced prices with textual context: “was 149.00 euros, now 129.00 euros” instead of a struck-through value without explanation.
- Rating stars with a text alternative such as “4.3 out of 5 stars from 128 reviews”.
- Labels such as “new” or “only a few left” as text, not as a background graphic.
Target sizes, gestures and zoom under WCAG 2.2
WCAG 2.2 is published as a W3C Recommendation, with the current version dated 12 December 2024, and it added nine success criteria compared with WCAG 2.1 (WCAG 2.2). Several of them hit the search and filter stretch directly, because they concern exactly the controls that sit densely packed there: small chips, star filters, sliders and sticky filter bars.
| Success criterion | Requirement | Typical place in search and filters |
|---|---|---|
| 2.5.8 Target Size (Minimum), AA | at least 24 by 24 CSS pixels, except where a smaller target is essential | filter chips, removal crosses, star filters, page numbers |
| 2.5.7 Dragging Movements, AA | any function operable by dragging is also operable without dragging | price sliders, range selection, map radius |
| 2.4.11 Focus Not Obscured (Minimum), AA | the focused element is not entirely hidden by author-created content | sticky filter bar, action bar above the results list |
| 4.1.3 Status Messages, AA | status messages can be programmatically determined | result count, loading note, zero-results message |
| 1.4.1 Use of Color, A | colour is not the only visual means of conveying information | availability, discount marking, active facet |
| 3.3.7 Redundant Entry, A | information already entered is not requested again | search term preserved after a filter change |
The price slider deserves particular attention, because it appears in almost every shop and is usually operable by dragging only. Two number fields for minimum and maximum price next to the slider resolve criterion 2.5.7 completely and at the same time help everyone who wants to enter a precise value. Beyond that, the slider itself needs arrow-key operation and a label that states the current value, not merely the position.
Zoom quickly separates solid shops from fragile ones. Success criterion 1.4.10 Reflow requires presentation without scrolling in two dimensions at a width of 320 CSS pixels, and 1.4.4 Resize Text requires text enlargement to 200 percent without loss of function (WCAG 2.2). Facet sidebars with fixed pixel widths, chips with fixed heights and result grids with fixed column counts break precisely here. What WCAG 2.2 introduced overall is broken down in our article on the new success criteria in WCAG 2.2.
Filter state in the URL and the zero-results page
Anyone who has assembled a filter combination, opened a product and then navigated back expects the same list. If the shop resolves that state only in page memory, it is lost on the way back and every hard-won facet has to be clicked again. For users who make each selection by keyboard or voice control, that is not a detail, it is the point at which the session ends. Success criterion 3.3.7 Redundant Entry targets exactly this pattern (WCAG 2.2).
- Search term, facets, sort order and page number are held as parameters in the URL.
- Back navigation fully restores the previous state.
- The link can be copied and shared without losing filters.
- After returning, focus is placed on the product card last opened or on the list heading.
- The page title names the active search term so history entries and tabs stay distinguishable.
The zero-results page is the second underestimated point. It appears more often than shop operators assume, because real queries rarely follow catalogue vocabulary. The Baymard Institute reports that 54 percent (Baymard Institute) of shops struggle with abbreviation and symbol searches, and 66 percent (Baymard Institute) with non-product searches such as shipping or returns. Across channels, the research rates search quality as mediocre or worse on 46 percent (Baymard Institute) of desktop, 58 percent (Baymard Institute) of mobile and 64 percent (Baymard Institute) of app implementations.
What a usable zero-results page does
A test routine for shop teams
The search and filter stretch does not need a testing lab. Three passes uncover most of the problems, and a team without specialist training can complete them within a short hour. What matters is running them on a real category with many results rather than a tidy test category holding twelve products.
- Keyboard pass: from the search field through the suggestion list, the facets, the chips and the pagination to the product detail page, using the keyboard only. Every focus must be visible, no trap may hold it, and after each action it must be clear where it sits.
- Screen reader spot check: enter a query, move through the suggestions with the arrow keys, apply a facet and remove the chip again. The check covers whether result counts and loading states are announced and whether facet groups are exposed with their names.
- Zoom test: browser zoom at 400 percent or a window width of 320 CSS pixels. The facet sidebar must stay reachable, chips must not be cut off, and the results list must not force horizontal scrolling.
- Measure target sizes: check chips, removal crosses, star filters and page numbers in developer tools against 24 by 24 CSS pixels.
- URL and back test: set a filter combination, open a product, navigate back, then open the link in a new tab. The state has to survive all three cases.
- Zero-results test: submit an invented query, an abbreviation and a non-product query such as “returns”, then check what the page offers.
The second part is repetition. Search and filter stretches are rarely pure templates in shop systems; they are a mix of theme, search module and configuration. Any update can change the roles on the search field, the structure of the facets or the target sizes of the chips without that appearing in a changelog. The routine therefore belongs attached to every major update, with its outcome documented. For that recurring part we offer ongoing accessibility monitoring, and for the initial assessment the structured WCAG 2.2 audit with a test report.
Where the stretch has been heavily customised, an assessment with real assistive technology beats automated tooling alone; our screen reader testing service covers exactly that part. Editorial and shop teams that maintain category texts, facet labels and product names themselves benefit additionally from short accessibility training, because many problems in the results list originate in day-to-day content work rather than in the template.
Sources and studies
aria-expanded.Related Articles
Accessible Maps: Store Locators Without Dead Ends
Map widgets fail audits with striking regularity. How a location search still works without a mouse, without colour perception and with a screen reader: list.
Accessible E-Learning: Platforms, Courses and Quizzes
Paid online courses fall under the BFSG, universities under BITV 2.0. How to make the learning journey from booking to certificate genuinely accessible.
Accessible Sliders: Carousels Without Barriers
Auto-rotating carousels violate WCAG 2.2.2 and lock out keyboard and screen reader users. How to make sliders accessible with pause, keyboard and ARIA.