Go through your website without a mouse. You will probably be stuck on the third screen
Main chat
A chat for vibe coders: news, guides, live cases, marketplace, and finding executors.
Close your eyes, move your mouse, remove your hand from the trackpad. Open your product and go through the main scenario - registration, ordering, creating a project - only from the keyboard. Not as an accessibility exercise, but as an ordinary user who broke a mouse today, or rides a train with a touchpad that glides, or just used to working from a keyboard.
You'll probably get stuck. Sometimes on the second screen, often on the third. On a modal that cannot be closed by Escape. On a dropdown that doesn't open with Enter. A custom checkbox that doesn't get a focus at all. On the “cross”, which is visually there, but in the tab order it is not.
And here's what's important: this isn't a story about blind users or about WCAG compliance for a lawyer. It's a story that half of the interface is based on a single input modality, and if you remove it, the product breaks. It's not about accessibility anymore. It's about quality.
Why is this a product problem, not an “inclusive” one
When the designer hears “accessibility”, in his head clicks: screenreaders, contrast, alt-texts, a separate task in the backlog with priority “after”. This is a convenient excuse because it allows you not to think about the keyboard every day.
But keyboard navigation is not a subset of accessibility. This is the basic interface mechanics used by:
- any experienced user who types faster than the cursor
- everyone who works on a laptop without a mouse on the road
- users of screen readers and people with motor limitations
- autotests that run through the interface via tab/enter
- browser extensions and autocomplete that rely on focus
- LLM agents and password autofills that need a predictable focus order
If the keyboard script is torn - not only the screen reader user suffers. Suffers the speed of your sappor, which every day has to fill the same form.
Where it hits the metrics
In a team, this rarely pops up as an "accessibility issue." This is different
- conversion drops in forms with non-standard fields (dates, multiselects, file downloads)
- the number of tickets “can’t close the window”, “nothing pressed”
- autotests on E2E are constantly falling, and QA writes fragile selectors instead of relying on roles
- new onboarding with modals shows a strange drop-off in experienced users - and these are those who press Esc out of habit and fly off the wrong way
The connection is not always visible directly. But if you start to fix the keyboard systematically, these symptoms go away in a pack.
10 Minutes Test: Complete Your Product
Before you read further, do an exercise. It takes less time than to finish this article and gives more than any audit.
Rules
- Open the product in a normal browser. Not in developer mode, not with a screen reader turned on, just a browser.
- Get your hand off the mouse. At all. Put it on your knee.
- Go through the key scenario in its entirety: from entry to result.
- Allowed only: Tab, Shift+Tab, Enter, Space, Escape, Arrows.
What to fix
Get a simple document and write along the way:
- You hit Tab and you can't see what you're doing. This is the most common breakdown.
- I opened the modal and the focus remained on the button below it.
- Tab jumps from the hat to the footer, then into the middle.
- That doesn't press. ** Custom selection, switch, button card.
- What doesn't close. Modul, popp, dropdown without Escape.
- Where you can't get to at all. Icon menu, toult, action in the table.
After such a pass, usually 15-30 points are scored on the average product. That’s your backlog for your nearest keyboard sprint – and it’s repairing faster than it seems.
Anti-patterns that occur almost everywhere
Before you understand how to build well, it is useful to see typical breakdowns. If you learn something of your own, it is normal, everyone has them.
Invisible trick
The most common case is that someone in CSS wrote outline: none on the buttons because “the blue frame is ugly” and didn’t add a replacement. Tab works, but the user cannot see where it is. This is the equivalent of a mouse cursor that has become transparent.
Focus trap that doesn't exist
The modal has opened - and Tab continues to walk the page beneath it. The user presses Enter and accidentally presses a button they can’t even see. The reverse story is that there is a focus trap, but you can’t get out of the modal because Escape isn’t hanged.
Castomy components without roles
Div with an onClick handler is not a button. For the eye - yes, for the keyboard and screen reader - just a rectangle. If the design system has <Card clickable>, which under the hood div is a time bomb.
Tab order by DOM, not logic
Visually, the “Continue” button at the bottom of the form. In DOM, she was earlier than the fields, because it is more convenient for a layout designer. The user presses Tab and flies off to “Continue” before filling out the form.
Skip link that no one has seen
Formally, there is “Go to content” at the beginning of the page. In fact, it's hidden forever, only appears when focused, and half the team doesn't even know it's there.
If you know at least three things from this list, welcome to the club. Next, we will understand how to fix it systematically, not point-by-point.
How to build a keyboard script into the work
Fixing the keyboard in the sale is always more expensive than laying it in the layout. Not because the code is complicated, but because half of the decisions are made at the level of how the screen works, not how to paint the button. If the designer did not think about the order and state, the developer will guess. He'll guess the wrong way.
What to put in the layout and not leave for later
Figma rarely draws focus states. This is the first sign that the keyboard has been forgotten. The minimum that should be in any interactive component:
- default, hover, focus-visible, active, disabled
- state for focus within the group (e.g. selected chip in focus)
- what the focus looks like on a dark background and on a color button – the contrast should not break
Focus is not a hover. Hover shows "mouse on top", focus shows "I'm here now, press Enter - something will happen". If they look the same, the user from the keyboard is lost when the mouse cursor is also above the page.
Reading order as part of the layout
On any complex screen there are several logical zones: cap, filters, content, actions. In the layout, it is useful to directly show with arrows in what order Tab should go on them. This is not red tape – it saves you from a situation where the developer assembles a page from components in the order in which he is comfortable, and Tab jumps in zigzag.
This is particularly important for:
- modal with form and buttons "Cancel / Save"
- linear
- sidebars with nested navigation
- multi-step forms, where "Back" and "Next" are visually separated
Shortcuts: negotiate a dictionary
If hotkeys appear in the product (/ for search, ? for hints, g + i for transition), they should be uniform in all sections. The most common mistake is that each team comes up with its own, and in one section Esc closes the modular, and in another it resets the filters.
It is useful to start a page in the design system: a list of global shortcuts, a list of reserved keys (Esc, Enter, Space, Tab – they can not be overridden to your desires) and the rule of how to show a hint with a shortcut in the tooltype.
Diagnostics on the layout review
When you look at someone else’s layout (or yours every other day), there’s a short list of questions that catches most keyboard issues before they’re even developed.
Questions for design review
- Where is the default focus here when the screen opens?
- What happens if you press Tab right now? Where's the trick going?
- How will the user close this window without a mouse?
- Is there a focus-visible state for all clickable items, including icons and cards?
- If it's a modal, where will the focus return after it closes?
- If it's a list, are the arrows inside working? Is Tab coming out?
- Does the Disabled button get a focus or skip? What's better for this scenario?
The last point is worth clarifying. Completely removing the disabled element from tab order means that the user will not understand why Save is not available. Often it is better to leave the focus, but give an understandable reason nearby.
Scenarios that usually break down
Gather an internal list of “hellish floats” and run them off the keyboard on each release:
- login
- payment with card selection and CVC input
- drag and drop file download (and alternative via button)
- search with auto-addition: arrows select a hint, Enter confirms, Esc closes
- multiselective
- table
These are the places where custom components usually stand, and where the keyboard script breaks first.
Common mistakes on the designer’s side
Not all keyboard bugs are the fault of development. Some of them grow directly from the model.
Transparent focus for aesthetics
“Let’s make focus like hover, just a little bit.” As a result, the light focus button is a gray frame on a white background that is not visible. The rule is simple: focus should be visible from a distance of half a meter from the screen. If you have to look closely, it doesn’t work.
Icon without text and without role
The icon-button "three dots" in the corner of the card. On the layout is beautiful, in the sale - for the screen reader it is "button", without a name. The designer must sign in the layout which aria-label at such a button. This isn’t a developer’s job – they don’t know that this icon means “Open the Action Menu with a Task.”.
A maid with no first trick
It opened - and the focus is unclear where. A good modular catches the focus on the first meaningful element: the input field if there is a form; the header if it is a confirmation; the main button if it is a short “Delete?” question. In the layout, this decision is made, and not left for development.
A toult that is only visible on a hover
A hint on the icon appears on the mouse guidance. From the keyboard, nothing. If the toult carries important information (e.g., explains what an icon means), it should also be displayed on focus.
Short summary
Keyboard accessibility is not a “special feature for the blind.” This is a basic characteristic of the interface, like contrast or readability. It is caught in one pass without a mouse, repaired mainly at the level of the layout and design system, and pays off by increasing the speed of internal users earlier than by a formal tick on the WCAG. Let’s look at how to turn this into a constant team practice, rather than a one-off heroism of one designer.
When a team sits AI and writes code
Now half of the product teams use AI assistants in one way or another: Copilot, Cursor, something based on MCP, component generation from Figma. This greatly changes who and where drops keyboard availability. It used to be the designer who didn’t think or the developer who didn’t. Now a third was added: a model that boisterously generated <div onClick={...}> instead of a button, because there was a lot of this in the training sample.
What AI does poorly by default
Without explicit instructions, the model is almost always:
- puts interactivity on
divandspanbecause it's shorter - forgetting
aria-labelon icon buttons - creates a custom dropdown without controlling the shooters
- makes a modal without a trap focus and without returning focus to a trigger
- uses
tabindex="-1"andtabindex="3"as if it were normal
It's not malice, it's statistics. If the prompt doesn’t say “semantic tags, focus management, keyboard navigation,” the model optimizes to “look like a screenshot.”.
What should be in the team’s system prompt
If you have a common prompt for an AI agent (in Cursor, in custom tuning, in the MCP server for Figma), there are three things to sew:
- use native elements:
button,a,input,dialog, and only if necessary - cast withrole - any interactive element must be accessible by Tab and activated by Enter/Space
- when generating modals, menus and combo boxes, rely on ARIA Authoring Practices rather than inventing
These are short rules, but they change the issuance noticeably. It is simple to check: ask to generate a “dropdown with search” before and after – the difference is visible immediately.
Figma code over MCP: where availability is lost
When a design goes into generation through an MCP or plugin, semantics are lost. In the layout, a “three-point card” is a frame, rectangle, and icon. The model doesn’t know that the three dots are the “Open action menu” button. Therefore, in the layout, you need to explicitly sign the roles and aria-label directly in the layer or in the description of the component. It’s not a superfluous job – it’s the only way to make sense of the car.
How to Check Keyboard Quality
To prevent this from being a one-off feat, three levels of verification are needed: fast manual, automatic and regular.
Minute per component
Before the merge component in the design system:
- Tab on it - focus visible, order logical
- Enter and Space are doing what is expected of his role
- Esc closes if there is something to close
- arrows work if it is a list, menu or table
- focus-visible does not disappear on a dark theme and on a colored background
Automation as a lower threshold
Axe, Lighthouse, Storybook a11y addon catch rough things: no label, no name button, focus contrast below the threshold. This does not replace manual checking, but does not let outright trash into the main. It is useful to screw such checks in the CI at the level of the components.
Regular running of scenarios
Once in a sprint or once in a release, someone goes through key fly completely without a mouse. Not for a checkmark, but with a screen recording and a list of places you're stuck in. This is the same practice as cross-browser testing: boring, but the only thing that really works.
How to explain it to the team and not be a bore
"We need accessibility" is a phrase that bounces off any backlog. Another approach is working.
Talk about speed, not disability
Internal users – operators, appporters, analysts – work with the interface for eight hours a day. For them, keyboard flow is literally money: less mouse movement, higher throughput. This is an argument that any product and any operating system manager understands.
Show the video, not the report
Write down thirty seconds as you try to place an order without a mouse and get stuck on the third screen. This is stronger than any WCAG audit. After this video, it takes five minutes instead of two weeks to talk about priority.
Embed in the definition of done
Not a separate task "to fix availability through the quarter", but a line in the DoD component: "passes from the keyboard, focus-visible on all states, correct roles." Then it's not heroism, it's the norm, and you don't have to fight for priority every time.
Questions worth asking on the sync
- what is the keyboard script for this feature?
- what is Esc doing on this screen?
- where does the focus return after the modular closes?
- if it's a new custom component, what pattern of ARIA is it based on?
These four planning questions save weeks of rework.
Short summary
AI speeds up the generation of interfaces, but by default degrades their keyboard quality – so the rules need to be sewn into the prompts and design system, and not rely on the common sense of the model. Verification is done in three layers: manual minute per component, automation in CI, regular running of scripts as a whole. And the conversation with the team is conducted not through accessibility-morality, but through the speed of work and video, where the interface does not pass without a mouse.
Checklist before feature release
This list is something that should fit on one page and pass in ten minutes for a review. Not as a formality, but as a filter that catches most of the pain before it reaches the market.
Keyboard
- you can go from the first screen to the confirmation without touching the mouse
- tab goes from top to bottom, from left to right, without jumping across the page
- focus-visible visible on light and dark theme, on color buttons and over pictures
- focus traps are only in modals and woodworkers, and they are released by Esc
- after closing the module, the focus returns to the element that opened it
- skip link “to the main content” works and is not hidden
Semantics and roles
- custom components rely on a specific ARIA pattern rather than “well, it looks like a dropdown.”
- button icons have aria-label or hidden text
- states (selected, deployed, loaded) are transmitted via aria-*, not just by color
- shape errors are associated with fields via aria-describedby rather than hanging side by side in the air
AI generation
- in the system prompt the rules about semantics, focus and ARIA are sewn
- generated component ran through axe or storybook a11y before review
- reviewer passed the component with the keyboard hands, and did not believe the screenshot
Anti-patterns that occur most often
It's not exotic, it's things that get into the market in almost every project where accessibility isn't sewn into the process.
Div, which pretends to be a button
The most common is after AI generation. Visually, the button is clicked by the mouse, the keyboard is not activated, the screen reader sees the “group”. It can be rewritten on a button or added a role, tabindex and Enter/Space processor. Better the first way.
A modular with no return of focus
Open the dialogue, close — the focus flew to the beginning of the page or in the body. The keyboard user loses space and starts over. Returning focus to the trigger should be the default of the modal component, not the task of everyone who uses it.
Outline: none without replacement
A classic that still comes from "beautiful" Templates. The designer doesn’t like the system outline – he removes it and forgets to draw his own. As a result, the keyboard user does not know where they are. If you remove the outline, be sure to draw the focus-visible on top.
Toasts and autodismiss of important messages
The error message pops up for three seconds and disappears. The visual with the mouse manages, the keyboard user and screen reader user do not. Critical messages should not disappear on their own, but should be in a live region.
Custom selection for design
The team rewrites the native select because “it’s ugly,” and loses the keyboard, mobile keyboard, letter search, and screen reader integration. In nine cases out of ten, it is worth staying native and stylizing it, not doing your own.
Questions for design and code review
These questions should be asked in the same way – both on the review of the layout in Figma, and on the pool request.
The layout
- where is the focus here, and what does it look like in each state?
- what elements are buttons, what links, what switches? is it signed in layers?
- what's going on with Esc on this screen?
- where does the trick go after successfully submitting the form?
By code
- if it is not a native element, what ARIA pattern does the implementation rely on?
- what is DOM-order: Does it match the visual?
- what aria-* attributes change in the runtime, and who updates them?
- what does the screen reader say when a validation error occurs?
Using AI-generated code
- what availability rules were in the prompt?
- has the result been automatically checked before a human review?
- has anyone actually clicked Tab on this component, or are we just looking at a screenshot?
What to take with you
Keyboard accessibility is not a separate discipline, but a test that the interface is generally understandable as a system: where the buttons are, where the states are, where the outputs are. If you are stuck on the third screen without a mouse, it is a signal that the interface is based on visual supports, not on structure. Fix the structure: semantics, order, focus, returns. Then the mouse, keyboard, screen reader, and auto generation will work with the same product, not with three different ones.