Accessible CSS Dropdown Menu

How can i make a CSS drop down menu accessible for keyboard navigation?

Thanks to Shannon Youg who tried to help.

I found a solution, but I had to put some Javascript to make it work.

HTML:

<div class="my-menu">
<a id="menuUser" href="javascript:showHideMenu()" class="">
<div>
Test
</div>
</a>
<ul id="menuUserDropdown" class="menu-dropdown">
<li>
<a href="#" class="menu-dropdown-item">
Option 1
</a>
</li>
<li>
<a href="#" class="menu-dropdown-item">
Option 2
</a>
</li>
<li>
<a href="#" class="menu-dropdown-item">
Option 3
</a>
</li>
</ul>
</div>

CSS:

.my-menu a{
display: inline-block;
font-family: 'OpenSans Bold';
font-size: 16px;
color: #646464;
text-decoration: none;
cursor: pointer;
position: relative;
}
.my-menu a div{
padding: 4px 5px 4px 0;
}
.my-menu a.opened div,
.my-menu a:hover div{
background-color: #c9252b;
color: #fff;
}
.my-menu .menu-dropdown.opened{
display: block;
}
.my-menu div{
display: inline-block;
vertical-align: middle;
}
.my-menu .menu-dropdown{
display: none;
margin: 0;
position: absolute;
z-index: 30;
background-color: #FFF;
list-style: none;
padding: 0;
border: 1px solid #b4b4b4;
}
.my-menu .menu-dropdown-item{
display: block;
background-color: white;
padding: 12px;
text-decoration: none;
width: 162px;
cursor: pointer;
font-size: 16px;
color: #323232;
}
.my-menu .menu-dropdown-item:focus,
.my-menu .menu-dropdown-item:hover{
background-color: #b4b4b4;
color: #fff;
}

Javascript, well, I made with GWT, but the logic is simple:

/* Just add or remove the class "opened" from "menuUser" and "menuUserDropdown".
You can put a "blur()" and "mouseLeave()" functions
to close the menu when the user moves away the cursor or
move the focus out of the menu too. */

Javascript and css accessible dropdown menu

The solution is add this extra on:

// If sub menu is already open

   if ( $(this).children('a').hasClass('js-openSubMenu') || $(this).children('ul').hasClass('js-showElement')) { ... }

else { ... }

Thank you everything.

Making my drop-down menus accessible when only using the keyboard

Looking at the tutorial, it is not really a good starting point to make fully keyboard accessible. Unfortunately it isn't just a matter of showing the drop-downs when pressing tab.

Once you get past a couple of items in each drop-down it it not a good thing for keyboard users to have to tab through every option.

There are two main ways to make this type of menu accessible:

  1. Traditional method: Make each top level link go through to a landing page that includes the links from the menu, and hide the drop-downs from keyboard use.

  2. HTML5 (new) method: Use WAI-ARIA markup and lots of scripting to enable full keyboard accessibility.

The traditional method if fairly easy to do, you just need to properly hide the menus that are off-screen using display: none; on the classes starting .dropdown_1column. The means keyboard users won't tab through the sub-menus.

And then use display: block to show the sub-menus on hover (not focus), where the CSS starts:

#menu li:hover .dropdown_1column

To achieve the HTML5/new method I would start with Adobe's open-sourced "Accessible Mega Menu". It would be a huge amount of work to do this from scratch, and unless you know how to test with a wide range of user-agents, it is unlikely to work as well as Adobe's.

Keyboard accessible drop down menu not iterating through sub menu

I use some script to add a class to the item that has focus and walk up the DOM to add it to ancestors so that I can display them. I also remove the class when the focus changes.

It has been a while since I have reviewed it to remove / tweak any dumb bits.

Part of the issue you are having is that you are using display: none, which means a keyboard will never find it. If you use an off-screen technique, then the user can tab into the control.

Also, please remove role="menuitem" throughout as well as tabindex="0". The former implies interaction you are not supporting (such as the arrow keys) and the latter creates extra tab stops that do not announce themselves correctly to screen readers.

    // Get the nav by id
var pNav = document.getElementById("globalNav");

function unClassy(){
try {
// Remove the focus class
pNav.classList.remove("focus");
// Remove the focus class from all its descendents
pNavDesc = pNav.getElementsByTagName('*');
for( var i = 0; i<pNavDesc.length; i++){
pNavDesc[i].removeAttribute("class");
}
} catch (e) {
console.log(e);
}
}

/* For any clicks, clear the focus class from the nav and all its descendants, essentially closing the menu when a user clicks/taps outside of it. */
document.documentElement.onclick=function() {
try {
unClassy();
} catch (e) {
console.log(e);
}
}

/* Manipulate focus classes in navigation. */
function classy(){
try {
unClassy();
// Add the focus class to items that have focus
// Get the element that currently has focus
var focusedElement = document.activeElement;
// If that element is the primary nav, add the class
if (focusedElement.id == pNav.id){
// Add the focus class
pNav.classList.add("focus");
}
// If nav contains the focused element, add the class
if (pNav.contains(focusedElement)){
focusedElement.classList.add("focus");
el = focusedElement;
while (el.parentNode) {
el.classList.add("focus");
el = el.parentNode;
}
}
} catch (e) {
console.log(e);
}
}

/* Delay the assigning of classes to give the :focus a chance to catch up. There has to be a better way for this. */
document.documentElement.addEventListener("keydown", delayClassy, false);
function delayClassy(){
try {
setTimeout(classy, 200);
} catch (e) {
console.log(e);
}
}


Related Topics



Leave a reply



Submit