You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅用CSS实现通过Tab键展开Mega Menu?

不用JS实现可访问的Mega菜单:解决Tab导航不触发的问题

问题出在:你给 <li> 加了 tabindex 但Tab键切换时,焦点会优先落在内部的 <a> 标签上(因为 <a> 是默认可聚焦元素),导致 li:focus 状态根本触发不了。不过不用JS也能解决,用CSS的 :focus-within 伪类就行。

具体修改:

1. 替换CSS触发规则

把原来的hover和focus触发代码:

li.has-children:hover .mm-cont,
li.has-children:focus .mm-cont {
  display:flex;
}

改成:

li.has-children:hover .mm-cont,
li.has-children:focus-within .mm-cont {
  display:flex;
}

2. 优化Tab导航设置(可选)

可以直接删掉 <li> 上的 tabindex,因为内部的 <a> 本来就能被Tab键选中,没必要给父级li加焦点。如果要调整导航顺序,直接给 <a> 设 tabindex 更合理。

修改后的完整代码:

CSS

nav {
  background:#ccc;
  position:relative;
}
nav > ul {
  display:flex;
  column-gap:1.5rem;
  width:100%;
  list-style:none;
  margin:0;
  padding:0;
}
nav li {
  padding:1.5rem;
}
nav li a {
  position:relative;
}
nav li.has-children > a:after {
  content:"";
  display:block;
  width:25px;
  height:25px;
  background-image:url('https://upload.wikimedia.org/wikipedia/commons/9/9a/Caret_down_font_awesome.svg');
  position:absolute;
  right:-30px;
  top:50%;
  transform:translateY(-50%);
}

.mm-cont {
  display:none;
  position:absolute;
  width:100%;
  background:#aaa;
  bottom:-132px;
  left:0;
}
.sub-menu {
  list-style:none;
  padding:0;
}

/* 鼠标悬停或子元素获焦时显示菜单 */
li.has-children:hover .mm-cont,
li.has-children:focus-within .mm-cont {
  display:flex;
}

HTML

<input type="text" placeholder="start here" tabindex="0" />
<nav>
  <ul>
    <li class="has-children">
      <a href="#" tabindex="1">Lorem</a>
      <div class="mm-cont">
        <ul class="sub-menu">
          <li><a href="#">Lorem</a></li>
          <li><a href="#">Ipsum</a></li>
        </ul>
        <ul class="sub-menu">
          <li><a href="#">Dolor</a></li>
          <li><a href="#">Sit</a></li>
        </ul>
      </div>
    </li>
    <li><a href="#" tabindex="2">Ipsum</a></li>
    <li><a href="#" tabindex="3">Dolor</a></li>
    <li><a href="#" tabindex="4">Sit</a></li>
  </ul>
</nav>

为什么这个方案可行?

:focus-within 会在元素本身或者它的任意子元素获得焦点时触发样式。当用户按Tab键切换到父li里的a标签时,父li会触发:focus-within,自然就展开了mega菜单。同时保留:hover规则,鼠标悬停的交互也正常,全程不用写一行JS,还符合键盘导航的可访问性要求。

内容的提问来源于stack exchange,提问作者user19103974

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 05:16:05