火次果
火次果

暂无菜单项

首页/文章/技术文章/web前端/HTML5/
打开 MD 链接

HTML 多级菜单的触屏交互:hover 到 click 的改造

发布于 4天前
2

桌面端好好的多级菜单,搬到手机上就点不开 📱。原因很直接:触屏没有悬停状态,li:hover 这套展开逻辑在移动端失效。改造思路不是推倒重写,而是把 hover 与 click 两套触发方式并存。

手机屏幕上的应用菜单界面
触屏设备缺少悬停状态,多级菜单必须改造触发方式

第一步:结构先语义化

<nav>
  <ul class="menu">
    <li><a href="/a">一级</a>
      <ul class="sub"><li><a href="/a/1">二级</a></li></ul>
    </li>
  </ul>
</nav>

嵌套 ul 放在父级 li 内部,屏幕阅读器才能正确读出层级。

第二步:桌面端保留 hover

@media (hover: hover) {
  .menu li:hover > .sub { display: block; }
}

hover: hover 媒体查询只在真正支持悬停的设备上生效 🖱️,避免触屏首次点击被解释成 hover 而不跳转。

第三步:触屏端改为 click 切换

给含子菜单的一级项绑定点击事件:首次点击展开子菜单并阻止跳转,再次点击才放行。同时维护 aria-expanded,屏幕阅读器依赖它播报展开状态。注意事件冒泡 ⚠️:点击子项时不应把事件传到父级触发折叠,必要时调用 stopPropagation()。

第四步:键盘可达性补全

.menu li:focus-within > .sub { display: block; }

focus-within 让 Tab 键进入子菜单时保持展开 ⌨️,键盘用户与鼠标用户获得一致体验。

收尾验证

桌面 hover、触屏 click、键盘 Tab 三条路径各测一遍 ✅。三条路径共用同一份结构,差异只在触发层,这就是渐进增强的标准做法。

常见问题(FAQ)

为什么手机上 hover 菜单点不开?
触屏没有悬停状态。多数移动端浏览器把首次点击解释为 hover,导致菜单展开但不跳转,再次点击才触发链接。
focus-within 在多级菜单里有什么用?
键盘 Tab 进入子菜单任意项时,父级 li 保持 focus-within 状态,子菜单就不会收起,键盘用户得以完整浏览。
aria-expanded 必须加吗?
需要。屏幕阅读器通过 aria-expanded 播报菜单展开或收起状态,缺少该属性时视障用户无法感知菜单结构变化。
hover: hover 媒体查询的作用是什么?
区分设备输入能力。只有支持悬停的设备才启用 hover 展开规则,触屏设备自动走 click 逻辑,两套方式互不干扰。
移动端子菜单展开遮挡正文怎么办?
移动端改用手风琴式内联展开,子菜单推开下方内容;桌面端再用绝对定位浮层,两种布局按断点切换。
事件冒泡响应式布局多级菜单渐进增强触屏交互
支持作者
如果这篇内容对你有帮助,可以请作者喝杯咖啡
0 点赞
0 收藏
分享
0 讨论
反馈
0 / 600
细中粗
0 讨论
热门最新
总结
暂无总结
嗨,下午好!
所有的成功,都源自一个勇敢的开始
创作
社区
购物
会员
近期热门

暂无数据

火次果
火次果
首页
资迅中心
小店
AI导航
社区
所有的成功,都源自一个勇敢的开始
不辜负每一个勇敢的开始
关于FAQ协议
火次果 © 2026鲁ICP备2025164830号-1