This is a control panel for administrators. The collapsible sidebar you see below contains links to other pages related to administration.

animated gif showing keyboard navigation order

This image shows me navigating with the TAB key, demonstrating that the TAB order is not messed up. The button is right before the collapsible sidebar.

When the collapsible target element is transitioned in or out of the screen, it is made visible or hidden with the display property. This means that the navigation links are only accessible after using the toggle button. This is very similar to Bootstrap's Collapse component, but it's my code.

Another thing it does is toggle the value of aria-expanded. The attribute aria-controls points to the target collapsible element.

So far so good, right? But I've been thinking... isn't this menu of the same kind as the Bootstrap Dropdown you see to the top-right corner?

  1. Both toggle the display of something.
  2. Both cause that something to 'popup' on the screen.
  3. Both toggles are buttons. They execute JavaScript when activated. It's not like a list of links that is always accessible by keyboard and that slides into view when you hover over an element.

The Bootstrap Dropdown component, in addition to what my menu also implements, uses the attribute aria-haspopup and provides keyboard navigation between menu items using the arrow keys. The ESC key closes it. Finally, when focus leaves the toggle or the popup menu, it is collapsed/closed.

So the question is, should I treat my collapsible menu the same as a Bootstrap Dropdown? That would mean implementing all of the dropdown's accessibility features.

1 Answer 1


Short Answer

The principles for displaying hidden content that you describe work for both a dropdown and for a menu.

If you implement all of the same accessibility features for the toggle part (not the content of the 'dropdown' / 'menu' content) then you should have a pretty good accessible menu.

Long Answer / Things to consider

Without seeing the code side by side I am making general assumptions.

I am also covering a lot of points about the content of a bootstrap dropdown vs a menu as you didn't make it clear which parts you were thinking of copying.

A few things I would consider / to be aware of

(1) - Your menu should use the <nav> element to be semantically correct. At this point you can hopefully see that the structure of a bootstrap dropdown won't work as it is designed to work with just links, not contained within a list.

(2) - One thing you didn't mention (but I assume you have done) is naming the button to open the menu with either aria-labelledby, aria-label or with some visually hidden text.

(3) - I noticed you can tab out of the menu when it is open, yet again can't see your code but I would normally say trap focus within the menu (rather than closing it as you would a dropdown) and either have a 'close' button or allow navigation back to the menu toggle to close the menu again (and change the label / use visually hidden text to indicate menu close when it opens - e.g. change 'open menu' to 'close menu' in your label / visually hidden text).

Either that or make sure that if you allow users to move focus outside of the menu it closes automatically (I prefer the first option as screen reader users may navigate by links in your menu so you can't rely on capturing just the tab key and then you are trying to check where the focus is).

If you decide to trap focus for screen reader users you need to add aria-hidden="true" to everything outside of the menu as well as managing the tab key.

I normally position the menu <nav> outside of the <header> if I am creating a flyout menu so that I can just apply the tabindex and aria-hidden to the <header>, <main> and <footer> and toggle those values on the <nav>. (reverse them for when the menu is closed / on page load). This is another important distinction as the parent container for the flyout menu must be the <nav> element to be HTML5 valid.

(4) - Make sure you can close the menu with the Escape key as that is expected (you mentioned that, just reinforcing it).

(5) - You also need to consider indicating the current page in navigation vs a dropdown where it contains just actions.

The most widely accessible version of 'current page' I know of looks like the following:-

    <li><a href="#" aria-describedby="pageCurrent">home</a></li>
    <li><a href="about">about</a></li>
    <li><a href="contact-us">contact us</a></li>
  <div id="pageCurrent">current page</div>

Or just remove the link to the current page from the menu list entirely as it should be your H1 (some debate about which method is best, I think both are fine).

Once you consider all of the above factors (off the top of my head as I can't do a code comparison) you can see why you can't really use bootstraps dropdown for anything other than the toggle method, which you seem to have implemented all necessary accessibility features anyway.

  • Thanks for the information. (1) The outermost element (the one that is collapsed and expanded) is now a <nav>. (2) Yes, it was already labelled with aria-label. (3) Bootstrap traps focus to dropdown items when navigating with the arrow keys, but allows the TAB to exit the menu, which collapses it. It's good enough like that, isn't it? I was always warned not to mess with tabindex. About indicating current toggle state, isn't aria-expanded enough? I tested Orca, and it speaks correctly. (4) Will implement that. (5) I use aria-current="page" for that. Not widely supported? Commented Jan 9, 2020 at 13:06
  • (1) ✔ (2) ✔ (3) Never use positive tabindex, however tabindex="-1" can be used to remove items that would normally receive focus from the tab order and is perfectly acceptable (and change it to tabindex="0" to toggle it and not break tab order), aria-expanded` is enough unless you want to use the toggle as a close button in a trapped list, in which case it is a good idea to indicate it is a close button, but not essential (4) ✔ (5) No support is not that great sadly. Glad I could help. Commented Jan 9, 2020 at 13:28
  • I understand it better now. Thanks again. Commented Jan 9, 2020 at 13:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.