Keyboard and focus Rule

Scrollable areas must be reachable with a keyboard scrollable-region-focusable

When a box has its own scrollbar, mouse users scroll it with the wheel. Keyboard users can only scroll something that has focus, and a plain div cannot take focus. Anything below the visible part of that box is out of reach to them. Give the box tabindex="0" and a name, or make sure something focusable inside it does the job.

WCAG 2.2 A 2.1.1 Keyboard

Websight reports this as Scrollable region must have keyboard access

Who it affects

Someone with RSI who uses the keyboard instead of a mouse presses Tab and the terms of hire box is skipped. The last clause, the one that says the deposit is lost if the alarm goes off, is never seen.

A switch user who steps through focusable things one at a time has no way to step into a box that cannot take focus, so cannot read past its first few lines.

Someone using a screen reader can usually read the text anyway, because screen readers read the page rather than the screen, but cannot operate a button that sits below the visible part of the box.

Broken versus fixed

Both examples are live and rendered in a sandboxed frame. The broken one is deliberately broken.

Broken

Click in the frame, then press Tab. Focus goes straight to the Book the hall link. The arrow keys scroll the page, not the terms, so clauses 4 and 5 cannot be reached.

Fixed

Tab now stops on the box with a visible outline, and the down arrow scrolls it. A screen reader announces: Terms of hire, region.

Show the markup behind both examples
Broken
<style>body{font-family:system-ui;margin:0;padding:12px;font-size:14px}.terms{height:72px;overflow-y:auto;border:1px solid #999;padding:0 8px;background:#fafafa}.terms p{margin:8px 0}</style>
<p style="margin:0 0 8px">Click here, then press Tab. The box below is skipped.</p>
<div class="terms">
  <p>1. The hall must be left as found.</p>
  <p>2. No candles or naked flames.</p>
  <p>3. Music off by 11pm.</p>
  <p>4. The deposit is not returned if the alarm is set off.</p>
  <p>5. Keys back to the caretaker by 9am.</p>
</div>
<p><a href="#">Book the hall</a></p>
Fixed
<style>body{font-family:system-ui;margin:0;padding:12px;font-size:14px}.terms{height:72px;overflow-y:auto;border:1px solid #999;padding:0 8px;background:#fafafa}.terms p{margin:8px 0}.terms:focus{outline:3px solid #1d4ed8;outline-offset:2px}</style>
<p style="margin:0 0 8px">Click here, then press Tab. The box takes focus and the arrow keys scroll it.</p>
<div class="terms" tabindex="0" role="region" aria-label="Terms of hire">
  <p>1. The hall must be left as found.</p>
  <p>2. No candles or naked flames.</p>
  <p>3. Music off by 11pm.</p>
  <p>4. The deposit is not returned if the alarm is set off.</p>
  <p>5. Keys back to the caretaker by 9am.</p>
</div>
<p><a href="#">Book the hall</a></p>

Test it by hand in two minutes

  1. Click just above the scrolling box, then press Tab. The box should get a visible focus outline.
  2. With the box focused, press the down arrow and then Page Down. The content inside should move.
  3. Turn on a screen reader and Tab to the box. It should announce a name, not just group or nothing at all.
  4. Repeat for every box on the page with its own scrollbar: chat widgets, code samples, long legal text, side panels.

The fix

Before
<div class="terms">
  ...
</div>
After
<div class="terms" tabindex="0" role="region" aria-label="Terms of hire">
  ...
</div>

tabindex="0" puts the box in the Tab order. The role and label tell screen reader users what they have landed on. Add a visible :focus style so sighted keyboard users can see where they are.

Box that only scrolls because of a fixed height

Before
.news { height: 200px; overflow: auto; }
After
.news { overflow: visible; }

If the height limit is only there to tidy the layout, remove it. No scrolling box, nothing to fix.

Code sample that overflows sideways

Before
<pre><code>const rota = loadRota("food-bank", { week: 42, site: "St Mary's" });</code></pre>
After
<pre tabindex="0"><code>const rota = loadRota("food-bank", { week: 42, site: "St Mary's" });</code></pre>

Long code lines scroll horizontally. The same fix applies, and a role is not needed on a pre.

Common mistakes

  • Using tabindex="-1", which lets script focus the box but keeps it out of the Tab order.
  • Adding tabindex to the paragraphs inside instead of the element that scrolls.
  • Fixing it with a JavaScript scroll handler that only responds to the mouse wheel.
  • Forgetting a focus outline, so keyboard users cannot see that the box has focus.

WCAG criteria this rule maps to

axe-core tags this rule as WCAG 2.2 level A. It is one of the checks for:

The scanner finds elements whose content overflows with scrolling enabled and checks that the element, or something inside it, can take keyboard focus. It cannot tell whether the focusable thing inside is enough to reach all the content, so try it with Tab and the arrow keys. Recent Chrome and Firefox make some scroll boxes focusable on their own; Safari does not, and the scanner reports the issue regardless. Automated tools find only part of the accessibility problems on a page; a pass on this rule is not a pass on the criterion.

Scan your own page for this and 63 other checks

Open any page in Chrome, click Websight, and get a score out of 100 with every issue explained and a draft fix snippet per element.

Add Websight to Chrome

Free scans, no account, nothing leaves your computer. Automated tools find only part of the problems; the extension says so on every report.