transition必须写在常态选择器中而非:hover里,否则手机端移出时因过渡上下文丢失而跳变;需配合@media (hover: hover) and (pointer: fine)包裹整套悬停规则,并避免用transition: all。

transition写在:hover里,手机端移出时直接跳变
这是最常被忽略的根源:浏览器只在:hover激活时“看到”transition声明,一旦离开,过渡上下文就丢失了。结果就是悬停时有动画,手指松开瞬间阴影/位移直接归零——不是没触发,是压根没过渡契约。
必须把transition声明抽到常态选择器中:
.nav-item {
transition: opacity 0.2s ease, transform 0.2s ease;
}
.nav-item:hover {
opacity: 0.8;
transform: translateY(-2px);
}
- 别用
transition: all 0.2s——display、height这类属性不可插值,会静默失效 - 检查 DevTools 的 Computed 面板,确认
transition-property在常态下就存在,而不是只在:hover里亮起 - 如果菜单用了
display: none/block控制显隐,transition完全不生效;改用opacity+visibility+pointer-events
@media (hover: hover)没包住transition,Safari会误触发
iOS Safari 在某些场景下(比如页面缩放后)会短暂模拟:hover,但此时若transition没被媒体查询包裹,它会被解析并尝试执行,导致Vue/React组件重渲染时出现意外抖动或闪退。
正确做法是把整个悬停行为(包括transition和:hover规则)一起放进能力检测中:
@media (hover: hover) and (pointer: fine) {
.nav-item {
transition: opacity 0.2s ease;
}
.nav-item:hover {
opacity: 0.8;
}
}
- 单独写
@media (hover: none)清空样式不可靠——很多安卓浏览器误报hover: hover,反而漏掉真实触屏设备 - 不要用
max-width或UA判断设备类型,Surface Pro、iPad Pro宽度超1000px但支持悬停 - Tailwind CSS v3.3+、Bootstrap 5.3+ 默认已做这层包裹,但自定义构建或老版本需手动补上
移动端根本没有:hover持续状态,:active必须补上
触摸设备不支持持续悬停,iOS Safari 甚至默认禁用:active,导致用户点下去毫无反馈,第一反应是“点歪了”。这不是加个cursor: pointer就能解决的。
- 给按钮类加
cursor: pointer或监听touchstart,才能激活:active伪类 - 关键操作按钮建议加轻量
tap反馈:transform: scale(0.95),持续时间≤150ms - 别在媒体查询里清空
:focus样式——键盘用户和屏幕阅读器依赖这个焦点路径 - 纯CSS多级下拉在真机上基本不可用,必须用JS控制
is-open类并同步ARIA状态
父容器overflow:hidden裁切了动画区域
固定定位的导航项(如右下角悬浮菜单)常因最近的非static祖先设置了overflow: hidden,导致box-shadow或transform移出部分被直接剪掉——不是没动画,是被“砍”了。
- 检查
position: relative或position: absolute的父容器,删掉它的overflow: hidden - 若必须保留清浮动,改用
display: flow-root - Safari下仍糊边?可退而求其次用
filter: drop-shadow(),它绕过盒模型限制,但不支持inset - 高DPI屏(iPhone Retina、安卓旗舰)对小数敏感,
box-shadow所有值必须用整数,模糊半径至少4px
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











