Home » Jquery » jquery – Menu Visibility and MS Edge hack for tab accessable menu

jquery – Menu Visibility and MS Edge hack for tab accessable menu

Posted by: admin February 22, 2020 Leave a comment

Questions:

I have a css nav menu that uses focus-within to allow tabbing through the Main nav for handicap accessibility. Edge doesn’t support focus-within or allow tabbing into hidden items. I hope to use jquery to change the nested ul visibility as we tab through the nav links, I can’t figure out how to change the ul back to hidden when the tab focus moves off of that particular ul’s contents. So tab on to something with a ul that is hidden, the UL becomes visible, allowing tabbing in to it’s contents. Then after tabbing through all that UL’s contents, tab focus moves out of the ul to the next link and the UL is changed back to hidden and repeat for all UL’s inside the nav. I don’t know much jQuery just seemed like the right way to go until edge supports focus-within. The fiddle is below, Thanks for any help while I continue to attempt a solution.

TLDR; do you know the jquery syntax to change a ul to visibilty:hidden when someone .focusout of the .last item of an individual ul? We don’t want to hide the ul when focus has left the ul unless it was the LAST item in the list.

jQuery(document).ready(function(){
  jQuery('#main  a').focus(function(){
      jQuery(this).next("ul").css('visibility','visible')

  });

});

https://jsfiddle.net/joeyjosay/0jxqut74/7/

THIS IS THE SOLUTION I FOUND

jQuery(document).ready(function(){
  jQuery('#main  a').focus(function(){
      jQuery(this).next("ul").css('visibility','visible')

  });
  jQuery('li ul li:last-child').focusout(function(){
      jQuery(this).parent('ul').css('visibility','hidden')

  });
});
How to&Answer:

I hope to use jquery to change the nested ul visibility as we tab through the nav links

This is not how to make a menu accessible. The problem comes from the fact that if your menu had 15 drop-down items a user would be forced to tab through them all to get to the next ‘top level’ menu item.

Also how do people access these menu items on a tablet in landscape? As you can’t use :hover I would guess you cannot access your sub menus. (nowadays a lot of tablets are 1920*1080 or higher so you can’t rely on width CSS in your CSS).

Try the fiddle below (where I added a load more menu items to your example) and select ‘main 2’ – a total of 19 tab stops are needed to illustrate the frustration automatic drop-downs cause.

jQuery(document).ready(function(){
  jQuery('#main  a').focus(function(){
      jQuery(this).next("ul").css('visibility','visible')
  
  });
  
});
#main>ul li a{
  display:inline-block;  
  float:left;
}
#main li > ul {
  visibility: hidden;
  
}
#main li:hover > ul{
  visibility: visible;
  
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="main">
  <li>
    <a href="#">main 1</a>
      <ul>
        <li>
          <a href="#">sub 1</a>
            <ul>
              <li>
                <a href="#">dubsub1</a>
              </li>
              <li>
                <a href="#">dubsub2</a>
              </li>
              <li>
                <a href="#">dubsub3</a>
              </li>
              <li>
                <a href="#">dubsub4</a>
              </li>
              <li>
                <a href="#">dubsub5</a>
              </li>
              <li>
                <a href="#">dubsub6</a>
              </li>
              <li>
                <a href="#">dubsub7</a>
              </li>
              <li>
                <a href="#">dubsub8</a>
              </li>
              <li>
                <a href="#">dubsub9</a>
              </li>
              <li>
                <a href="#">dubsub10</a>
              </li>
              <li>
                <a href="#">dubsub11</a>
              </li>
              <li>
                <a href="#">dubsub12</a>
              </li>
              <li>
                <a href="#">dubsub13</a>
              </li>
               <li>
                <a href="#">dubsub14</a>
              </li>
              <li>
                <a href="#">dubsub15</a>
              </li>
            </ul>
          </li>
        <li>
          <a href="#">sub 2</a>
        </li>
      </ul>

  </li>
  <li>
    <a href="#">main 2</a>
      <ul>
        <li>
          <a href="#">sub 1.1</a>
          <ul>
              <li>
                <a href="#">dubsub2</a></li>
            </ul>
          
          </li>
        <li>
          <a href="#">sub 2.1</a>
        </li>
      </ul>
  </li>
  <li>
    <a href="#">main 3</a>
  </li>
</ul>

What Should you do instead?

Instead you should provide a clickable item in the menu to show the drop-down for keyboard users.

There are several ways to do this. One option is to make the top level menu item for each sub-menu open the sub-menu instead of going to the main page.

If you cannot support this due to site architecture then add a down-arrow next to the top level menu item that when clicked opens the drop-down menu.

A great example to get you started is available at W3C – it shows how to add a separate drop down arrow that is focusable and toggles the sub-menu for keyboard users but also shows the drop-down menu on :hover so it provides the same experience for mouse users as before.

The only thing I would add to the example is if possible make the drop-down target 44px by 44px minimum so that it also complies with minimum touch target sizes according to WCAG. – although this is difficult if you haven’t designed for it so just do what you can!

Whichever way you choose the result is that instead of 19 tab stops to reach ‘main 2’ you instead only have 3 tab stops -> ‘main 1’ -> ‘main 1 drop down’ -> ‘main 2’.

Final thing, focus-within is great and all but only has 84% browser coveragesee this answer I gave about focus-within for another way to achieve certain things in CSS using the + operator, which may be useful for you as it covers similar theories on how to work with aria-expanded and use it in CSS.

Answer:

This code was able to identify the last item in each list and once it lost focus the visibilty of it’s parent ul was set back to hidden. A good hack for now, but like other answers stated a different nav build would be ideal.

jQuery(document).ready(function(){
  jQuery('#main  a').focus(function(){
      jQuery(this).next("ul").css('visibility','visible')

  });
  jQuery('li ul li:last-child').focusout(function(){
      jQuery(this).parent('ul').css('visibility','hidden')

  });
});