Search topics
Custom dropdowns that a keyboard can't open or read
A dropdown rebuilt from divs and list items to match the design takes clicks only, or moves a highlight drawn by a class, so keyboard users can't choose and screen readers never hear a role, a value or the options.
<div class="select" tabindex="0"> The problem
Keyboard users can't open the dropdown or pick an option, and screen reader users hear no role, no current value and no options, so they can't tell what they are choosing.
A shop's product page has a Size dropdown above the Add to basket button. It shows "Choose a size" in a rounded box with a chevron, and a click opens a list: Small, Medium, Large, Extra large. Someone using a keyboard meets one of two builds. In the first, Tab jumps straight from the product name to Add to basket: the dropdown never takes focus, so no size can be chosen, and the basket refuses the item. In the second, the dropdown does take focus, Enter opens it, and the arrow keys move a highlight through the sizes. A screen reader, though, says only "Choose a size", with no role and no hint that it opens, reads nothing as the highlight moves, and after Enter still says nothing about which size was chosen.
Success Criterion 2.1.1 asks that everything a mouse can do can be done with a keyboard. In the first build, the trigger is a div with a click handler: it can't take focus and no key reaches it or its options. Success Criterion 4.1.2 asks that a control's name, role and value, and any state the user can change, are available to assistive technology. In the second build, the keyboard works, but the element has no role, its name is whatever text it shows, the open list is not exposed as open, and the highlight is a CSS class. The browser has nothing to pass on, so a screen reader user can operate the control only by guessing.
Dropdowns are often the step that must be done before anything else, such as a size, a delivery country or a time slot, so a dropdown that can't be used stops the whole task. On a phone, a native select opens the system picker with large rows; a rebuilt one gives up that picker too.
4 of 10 groups affected
- No vision (affected)
- Low vision (affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (not affected)
- Limited manipulation Keyboard and switch users can't open the list, or move through it without knowing what Enter will pick, so a required choice such as a size blocks the whole form.
- Without vision Screen reader users hear the trigger's text with no role and no value, and nothing as the highlight moves, so they can't tell it is a choice, what is chosen, or what else there is.
- Limited vision A highlight drawn only as a pale fill can vanish in forced colors, and a closed dropdown drawn only by its background may stop looking like a control.
- Limited language, cognitive and learning abilities A control that looks like a dropdown but ignores the keys a dropdown takes is confusing, and the person may not notice that no size was set.
A scan sees a div with some text and a ul of li elements. With no role or ARIA, nothing in the markup breaks a rule a scanner knows, and the list is hidden until a click. A scan that checks only for tabindex passes the second build. AI assistants asked for "a styled dropdown" often write exactly these two builds, or add role="listbox" to the list but leave the trigger without a role, value or aria-activedescendant, which still leaves the highlight silent. Only tabbing, opening, arrowing and listening shows whether it works.
Try it
Try to choose a size with the keyboard: Tab to Size, Enter to open, the down arrow, then Enter.
Can you choose a size without the mouse? In Broken 1 you can’t even reach it: Tab skips Size, which is the failure. Try clicking it instead, then switch to Broken 2. The panel shows what a screen reader says as you move and pick.
Broken Can you fix this?
Everyday cotton T-shirt
- Small
- Medium
- Large
- Extra large
Screen reader says:
(Tab to Size)
The fix
Make the dropdown a native select, or a combobox whose role, value and highlighted option reach assistive technology and whose keys work like a select's.
- 1Tab reaches the closed dropdown, and its name, role and value are read.
- 2The keys a select takes open it, move through the options and pick one.
- 3The highlighted option is exposed in code, not only drawn.
A dropdown only a click can open
<span id="size-label">Size</span><div class="select"> <div class="select-trigger">Choose a size</div> <ul class="select-options" hidden> <li>Small</li> <li>Medium</li> <li>Large</li> <li>Extra large</li> </ul></div>A native select with a styled box
<label for="size">Size</label><span class="select-box"> <select id="size" name="size"> <option value="">Choose a size</option> <option value="s">Small</option> <option value="m">Medium</option> <option value="l">Large</option> <option value="xl">Extra large</option> </select></span>Why this fix: Use native HTML first
The trigger and the options are a div and list items with click handlers. None of them can take focus, so Tab skips the dropdown and no key opens it.
The browser makes the select a Tab stop, opens it with the keys each platform expects, moves through the options with the arrows and by typing a letter, and tells a screen reader its name, its role, its value and each option. On a phone it opens the system picker. Only the closed box is restyled: the border, the chevron and the focus ring are yours to draw, and all three survive forced colors.
Both pass 2.1.1 and 4.1.2. Use the native select: it does the same job with no script, and the browser gives every device its own keys, its own picker and its own announcements, which no rebuild matches. Build the ARIA combobox only when an option has to show something a select can't, such as a colour swatch or a stock note beside the size, and accept that its keys, states and touch behaviour are yours to test and maintain.
Styling only the closed box covers most designs: the open list is drawn by the system, which suits phones and screen magnifiers. Newer Chromium browsers also let the open list be styled with appearance: base-select, so a native select can show richer options while other browsers fall back to the ordinary select. Treat that as an enhancement, and test the fallback.
Keep a visible label beside the dropdown. A placeholder option such as "Choose a size" is the value until something is picked, not the name; with a select, give it value="" and make the field required if a size must be chosen.
Hiding a native select and drawing a rebuilt one over it, as some older jQuery plugins do, gives you both problems: the real select is out of reach, and the drawn one is one of the Befores. Check component libraries by tabbing, opening, arrowing and listening, as in the steps below, before trusting their documentation. Choosing an option must not submit the form or load another page by itself; see dropdowns and fields that change the page on their own. When people type to filter a long list instead, see autocomplete fields with silent, mouse-only suggestions.
Fixing this with an AI coding assistant? Get this guide as Markdown
Verify the fix
5 checks, no mouse.
Test with: Keyboard, Screen reader, Zoom, Forced colors
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the shared dropdown component changes.
Limits
This is a starting pattern for a single-choice dropdown. It doesn't cover choosing several options, grouped options, or a list loaded from a server as the person scrolls. Test the complete journey, with your real options, in the browsers and assistive technology you support.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.