css transition必须写在默认状态而非:hover中,否则无效;:hover与:active叠加易致动画异常;应精确声明transition-property,避免all;移动端需用touch-action或js增强:active兼容性。

transition写在:hover里根本不会生效
CSS transition 必须写在「触发前的状态」上,也就是默认状态(常态)的规则块里。写在 :hover 或 :active 里,浏览器压根不认——它只负责定义“从哪变到哪”,不是“在哪开始变”。
- 错误写法:
.btn:hover { color: red; transition: color 0.3s; }→ hover 进入瞬间没过渡,只有离开时可能有(且不可靠) - 正确写法:
.btn { color: black; transition: color 0.3s; } .btn:hover { color: red; } - 如果只想让进入有动画、离开没有,得用
transition-property+ 状态分离,但多数场景没必要这么拧巴
:active和:hover同时存在时的过渡冲突
点击按钮时 :active 和 :hover 常常同时匹配(尤其鼠标未移开就点击),这时两个伪类的样式会叠加,而 transition 只响应最终计算出的样式变化。容易出现“点下去颜色跳变”或“松开手才开始动”。
- 典型现象:按钮悬停变蓝,点击变红,但松开手后才从红慢慢回蓝,而不是立刻回蓝
- 原因:
:active的样式覆盖了:hover,而transition是基于元素最终 computed style 的差值计算的 - 解法:统一用
:hover控制悬停态,:active只做瞬时反馈(比如加个transform: scale(0.98)),并确保transition不包含transform或设极短时长(如transform 0.05s)
transition-property设太宽导致意外动画
很多人图省事写 transition: all 0.3s,结果鼠标一 hover,连 box-shadow、opacity、甚至 z-index(虽然无效)都试图过渡,页面发虚、卡顿、布局抖动全来了。
- 常见副作用:文字模糊(因 subpixel 渲染被触发)、滚动变卡(触发重绘)、图标位置微偏移
- 推荐只声明真正要动的属性:
transition: color 0.3s, background-color 0.3s, transform 0.2s - 注意
background是简写,会隐式触发background-image过渡(加载慢时白屏闪动),改用background-color更安全
移动端 touchstart 下 :active 不触发或延迟
iOS Safari 和部分安卓浏览器对 :active 支持有限:不点住不动可能不触发,或者有 300ms 延迟。单纯靠 :active 做点击反馈,在手机上基本不可靠。
立即学习“前端免费学习笔记(深入)”;
- 现象:
.btn:active { opacity: 0.7; }在 iPhone 上点一下毫无反应,或要点两下才生效 - 原因:浏览器把第一次触摸当 scroll 判断,抑制了 :active
- 务实解法:加
touch-action: manipulation到按钮上;更稳的是用 JS 监听touchstart/touchend切换 class,再对那个 class 写 transition
transition 就完事,关键在谁来管“起始态”、谁决定“哪些属性可变”、以及伪类叠加时浏览器到底按什么顺序算样式。这些地方一错,动画就断在半路,或者干脆不动。










