box-shadow hover 卡顿因重排重绘,应改用 transform + 精简 box-shadow 并指定过渡属性,配合 will-change 或 translateZ(0) 触发 GPU 加速,移动端用 focus-within 或 touch 事件模拟。

box-shadow hover 为什么看起来“卡”
直接写 transition: all 0.3s 看似合理,但 box-shadow 的数值变化(比如从 0 0 0 0 rgba(0,0,0,0) 跳到 0 4px 12px -2px rgba(0,0,0,0.15))会触发浏览器重排+重绘,尤其阴影模糊半径(第三个值)突变时,GPU 渲染不连贯,人眼就感觉“硬”“跳”。
用 transform + filter 替代部分 shadow 效果
真正平滑的过渡依赖硬件加速属性,transform 和 filter 是首选。把“抬升感”交给 transform: translateY(-2px),把“柔化感”交给 filter: blur(1px)(慎用,仅小范围),而 box-shadow 只保留基础、低开销的投影:
- hover 前:只用
box-shadow: 0 1px 3px rgba(0,0,0,0.08) - hover 时:叠加
transform: translateY(-2px)+box-shadow: 0 4px 12px -2px rgba(0,0,0,0.15) - 务必给容器加
will-change: transform(或transform: translateZ(0))提前触发 GPU 层
只过渡 box-shadow 的特定维度
如果必须用 box-shadow 动画,别用 all,明确指定要过渡的属性,避免意外触发其他 CSS 变化:
card {
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
transition: box-shadow 0.25s cubic-bezier(0.2, 0.8, 0.2, 1),
transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
}
card:hover {
box-shadow: 0 4px 12px -2px rgba(0,0,0,0.15);
transform: translateY(-2px);
}
注意:cubic-bezier(0.2, 0.8, 0.2, 1) 比 ease 更柔和,减少初段突兀感;-2px 的 spread-radius(第四个值)能收紧阴影边缘,视觉上更“收得稳”。
立即学习“前端免费学习笔记(深入)”;
移动端 hover 失效?补一层 focus-within 或 JS 模拟
纯 CSS :hover 在触摸设备上不可靠。若卡片可点击,用 :focus-within 更稳妥;若需精确控制,监听 touchstart + touchend 切换 class:
.card {
transition: box-shadow 0.2s, transform 0.2s;
}
.card.active,
.card:focus-within {
box-shadow: 0 4px 12px -2px rgba(0,0,0,0.15);
transform: translateY(-2px);
}
关键点:不要等用户松手才还原,touchend 后立刻移除 active,否则阴影会卡住;iOS Safari 对 filter: blur() 支持差,优先用 transform + 精简 box-shadow。










