Search code examples
htmlcssdrop-down-menuaccessibilitykeyboard-navigation

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


I saw already some solutions, but i can't figure out how can i put some of these solutions in my code, or some solutions uses something that i can't use in my project.

Let's go to the question:

I need to make an already existing CSS drop-down menu accessible for keyboard navigation. I got some progress in opening the drop-down menu with [Tab] but i can't navigate into the options inside.

Here is my code:

    .menu .options-menu-dropdown{
        display: inline-block;
        font-family: 'OpenSans Bold';
        font-size: 16px;
        color: #646464;        
        text-decoration: none;
        cursor: pointer;
        position: relative;
    }
    .menu .menu-dropdown{
        z-index: -1;
        visibility: hidden;
        opacity: 0;
        position: absolute;
        top: 0;
        right: 0;
        min-width: 180px;
        text-align: right;
        overflow: hidden;
        margin-top: -6px;
        margin-right: -6px;

        -webkit-transition: all 200ms ease-in-out;
        -moz-transition: all 200ms ease-in-out;
        -ms-transition: all 200ms ease-in-out;
        -o-transition: all 200ms ease-in-out;
        transition: all 200ms ease-in-out;    
    }
.menu .options-menu-dropdown:focus .menu-dropdown,
    .menu .options-menu-dropdown:hover .menu-dropdown{
        z-index: 100;
        visibility: visible;
        opacity: 1;
    }
    .menu .title-dropdown{
        background-color: #005e8b;
        font-size: 16px;
        padding: 8px 6px;
        white-space: nowrap;
        border-bottom: 1px solid #b4b4b4;
        color: #FFF;
    }
    .menu .menu-dropdown-item{
        display: block;
        background-color: white;        
        padding: 12px 32px 12px 12px;
        text-decoration: none;
        cursor: pointer;
        font-size: 16px;
        color: #323232;
        -webkit-transition: all 200ms ease-in-out;
        -moz-transition: all 200ms ease-in-out;
        -ms-transition: all 200ms ease-in-out;
        -o-transition: all 200ms ease-in-out;
        transition: all 200ms ease-in-out; 
        border-top: #b4b4b4 1px solid;
        border-left: #b4b4b4 1px solid;
        border-right: #b4b4b4 1px solid;
    }
    .menu .menu-dropdown-item:last-child{
        border-bottom: #b4b4b4 1px solid;
    }
  .menu .menu-dropdown-item:focus,
    .menu .menu-dropdown-item:hover{
        background-color: #b4b4b4;
        color: #fff;
    }
<div class="menu" align="center" >
  <div class="options-menu-dropdown" tabindex="0">
    <div>Test Menu</div>
    <div class="menu-dropdown">
      <div class="title-dropdown">Opened Test Menu</div>
      <a href="#" class="menu-dropdown-item" tabindex="1">Menu Item 1</a>
      <a href="#" class="menu-dropdown-item" tabindex="1">Menu Item 2</a>
      <a href="#" class="menu-dropdown-item" tabindex="1">Menu Item 3</a>
    </div>
  </div>
</div>

code http://codepen.io/WillCodebit/pen/XpaqqJ

Note: I'm trying to avoid any javascript solution, because in this project I need to use GWT for any javascript, it is a pattern that I can't violate.

Thanks in advance.

EDIT This menu should have a similar behavior than the account menu of Google. And the options inside must be accessible by keyboard too.

Menu example


Solution

  • 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. */