Search code examples
htmlaccessibility

How can I build an accessible tab with close controls in HTML?


I have a tab system in my application. Tabs are focusable and can be interacted with. Within each tab is a button to close the tab.

<span role="tab" >
  <button />
</span>

Automated accessibility tests mark this as an issue, stating that the element (span tab) should not have focusable descendants.

How can I include a "close" button within my tab, while maintaining good accessibility on my page?


Solution

  • Regardless of the actual HTML tags used, if we assume that the tab is focusable, and that the close button is inside it, like this:

    <span role="tab" tabindex="0">
    Tab text
    <span tabindex="0">Close</span>
    </span>
    

    Then the automated tool is correct, there shouldn't be any focusable element inside another focusable element. This raises two problematic family of questions/problems:

    • The inner element is read both when the outer and inner elements get keyboard focus, resulting in confusion. In the example below, resp. "Tab text, close" and again "close". I don't want to close the tab, how do I activate it?
    • When the inner element is clicked, should the click also be triggered on the outer element? What about clicking inside the inner element but on a transparent point ? There are cases where you want both, and cases where you don't; it's unclear; it's hard to correctly manage event bubbling.

    You have basically two approaches to go around that.

    The simplest to understand is to change your HTML in order to avoid nesting. You can certainly change your CSS so that the close button stays visually inside the tab. For example:

    <span role="tab" tabindex="0">
    Tab text
    </span>
    <span role="button" tabindex="0">
    Close
    </span>
    

    However, observe how closable tabs are usually handled in desktop OS apps, and try to reproduce the same. You will notice that, most of the time, the close button is, in fact, not focusable, and, quite often, nor the tabs themselves.

    It isn't a problem if an interactive element isn't focusable, but only under the very important condition that there exists another reliable way to still perform the actions.

    Using keyboard shortcuts is generally a very good idea, but not in this particular case. The problem is that you can't use standard ones such as Ctrl+F4 or Ctrl+W to close, as well as Ctrl+PageUp/Down or Ctrl+Tab to switch, as they are already used for handling the tabs of the browser itself. Or you must be sure that the user isn't using your app inside a tab (maybe possible for a Elektron/NW.js app) IF you use another non-standard keyboard shortcut, you will need to tell the user about it, the user will have to remember about it, and it will anyway be a little uncomfortable.

    Remains several possibilities, among others:

    • An explicit close button at the end of the content (focusable this time, of course!)
    • A close item somewhere in a context menu or menu bar.

    In any case, in fact, it's always good to provide several alternatives to perform a given action. A keyboard shortcut may not be enough. There exists very limited input devices that simulate a keyboard but can only send 4, 6 or 8 different keys. Such devices may be actionned with a foot, a fist, the chin, the tongue, by blowing in pipes, ... for those who can't use neither a mouse, nor a touch device, nor a keyboard.