:hover在移动端失效是因触摸设备无持续悬停状态,ios/android仅短暂模拟后即失效;需用:focus-within替代,并确保html结构为文本子菜单,消除所有间隙、合理定位与事件控制。

纯 CSS 的 :hover 能触发二级菜单显隐,但只在桌面端可靠;移动端点击即跳转、无法保持展开——这不是你代码写错了,是浏览器行为本身决定的。
为什么 hover 在手机上点一下就收起来?
触摸设备没有持续 hover 状态。iOS 和安卓浏览器里,:hover 只在长按模拟悬停时短暂生效,松手立刻失效。用户点开一级菜单,手指一移,二级 ul 就消失,根本来不及选。
- 别指望
li:hover ul在真机上“正常工作”——它在 Safari 移动版里可能只闪一下,Chrome Android 里甚至不触发 - 用
:focus-within替代:一级菜单项必须是<a></a>(天然可聚焦),二级ul嵌在它的父li内部 - 结构必须是:
<li> <a>Products</a><ul><li><a>Laptops</a></li></ul> </li>,不能把ul放到li外面
二级菜单显示后马上消失的常见原因
鼠标从一级项移到二级菜单途中“断连”,导致 :hover 失效。这不是 CSS 写得不对,而是布局留了物理间隙。
-
ul必须设position: absolute,父li设position: relative,否则定位偏移或被裁剪 - 二级
ul的top值要刚好接住一级项的底边,比如top: 100%或top: 45px(取决于一级高度),不能靠margin-top - 检查是否有
border、padding或父容器overflow: hidden把二级菜单截掉 - 所有间隙(哪怕 1px)都会触发
mouseout——用开发者工具检查元素之间是否真正“无缝衔接”
display: none 切换为什么经常失效?
直接用 display: none / display: block 是最简方案,但极易出问题:切换硬、无过渡、且一旦父容器高度塌陷或 overflow 隐藏,子菜单就压根不出现。
- 初始状态用
visibility: hidden; opacity: 0; pointer-events: none;,hover 时改为visibility: visible; opacity: 1; pointer-events: auto; - 这样能加
transition: opacity .2s,视觉更稳,也避免 display 切换引发重排 - 千万别对二级
ul单独设display: none后又用li:hover ul { display: block }——如果父li高度为 0,它根本没 hover 区域 - 确保
ul ul(所有嵌套子菜单)默认隐藏:ul ul { visibility: hidden; opacity: 0; pointer-events: none; }
真正难的不是写几行 CSS,而是让鼠标从一级滑到二级的过程中,DOM 结构、定位、间隙、事件流全部对齐——漏掉任意一环,菜单就“飘”一下消失。移动端必须放弃 :hover,用 :focus-within + 键盘可访问性兜底,否则就是半残功能。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











