如何为键盘导航设置CSS下拉菜单?

时间:2017-01-25 13:50:13

标签: html css drop-down-menu accessibility keyboard-navigation

我已经看到了一些解决方案,但我无法弄清楚如何在我的代码中加入一些这些解决方案,或者某些解决方案使用了我在项目中无法使用的东西。

让我们回答一下问题:

我需要为键盘导航创建一个现有的CSS下拉菜单。我在使用[Tab]打开下拉菜单方面取得了一些进展,但我无法导航到里面的选项。

这是我的代码:

    .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>

代码http://codepen.io/WillCodebit/pen/XpaqqJ

注意:我正在尝试避免使用任何javascript解决方案,因为在这个项目中我需要对任何javascript使用GWT,这是一种我无法违反的模式。

提前致谢。

修改 此菜单应具有与Google帐户菜单类似的行为。内部的选项也必须通过键盘访问。

Menu example

3 个答案:

答案 0 :(得分:0)

From Heydon Pickering - Practical ARIA examples

<nav role="navigation" aria-label="example with dropdowns">
<ul class="with-dropdowns">
    <li><a href="#">Home</a></li>
    <li>
        <a href="/about" aria-haspopup="true">About</a>
        <ul aria-hidden="true" aria-label="submenu">
            <li><a href="/about/#who-we-are">Who we are</a></li>
            <li><a href="/about/#what-we-do">What we do</a></li>
            <li><a href="/about/#why">Why</a></li>
        </ul>
    </li>
    <li><a href="#">Blog</a></li>
    <li><a href="#">Contact</a></li>
</ul>

答案 1 :(得分:0)

感谢Shannon Youg试图提供帮助。

我找到了一个解决方案,但我必须使用一些Javascript才能使其正常工作。

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,好吧,我用GWT制作,但逻辑很简单:

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

答案 2 :(得分:0)

我有完全相同的问题-但是确实发现我的答案分散在互联网的不同地方,这就是为什么我在此处发布解决方案的原因。这是一种无需JavaScript即可运行的解决方案。秘密在于这些伪类:

li > a:hover + ul,
li > a:focus + ul,
li:focus-within > ul

完整的HTML(标题部分):

<header>
    <nav>
        <ul>
            <li>
                <a href="#">Page 1</a>
                <ul>
                    <li>
                        <a href="#">Sub page 1</a>
                    </li>
                    <li>
                        <a href="#">Sub page 2</a>
                    </li>
                </ul>
            </li>
            <li>
                <a href="#">Page 2</a>
                <ul>
                    <li>
                        <a href="#">Sub page 3</a>
                    </li>
                </ul>
            </li>
        </ul>
    </nav>
</header>

完整CSS(没有实际样式)–第一级元素彼此相邻显示(display: inline-block;),第二级元素被隐藏并在父元素处于活动状态时立即显示:

header ul {
    list-style: none;
}

header nav > ul > li {
    display: inline-block;
    vertical-align: top;
}

header nav > ul > li > ul {
    visibility: hidden;
    opacity: 0;
}

header nav > ul > li > a:hover + ul,
header nav > ul > li > a:focus + ul,
header nav > ul > li:focus-within > ul {
    visibility: visible;
    opacity: 1;
}