Keyboard-Only Scrolling Areas
I have spent a few years banging on about ensuring scrolling areas on a page are accessible to keyboard-only users. This is partly because the term “keyboard” maps to other input types that we distill to “keyboard” for ease of reference (speech input, sip-and-puff, on-screen keyboards, scanning software, etc.). When something cannot be operated with the keyboard, a whole bunch of users are blocked.
The most common technique to make a scrolling area work for keyboards is to give it a
tabindex. Once it has focus, arrow keys can scroll up and down, left and right. This accounts for scrolling areas with no interactive controls to take focus from a Tab , or when arrowing through those controls also sets their value (radio buttons, select menus) or triggers an action (broken radio buttons or select menus).
Once this otherwise generic area can accept focus, however, we have to address how that impacts screen reader users. It must have an accessible name so a screen reader can announce it. To have an accessible name, it must also have an appropriate role, which also brings along any interaction instructions (I use
region since it is a generic landmark).
Remember many areas do not scroll until something happens. Viewport changes, dynamic content, or other actions can cause content areas to change size on the fly and then generate scrollbars.
This all means screen reader users get a verbose interface as we work to support keyboard-only users, even when that area does not yet scroll.
Solutions for Users
As a keyboard user, the good news is that you can make use of scrolling areas without a
tabindex, role, and accessible name strapped onto every instance. Here are three methods.
Switch to Firefox
Firefox treats scrolling areas as tab-stops by default (and has done so since at least 2011 and Firefox 4). This means you can tab to it and then use the arrow keys to scroll.
This feature was requested and supposedly added in Chromium in 2018, but disabled a week later, and continues to be an open issue. In other words, it is not coming soon. I could find no feature in development or related bug for Safari.
This video shows how Firefox experiences a scrolling area of the page:
Activate Caret Browsing in Chrome, Edge, or Firefox
To better spot scrolling areas on Windows 10, head to Start → Settings → Ease of Access → Display → Automatically hide scroll bars in Windows and set it to “Off”. In Windows 11, use Start → Settings → Accessibility → Visual Effects → Always show scrollbars and set it to “On”.
To try caret browsing, press F7 in your browser and start arrowing.
There are some things to note:
- Focus and focus-within styles will not be triggered.
- Putting the caret into a scrolling area does not mean the area has focus.
- The area only scrolls when your text cursor is about to move into a hidden part of the content, which can still be a lot of key presses just to see content.
- If focus is already on a text input, you cannot just arrow past it; you will need to tab out of it and then arrow from wherever you land.
- If you set the text cursor indicator or text cursor thickness in Windows accessibility settings, they are not applied here.
This video shows Edge on Windows using the text cursor with text cursor accessibility settings in use:
For some context, here is the text cursor in Windows 11 with a more obvious indicator and a thicker line. Note how the caret browsing cursor looks nothing like it, retaining its single-pixel-thick line instead.
Safari: Use Mouse Keys
If you are on macOS and using Firefox, you can still tab to a scrolling area. If you are using Chrome, Edge, or Firefox, you can use caret browsing. But if you are using Safari, you have to rely on macOS itself to emulate a mouse (Full Keyboard Access is no use here).
First you must enable Mouse Keys. Then you can use your keyboard or the number pad to move the mouse pointer into position over the scrolling area. Then use your keyboard or the number pad to simulate a mouse click, essentially giving the scrolling area virtual focus. From there you can use the arrow keys to scroll the area itself.
To better spot scrolling areas on macOS, you may want to go into System Preferences → General → Show Scroll Bars and set it to “Always”.
If you are a mobility-impaired user, there are other ways to scroll an area that may be far easier than hammering the keyboard, but they are all based on also emulating a mouse. Joysticks, switches, voice, facial expressions, and so on.
This video shows Mouse Keys setting virtual focus to allow scrolling:
If you have no number pad, you will likely need to disable Mouse Keys immediately after using it (press ⌘ five times). Otherwise the next time you start typing in a text box you may be surprised when some letters and numbers do not appear (7, 8, 9, U, O, J, K, L, I, M, and .).
Solutions for Developers
Given all the information above, as developers we need to weigh this against what we know and can discover. This involves understanding the scrolling area’s purpose, the point of the page, the overall reason for the site, the patterns extant on the screens within the site, and so on.
It also involves understanding our user’s technology profile, mood, stress level, comfort with technology, skill with same, willingness to experiment, tolerance for mistakes, and so on.
Anecdotally, I have found most users are unaware caret browsing exists. How many mobility-impaired users know it exists is unknown to me, at least not without a more formalized research effort.
Twitter poll, which is clearly highly scientific:
Do you use caret browsing in your browser?
Out of 672 respondents, 79.2%, or 532 of them, did not know what caret browsing is. Only 25, or 3.7%, use caret browsing. Those percentages stayed consistent throughout the 24 hours the poll ran.
Use this example to test your own caret browsing or mouse emulation techniques. It is what I used for the videos above. Note the scrolling container has both
:focus-within styles. Visit the debug version free of the wrapping cruft to try it.
If I am building screens for a small set of users within an organization that is standardized on Microsoft Windows and I am in a position to train those users, then I will consider dropping my
tabindex / role / accName approach.
If I am building a public-facing site where critical information could be in a scrolling area that anybody using any browser on any platform could use, and I will never know them and they may never come back, then I am still leaning on
tabindex / role / accName.
Until Apple implements caret browsing for Safari and we have some comfort our audience uses caret browsing (or are all on Firefox), screen reader users will be stuck with overly-verbose scrolling interfaces. With the added irony that a blind screen reader user won’t even know it scrolls.
Update 6 June 2022: Spatial Navigation
I have seen some side discussion of spatial navigation as another option for users. The problem is that spatial navigation is meant for moving between interactive bits on the page, not non-interactive scrolling areas.
You can try this yourself and see it will not work in this scenario. Either:
- grab a Presto version of Opera (before it moved to a Chromium engine),
- try the
--enable-spatial-navigationswitch when launching Chrome (which does not seem to work anymore?), or
- install Vivaldi and enable it (with the Shift modifier key).
If you make the scrolling region interactive by giving it a
tabindex, role, and accessible name, then spatial navigation will work to put focus on it. Then you can use the arrow keys (no Shift modifier). At which point you are back to the verbose coding technique I am recommending.
Update 28 November 2022: Firefox Feature
Some developers consider the Firefox feature I outlined above to be a bug. Enough that they are trading tips on how to code around it — and making for a worse, less accessible experience in the process.
Bear in mind that when people ask browsers to fix accessibility problems automatically, we may be underestimating developers’ ability to understand why a feature exists in a browser. Oh, and their desire to leave it be.
Update 22 September 2023: Chrome Feature
Per Issue 1444450: Enable KeyboardFocusableScrollersEnabled code in ax_object.cc, Chrome 118 should mimic Firefox’s support for making scrolling areas focusable by default. If WebKit (Apple Safari) ever gets on board, the hack I outline here can go away.
Isn’t giving the scrollable container an accessible Name and role going to be really confusing for a screen reader? What role would you assign it? Could you kindly Give me an example? Much appreciated!
Tom, to answer each of your questions…
- Yup, which is why in the opening I say,This all means screen reader users get a verbose interface as we work to support keyboard-only users,and then at the end of the Verdict I say,screen reader users will be stuck with overly-verbose scrolling interfaces […]
- From paragraph three,
- I can give you two, also linked at the top of this post:
This is neat and I also didn’t know caret navigation exists. I understand that the most important thing is that people can navigate around the scrolling container. It’s accessible! Although I was wondering if you envisaged any negative effects for people who track caret focus, such as Windows Screen Magnifier users (with that setting turned on)?
Off the top of my head, only if they are reading something where their cursor is not. But in that scenario, that would be a user decision.