hover 配合 transition 实现属性变化的平滑过渡,需在非 hover 状态定义 transition;复杂动画则需 @keyframes + animation;常见失效原因包括 overflow 裁切、display 切换、伪类顺序错误及移动端无 hover 支持。

hover 配合 transition 实现平滑过渡
直接写 :hover 不会自动动起来,必须搭配 transition 才能产生动画效果。它控制的是「属性变化过程」,不是动画本身。常见写法是给原始状态加 transition,悬停时只改目标值:
比如让按钮背景色渐变:
.btn {
background-color: #007bff;
transition: background-color 0.3s ease, transform 0.2s ease;
}
.btn:hover {
background-color: #0056b3;
transform: scale(1.05);
}
注意点:
-
transition要写在非:hover的规则里(否则第一次悬停没效果) - 只对可动画的 CSS 属性生效,比如
color、opacity、transform、background-color(但不推荐用width/height,会触发重排) - 多个属性用逗号分隔,各自可指定不同持续时间与缓动函数
hover 配合 @keyframes 做复杂动画
当需要循环、多阶段或非线性运动(比如弹跳、抖动、路径移动),就得用 @keyframes + animation:
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-8px); }
}
.icon:hover {
animation: float 1.5s ease-in-out infinite;
}
关键区别:
-
animation是主动播放的,:hover只是触发开关 - 加
infinite才会循环;不加则只播一次 - 悬停离开后默认会立刻停止并跳回初始态,如需「自然收尾」得用
animation-fill-mode: forwards并配合animation-direction: normal等控制
hover 动画常见的失效原因
写了却没反应?大概率卡在这几个地方:
立即学习“前端免费学习笔记(深入)”;
- 父元素设置了
overflow: hidden,而动画中transform或position导致子元素被裁切 - 用了
display: none→block切换:这个不可过渡,改用visibility: hidden+opacity: 0组合 - 伪类层级被覆盖,比如
a:hover写在了a:visited后面,而链接已被访问过 - 移动端没有 hover(iOS Safari 默认不触发),需额外加
touchstart监听或用@media (hover: hover)做条件判断
性能与兼容性提醒
高频动画属性优先选 transform 和 opacity,它们走 GPU 加速,不会触发重排重绘。避免对 left、top、width 等布局属性做 hover 动画。
兼容性方面:
-
transition和animation在现代浏览器都支持,IE10+ 可用(但 IE10 不支持transform的某些写法) - 如果要支持 iOS Safari 旧版本,
transform需加-webkit-前缀,animation同理 - 用
will-change: transform可提前提示浏览器优化,但别滥用,可能引发内存开销
transition、什么时候必须上 @keyframes,以及是否值得为这点视觉反馈增加维护成本。










