Search code examples
htmlcsshtml-tableaccessibility

Tabindex on elements that are interactive only under certain conditions


In our web application we use multiple "responsive" HTML tables — they can be scrolled horizontally if their content gets too wide (CSS rules: width:100%; overflow-x: auto;). This allows to show all the necessary information in the table without breaking the layout and making the whole page horizontally scrollable.

In our case, this is relevant only for small screens (on resized browser windows or if the user increases the font-size by over 200%) as our tables aren't that big (note that the application is internal and will only be used on laptop/desktop screens).

Unfortunately, making content horizontally scrollable with overflow-x isn't accessible for keyboard users — the only way to scroll through the content would be with the mouse; using the arrow keys only works if the whole page is scrollable or if the element has focus.

So, in order to make our tables controllable with the keyboard, I was thinking about adding tabindex="0" to them and thus allowing to use the arrow keys. This seems to work fine if the table is scrollable, but also means that a non-interactive element (the table on a big screen) can receive focus, which might result in confusion in keyboard users.

Here is a little example (made with Bootstrap to spare writing some CSS). Resize the browser window to test it:

<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<h1>Some heading</h1>
<a href="#">First link (for tabbing purposes)</a>

<table class="table table-responsive" tabindex="0">
    <thead>
        <tr>
           <th scole="col">Column 1</th>
           <th scole="col">Column 2</th>
           <th scole="col">Column 3</th>
           <th scole="col">Column 4</th>
           <th scole="col">Column 5</th>
           <th scole="col">Column 6</th>
           <th scole="col">Column 7</th>
        </tr>
    </thead>

    <tbody>
        <tr>
           <td>Lorem ipsum</td>
           <td>Lorem ipsum</td>
           <td>Lorem ipsum</td>
           <td>Lorem ipsum</td>
           <td>Lorem ipsum</td>
           <td>Lorem ipsum</td>
           <td>Lorem ipsum</td>
        </tr>
    </tbody>
</table>

<a href="#">Second link (for tabbing purposes)</a>

Do you think that this solution might be a problem for accessibility and does anyone have a better idea how I can solve it? Thanks


Solution

  • In general, I would agree with @quentinc that putting the focus on a non-interactive element is not ideal (I wouldn't go so far as to say it's a "bad idea"), but it does give the keyboard user a way to scroll. I use the keyboard for most of my interactions and I don't have any other way to scroll. I don't know what roulette is and as far as I know, the browser doesn't have any dedicated keys for horizontal scrolling, other than left/right arrows, which you already mentioned scrolls the page and not the table, unless the table can receive focus, thus the reason for this question.

    On firefox, the table will already receive focus because anytime a container has a scrollbar, firefox allows the focus to move to that object, specifically to allow scrolling. So you are already getting the behavior you want in firefox. You're just trying to enable that same behavior for chrome, safari, and internet explorer.

    If you put tabindex="0" on the table, you can also add a visually hidden <caption> to the table to tell the screen reader that focus was moved to the table to allow keyboard users to scroll horizontally. Something like this:

    <table class="table table-responsive" tabindex="0">
      <caption class="sr-only">table receives focus so keyboard users can scroll it</caption>
    

    (The "sr-only" class is from bootstrap too. See What is sr-only in Bootstrap 3?. You don't have to use bootstrap but can create your own class that is similar.)

    However, one drawback of allowing the table to receive focus is that NVDA will announce the entire contents of the table when it receives focus. This is kind of annoying. Here's what NVDA says:

    table  with 2 rows and 7 columns 
    table receives focus so keyboard users can scroll it
    Column 1
    Column 2
    Column 3
    Column 4
    Column 5
    Column 6
    Column 7
    Lorem ipsum
    Lorem ipsum
    Lorem ipsum
    Lorem ipsum
    Lorem ipsum
    Lorem ipsum
    Lorem ipsum
    

    You might argue that that's a problem with NVDA, and maybe it is. When an object receives focus, it's accessible name should be announced. In the case of the table, the accessible name is sort of the contents of the table, although one could also argue the accessible name should be the <caption> and that's all that should be read. You can file a bug for NVDA if you think the behavior is incorrect. If the table didn't have a <caption>, then I could see the entire contents being read so I think you have a case that NVDA is wrong.

    I tried working around it by putting a title, aria-label, and aria-labelledby on the table (not all at the same time) but the entire table was always read (in addition to the title or label).

    But I also agree again with @quentinc that horizontal scrolling should be avoided if possible. On internet explorer, you don't even see the horizontal scrollbar until you actually start scrolling (with the keyboard) so you might not know there's more information to the right unless you can see some of the text clipped on the edge of the table. (Note, the scrollbar appears if you hover over the table with the mouse, but we're talking about keyboard users.)

    Tough situation. Without the focus, a keyboard user can't scroll the table. With the focus, a screen reader might hear all kinds of extra stuff. In the former, there isn't any kind of workaround. In the latter, while it's noisy to hear all that read, the screen reader user can hit ctrl to immediately silence the screen reader (and hopefully they silence it after hearing the <caption> read).