### [HTML 多级菜单的触屏交互:hover 到 click 的改造](https://www.huociguo.com/article/1789) **Published:** 2026-10-02T10:45:37 **Author:** 米了 **Excerpt:** 桌面端好好的多级菜单,搬到手机上就点不开 📱。原因很直接:触屏没有悬停状态, 这套展开逻辑在移动端失效。改造思… 桌面端好好的多级菜单,搬到手机上就点不开 📱。原因很直接:触屏没有悬停状态,`li:hover` 这套展开逻辑在移动端失效。改造思路不是推倒重写,而是把 hover 与 click 两套触发方式并存。 ![手机屏幕上的应用菜单界面](https://api.huociguo.com/wp-content/uploads/2026/10/pexels-photo-16052346.jpeg) 触屏设备缺少悬停状态,多级菜单必须改造触发方式 ## 第一步:结构先语义化 ``` ``` 嵌套 `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 ---