Home / Theme components

How do you make a Shopify search drawer accessible?

Published October 1, 2026

Treat the search drawer as what it is: a modal dialog. When it opens, move keyboard focus into it. While it is open, trap focus inside it. When it closes, return focus to the element that opened it. Label the search field properly, announce results to screen readers, and make the Escape key close it. Get those six behaviors right and the drawer works for everyone.

Call it a modal, because it is one

Shopify themes love the search drawer: a panel that slides in from the side or drops down from the header when the shopper taps the search icon. Designers think of it as a drawer. Assistive technology needs it to be a dialog. If the markup does not say role="dialog" with an accessible name, a screen reader user has no idea a new context opened. They are still, as far as they know, on the page behind it.

The fix starts in the markup. Give the drawer container role="dialog" and aria-modal="true", with aria-labelledby pointing at its visible heading or aria-label="Search" if there is no visible heading. This is not decoration; it is the announcement that tells a screen reader user where they are. Test it with an actual screen reader, because the announcement is the feature.

Focus in, focus trapped, focus returned

The three focus behaviors are the core of the whole task. On open, move focus to the search input inside the drawer. Do not leave focus on the trigger button while the drawer opens elsewhere; keyboard users will keep tabbing through the page behind the drawer, confused about where they are. On close, return focus to the trigger that opened it, so the user lands back where they started instead of at the top of the page.

While open, trap focus inside the drawer. Tab from the last element should cycle to the first, not escape to the page behind. This is the behavior users expect from any modal, and its absence is one of the most common accessibility failures in Shopify themes. The trap must also handle Shift+Tab going backward. Test both directions.

Label the search field like you mean it

Search drawers often rely on placeholder text as the only label: a gray "Search" inside the input that vanishes when you type. Placeholders are not labels. Screen readers may not announce them, and they disappear exactly when the user needs the reminder. Give the input a real label, visible or programmatically associated with a label element or aria-label. If the design insists on the placeholder look, keep the placeholder and add the label anyway; they can coexist.

While you are there, set the input's type and inputmode sensibly and give the submit button an accessible name. "Search" as the button text is fine. An icon-only button with no name is not. Every icon-only control in the drawer, close button included, needs a name.

Announce the results, do not just display them

Most search drawers show live results as the shopper types. Sighted users see them appear. Screen reader users hear nothing unless you tell them. Wrap the results region in an aria-live region, polite, so additions are announced without interrupting typing. Announce the count, "8 results," rather than reading every result; the user can navigate into the list if they want detail.

Handle the empty state too. "No results for 'xyz'" should be announced just like results are. Silence after typing reads as broken, and users will keep typing, deleting, and retyping, trying to fix a search that is actually working. A live region costs a few attributes and removes a whole class of confusion.

The Escape key is non-negotiable

Escape must close the drawer, from anywhere inside it, and return focus to the trigger. This is the single most expected keyboard behavior for anything dialog-like, and its absence strands keyboard users: they opened the drawer, they cannot see a close control in their tab order, and nothing they press gets them out. Wire the keydown handler, test it, and keep it working after every theme update.

The visible close button matters too. It must be reachable by keyboard in a sensible order, usually first or last in the drawer, and it must have an accessible name like "Close search." A decorative X with no name is a dead end for assistive tech. Name every control, test every path.

Test with a keyboard, not a mouse

The whole drawer can be verified in two minutes with no tools. Tab to the search trigger, press Enter, confirm focus is in the search field. Type a query, confirm results appear. Tab through the drawer, confirm focus never leaves it. Press Escape, confirm it closes and focus returns to the trigger. Do it again with a screen reader running and listen for the dialog announcement and the results count.

Run this test after every theme update and every app install that touches the header. Search drawers break silently: the drawer still opens for mouse users while the focus behavior regresses underneath. The two-minute keyboard test is the cheapest regression check a Shopify store can run, and it catches exactly the failures that generate demand letters.