transition 必须写在默认状态而非仅 :hover 中,否则移出时无动画;应放在基础样式里,搭配可动画化属性(如 opacity、transform)和明确缓动函数,避免使用 display、font-size 等无效属性。

transition 必须写在默认状态,不能只放 :hover 里
鼠标悬停时动画正常、移开却“啪”一下跳回——这是最常见问题,根源是 transition 被错误地只写在 :hover 选择器中。浏览器只在进入 :hover 时应用该规则,离开后规则失效,自然没有退出动画。
正确做法是把 transition 声明放在按钮的基础样式里(比如 .btn 或 button),确保它同时覆盖“进”和“出”两个方向:
.btn {
background-color: #4A90E2;
transition: background-color 0.3s ease-in-out;
}
.btn:hover {
background-color: #1E5799;
}
- 即使只改一个属性,也要保证基础态和悬停态都有明确值(例如
transform: scale(1)→scale(1.05)) - 如果基础态没设
transform,浏览器会从none开始过渡;移出时若没显式重置,可能残留计算值,导致行为不一致
只对可动画化属性用 transition,别碰 display 或 font-size
不是所有 CSS 属性都能过渡。只有「可动画化」的属性才支持 transition,否则会静默失败,你根本看不到效果。
推荐优先使用的属性(性能好、兼容稳):
立即学习“前端免费学习笔记(深入)”;
-
opacity、transform(触发 GPU 加速,首选) -
background-color、color、border-color -
width/height:能动,但会触发重排(layout),慎用 -
max-height:可用于展开/收起,但必须设具体数值(如0→200px),不能用auto
明确无效的属性(写了也白写):
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
-
display、z-index、font-size(虽部分浏览器能动,但易引发重排且行为不可靠) -
margin、padding:同理,尽量用transform替代位移
用 transform + opacity 组合比纯 background-color 更稳
纯背景色过渡在深色/浅色模式切换或高对比场景下容易显得生硬,而且 background-color 过渡在低端设备上可能有轻微卡顿。
更推荐组合使用 transform 和 opacity,它们天然触发硬件加速,动画更顺滑:
.btn {
opacity: 1;
transform: scale(1);
transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.25, 0.8, 0.25, 1);
}
.btn:hover {
opacity: 0.9;
transform: scale(1.03) translateY(-2px);
}
- 避免用
transition: all 0.3s—— 它可能意外触发动画(比如box-shadow每次重绘都算一次变化) - 缓动函数建议用
cubic-bezier(0.25, 0.8, 0.25, 1),比默认ease更有弹性感 - 如果按钮带文字,
opacity变化要小心:低于 0.8 可能影响可读性
JS 切换 class 时 transition 仍不生效?检查值是否已计算
用 JavaScript 通过 classList.toggle('dark') 切换主题类时,有时发现颜色没过渡——不是 CSS 写错了,而是浏览器还没来得及计算旧值。
典型场景:JS 直接改 style.backgroundColor,或快速连续 toggle 类,导致过渡被跳过。
- 确保目标元素在 JS 执行前已有明确的初始样式(不能靠继承或未声明的默认值)
- 如果手动设置内联样式,建议先读取一次
offsetHeight强制 reflow,让浏览器确认当前状态 - 暗色模式切换时,
background-color两边都必须是明确的颜色值(如#ffffff↔#121212),避免一边是transparent或initial
真正容易被忽略的是:transition 不是“自动感知变化”,它依赖浏览器能明确比较前后两个计算值。值模糊、未声明、或被更高优先级规则覆盖,都会让它静默失效。


















