### [HTML 多级菜单的触屏交互:hover 到 click 的改造](https://www.huociguo.com/article/1789)
**Published:** 2026-10-02T10:45:37
**Author:** 米了
**Excerpt:** 桌面端好好的多级菜单,搬到手机上就点不开 📱。原因很直接:触屏没有悬停状态, 这套展开逻辑在移动端失效。改造思…
桌面端好好的多级菜单,搬到手机上就点不开 📱。原因很直接:触屏没有悬停状态,`li:hover` 这套展开逻辑在移动端失效。改造思路不是推倒重写,而是把 hover 与 click 两套触发方式并存。

触屏设备缺少悬停状态,多级菜单必须改造触发方式
## 第一步:结构先语义化
```
```
嵌套 `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 三条路径各测一遍 ✅。三条路径共用同一份结构,差异只在触发层,这就是渐进增强的标准做法。
**Tags:** 事件冒泡, 响应式布局, 多级菜单, 渐进增强, 触屏交互
**Categories:** HTML5
---