transition必须写在默认状态而非:hover中,否则退出动画失效;伪元素需显式定义初始值;移动端无hover,需用媒体查询或js适配。

transition没写在默认状态,只写了:hover里
这是最常见也最隐蔽的问题。浏览器执行过渡动画,需要知道「从哪开始变」——这个「起点」必须在默认样式中声明transition。如果只在:hover里写transition: background-color 0.3s;,鼠标移出时,浏览器发现默认状态压根没过渡规则,就直接跳回原值,毫无动画。
正确做法是把transition写进非 hover 的基础选择器里:
button {
background-color: #007bff;
transition: background-color 0.3s ease; /* ✅ 这里必须有 */
}
button:hover {
background-color: #0056b3; /* ❌ 这里不用再写 transition */
}
记住:transition不是“告诉浏览器怎么进入 hover”,而是“告诉浏览器:只要这个属性变了,就按这个方式过渡”,无论变进去还是变出来。
过渡属性在默认态或 hover 态缺失具体值
即使transition写对了,如果某个属性在默认态是inherit、unset、auto,或干脆没声明,浏览器就无法计算起始值,过渡就会中断或失效。
-
height: 0→height: auto:不支持过渡(auto不是可插值数值) -
color: currentColor→color: #333:起始值不确定,可能跳变 -
transform: none→transform: translateY(-5px):没问题,none是合法初始值 -
opacity和transform最安全,优先用它们做动效
颜色过渡尤其容易翻车:别混用#ff0000和rgba(255,0,0,0.8),统一用rgba()或hsla()格式,确保起止值结构一致。
伪元素(::before / ::after)hover 动画退出卡顿
给伪元素加 hover 动画,比如下划线滑入、遮罩淡出,常出现“鼠标一走,效果直接消失”。根本原因是伪元素的默认态没设初始值,导致浏览器没有过渡上下文。
必须显式定义伪元素的起始状态:
a::after {
content: '';
display: block;
height: 2px;
background: #007bff;
transform: scaleX(0); /* ✅ 初始缩放为 0 */
transition: transform 0.2s ease; /* ✅ transition 也在默认态 */
}
a:hover::after {
transform: scaleX(1); /* ✅ 只改目标值 */
}
漏掉transform: scaleX(0)或opacity: 0这类初始声明,退出时就只能硬切。
移动端 hover 根本不触发,谈不上过渡
这不是 bug,是事实:iOS 和 Android 浏览器没有 hover 状态。轻点按钮只触发click或touchstart,:hover规则多数被忽略(Safari 偶尔模拟,但不可靠、不一致)。
依赖 hover 做核心交互会直接失效。真实方案只有两个:
- 用
@media (hover: hover) and (pointer: fine)媒体查询包裹 hover 规则,明确限定仅桌面精细指针设备 - 用 JS 监听
touchstart添加临时类(如.is-touched),再写.btn.is-touched对应样式,兼顾触控反馈
别指望纯 CSS 在手机上让 hover 过渡“生效”——它从源头就不存在。
过渡是否双向生效,不取决于:hover写了什么,而取决于「默认状态有没有声明transition + 起止值是否都具体可计算」。最容易被忽略的是伪元素初始值和移动端的交互模型差异。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











