Multi-level dropdown menu that is keyboard accessible for WCAG ada compliance

纵饮孤独 提交于 2021-01-28 23:24:55

问题


I'm trying to create a dropdown menu that can be navigated by using the keyboard. I can get the first level to work by using the tab key, but have been unable to access the second level. Example can be found here https://codepen.io/jjfash/pen/oNgqEjx

The html:

    <html lang="en">
    <head>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
    </head>
    <body>
        <div class="featuredTopics">
            <a class="btn btn-semiTransparent dropdown-toggle" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" tabindex="0">News Archive</a>
            <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu">
                <li class="dropdown-submenu pull-right dropdown-item"><a tabindex="0" href="#">2017</a>
                    <div class="dropdown-menu">
                        <ul>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q1</a></li>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q2</a></li>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q3</a></li>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q4</a></li>
                        </ul>
                    </div>
                </li>
                <li class="dropdown-submenu pull-right dropdown-item"><a tabindex="0" href="#">2018</a>
                    <div class="dropdown-menu">
                        <ul>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q1</a></li>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q2</a></li>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q3</a></li>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q4</a></li>
                        </ul>
                    </div>
                </li>
                <li class="dropdown-submenu pull-right dropdown-item"><a tabindex="0" href="#">2019</a>
                    <div class="dropdown-menu">
                        <ul>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q1</a></li>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q2</a></li>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q3</a></li>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q4</a></li>
                        </ul>
                    </div>
                </li>
                <li class="dropdown-submenu pull-right dropdown-item"><a tabindex="0" href="#">2020</a>
                    <div class="dropdown-menu">
                        <ul>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q1</a></li>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q2</a></li>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q3</a></li>
                        <li class="dropdown-item"><a tabindex="0" href="#">Q4</a></li>
                        </ul>
                    </div>
                </li>
          </ul>
        </div>
    </body>
    </html>

The CSS:

/* Buttons */

.btn {
    border:none;
    padding:12px;
    color:#fff;
    border-radius:0;
    box-shadow: 0px 2px 5px rgba(0,0,0,0.2);
}

.btn:hover,
.btn:focus,
.btn:active {
    text-decoration:underline;
    color:#fff;
} 

.btn:focus {
    box-shadow: 0px 2px 5px rgba(0,0,0,0.2);
}

.btn-semiTransparent:hover,
.btn-semiTransparent:focus,
.btn-semiTransparent:active {
    background:rgba(0,0,0,.1);
    color:#1f2a44;
}

.btn-semiTransparent:not(:disabled):not(.disabled):active {
    box-shadow: inset 0px 0px 5px #666 !important;  /* makes it look like you've pressed the button */
}



/* Dropdown Menu */

.dropdown-item {
    margin:0;
    padding:0;
    text-align:left;
}

.dropdown-submenu .dropdown-menu {
    left:100%;
    top:-3px;
    border-radius:0;
}

.dropdown-submenu {
    position: relative;
}

.dropdown-submenu:hover>.dropdown-menu {
    display: block;
}

.dropdown-submenu:hover>a:after {
    border-left-color: #fff;
}

.dropdown-submenu.pull-left {
    float: none;
}

.dropdown-submenu.pull-left>.dropdown-menu {
    right:100%;
}

.dropdown-item:focus, 
.dropdown-item:hover, 
.dropdown-item:active {
    background:#e6e6e6;
}

.dropdown-toggle {
    line-height:120%; /* makes the height of the button similar to the regular buttons.  having the caret as an ::after is making it taller */
}

.dropdown-toggle::after {
    font-family: 'FontAwesome';/* essential to enable caret symbol*/
    content:"\f054" !important;
    color:#a84300;
    border:none !important;
    min-width:16px;
    position:relative;
    top:4px;
}

.dropdown-toggle[aria-expanded="true"]::after{
    content:"\f078" !important;
    color:initial;
}

li.dropdown-submenu>a:after {
    font-family: 'FontAwesome';/* essential to enable caret symbol*/
    content:"\f054";
    color:#a84300;
    position:relative;
    left:8px;
    display:inline-block;
    width:15px; 
}

li.dropdown-submenu:hover > a {
    text-decoration:none;
}

li.dropdown-submenu:hover > a:after {
    content:"\f078" !important; 
    color:initial;
}

.dropdownPadding {
    padding:0px 150px 50px;
    background:transparent;
    border:none;
    right:calc(100% - 150px) !important;
}

.dropdownPadding ul {
    border:1px solid #ccc;
    margin:0;
    padding:10px 0;
    background:#fff;
}

At minimum, I'd like it so the menu is fully navigable using the keyboard for ADA compliance. My best case scenario would be working using arrow keys (not just the tab key) to navigate. I tried adding tabindex="0" to each element hoping that would work, but no luck so far. Any help is appreciated.


回答1:


There are a few ways to handle this but a great place to start is this W3C article about Menus as this covers a lot of the basics of menu design, sub menus, expected controls etc.

It also has some examples of how to set up the JavaScript for the expected functionality so that will help you.

One of the key parts is intercepting the enter key to open sub-levels, either directly on the menu item or as a separate drop down arrow next to the main menu item.

I personally prefer having any top level items not being a link and instead being used as toggles to open sub menus but it depends on your site architecture.

The last thing you want is to make each sub-menu accessible via just tabbing. At that point if someone wants to reach "2020 Q4" they would have to tab past 15 items.

What you want instead is for each 'quarter picker' to open after pressing either enter or the right arrow key.

That way to get to "2020 Q4" is just 4 tabs, enter (or right arrow), 4 tabs so only 9 key presses (instead of 15).

One last thing to consider is that your menu needs to work without JavaScript or offer an alternative.

What I tend to do is have a <noscript> element with a link to the complete HTML sitemap show if they don't have JavaScript enabled and I have a more complex menu such as this.



来源:https://stackoverflow.com/questions/59668131/multi-level-dropdown-menu-that-is-keyboard-accessible-for-wcag-ada-compliance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!