Scrollable region must have keyboard access
A scrolling container holds no focusable content, so keyboard-only users can't reach it or scroll through the overflow it hides.
What you see
Scrollable region must have keyboard access Element should have focusable content Element: <div class="code-block" style="overflow:auto; max-height:300px">
What’s actually happening
A box with overflow:auto or overflow:scroll — a long code sample, a wide data table, a chat log, a terms-and-conditions panel — clips its content and shows a scrollbar. With a mouse you grab the bar or use the wheel. With a keyboard only, you can't: Tab never stops on the container, and arrow keys only scroll the element that currently has focus. So a keyboard or screen reader user hits a wall at the visible edge and the rest of the content is unreachable. axe flags it because the region scrolls but has no focusable descendant to land on.
Common causes
- A container has overflow:auto / scroll / overlay (often with a fixed height or width) but contains only static text or images — no links, buttons, or inputs
- A syntax-highlighted code block or <pre> wraps long lines in a scroll box with no interactive content inside
- A wide responsive table is dropped into a scrolling wrapper <div> for small screens without making the wrapper focusable
- A custom scrollbar library replaces native scrolling on a plain <div> and never adds keyboard handling
- Content is virtualized/lazy-rendered, so at scan time the scroll container is effectively empty of focusable nodes
How to fix it
- Add tabindex="0" to the scrolling containerPutting tabindex="0" on the element with the overflow makes it a tab stop. Once focused, the browser's built-in behavior takes over: arrow keys, Page Up/Down, Home/End, and Space all scroll it. This is the direct fix axe is asking for and needs no JavaScript.
- Give the region an accessible name and a roleA bare focusable div announces as "group" or nothing useful. Add role="region" (or role="group") plus aria-label, e.g. aria-label="Code sample" or aria-label="Pricing table", so screen reader users know what they've focused before they start arrowing through it.
- Prefer focusable content over a focusable wrapper when it existsIf the region legitimately contains links or controls, those satisfy the rule on their own and you don't need tabindex on the wrapper. The wrapper tabindex is specifically for regions whose content is non-interactive (text, code, images).
- Avoid faking it with a focusable form fieldDon't drop a hidden or dummy <input> inside just to create a focus stop. Browsers can intercept arrow/typing keys for autocomplete, the focus target is wrong, and the AT announces a phantom field. tabindex="0" on the static container is the safer, predictable path.
- Test keyboard scrolling directlyTab to the box, confirm a visible focus indicator appears on the container, then press the Down arrow and Page Down and watch the content move. Do this in Safari and Firefox — focus-to-scroll behavior on overflow containers has historically differed between engines.
Stop it recurring
Any element you give overflow:auto or scroll should also get tabindex="0", a role, and an aria-label in the same commit.