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

响应式菜单使用focus导致点击无法跳转链接,如何解决?

问题分析与解决方案

你的问题出在focus伪类的特性上:只有当按钮持续持有焦点时,.nav-item的展开样式才会生效。点击按钮后,如果你立刻点击菜单里的链接,按钮会瞬间失去焦点,导致.nav-item的高度变回0,菜单直接收起,链接的点击事件被中断,自然无法跳转。而用Tab键切换焦点时,焦点在按钮和菜单元素之间有序转移,不会触发按钮突然失焦,所以能正常交互。

下面给你两种可行的解决办法:

方法一:用focus-within伪类(无JS,推荐)

这个方法不需要写JS,只需要调整HTML结构和CSS:

  1. 把按钮和.nav-item放到同一个父容器里:
<div class="nav-wrap">
  <button>菜单按钮</button>
  <div class="nav-item">
    <a href="/page1">链接1</a>
    <a href="/page2">链接2</a>
  </div>
</div>
  1. 修改CSS规则:
/* 只要父容器内有元素持有焦点,就展开菜单 */
.nav-wrap:focus-within .nav-item {
  height: 330px;
}

@media only screen and (max-width:1117px) {
  .nav-item{
    display: flex;
    flex-direction: column-reverse;
    align-items: flex-end;
    height: 0;
    overflow: hidden; /* 必须加,确保高度为0时内容完全隐藏 */
    transition: height 0.3s; /* 可选,添加过渡动画让展开/收起更流畅 */
  }
}

focus-within的特性是:只要容器内的任意元素(按钮或菜单链接)获得焦点,容器就会触发这个伪类。所以点击菜单链接时,父容器仍处于focus-within状态,菜单不会收起,链接能正常完成跳转。

方法二:JS切换类(兼容旧浏览器)

如果需要兼容不支持focus-within的旧浏览器(比如IE),可以用JS给菜单添加切换类的逻辑:

  1. 添加JS代码:
const menuBtn = document.querySelector('button');
const navItem = document.querySelector('.nav-item');

menuBtn.addEventListener('click', () => {
  navItem.classList.toggle('expanded');
});

// 可选:点击菜单外部时收起菜单
document.addEventListener('click', (e) => {
  if (!menuBtn.contains(e.target) && !navItem.contains(e.target)) {
    navItem.classList.remove('expanded');
  }
});
  1. 修改CSS规则:
/* 保留原focus规则,同时添加类触发的规则 */
button:focus ~ .nav-item,
.nav-item.expanded {
  height: 330px;
}

@media only screen and (max-width:1117px) {
  .nav-item{
    display: flex;
    flex-direction: column-reverse;
    align-items: flex-end;
    height: 0;
    overflow: hidden;
    transition: height 0.3s;
  }
}

这样点击按钮时,通过JS给.nav-item添加expanded类,强制保持展开状态,即使按钮失去焦点,菜单也不会立刻收起,链接可以正常跳转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:35:15