纯css无法实现真正“缓缓扩散”的光晕效果,因:active状态瞬时消失导致transition反向执行;必须用@keyframes定义单向动画,并配合animation-fill-mode:forwards锁定结束帧,且需js动态添加类或创建定位元素以确保触发与中心对齐。

直接用 box-shadow 配合 :active 或 @keyframes 就能实现,但纯 CSS 实现“缓缓扩散”必须用动画,:active 只能触发瞬时效果,撑不起“缓”字。
为什么 :active 加 transition 不行?
因为 :active 状态只在鼠标按下/触摸期间存在,松开就立刻消失——你没法让光晕“从点击点开始、持续 300ms 向外扩散再淡出”。transition 在状态退出时会反向执行(比如阴影缩回),这和“扩散后自然消失”逻辑冲突。
常见错误现象:button:active { box-shadow: 0 0 0 0 rgba(0,0,0,0.2); transition: box-shadow 0.3s; } —— 松手瞬间阴影往回收,像被吸回去,不是扩散感。
- 真正需要的是单向、不可逆的动画:按下即触发,播完即停
- 必须用
@keyframes定义从0px到30px的模糊半径增长 + 透明度衰减 - 动画要绑定在
:active上,但得用animation-fill-mode: forwards锁住结束帧(否则播完立刻清空)
怎么写一个靠谱的扩散光晕动画?
核心是两层叠加:box-shadow 控制光晕大小和模糊,opacity 控制淡出。不能只调 box-shadow 的 rgba 透明度,否则动画中间帧会发虚(浏览器渲染问题)。
@keyframes ripple {
0% {
box-shadow: 0 0 0 0 rgba(66, 133, 244, 0.6);
opacity: 1;
}
100% {
box-shadow: 0 0 0 24px rgba(66, 133, 244, 0);
opacity: 0;
}
}
- 起始
box-shadow半径为0,但模糊值(第三个0)要设成小正数(如2px),否则动画第一帧看不见光晕边缘 - 结束帧必须把
rgba的 alpha 设为0,不能靠opacity: 0单独控制——否则光晕残留残影 - 动画时长建议
0.35s~0.45s,太快像闪,太慢拖沓
按钮上怎么正确绑定这个动画?
关键在触发时机和样式隔离:不能写在 button 默认态,也不能只靠 :active——移动端 touch 事件不触发 :active,且动画需兼容 hover 按下反馈。
- 给按钮加
class="ripple-btn",用 JS 监听click或touchstart,动态添加class="ripple-effect" - CSS 写
.ripple-btn.ripple-effect { animation: ripple 0.4s ease-out; } - JS 里播完动画后用
animationend事件移除 class,避免重复点击堆叠动画 - 如果不用 JS,退而求其次:只支持鼠标设备,用
button:active { animation: ripple 0.4s forwards; },但 iOS Safari 会失效
最易被忽略的一点:光晕中心必须对准点击位置。纯 CSS 无法获取点击坐标,所以真要“从指尖/鼠标处发散”,必须用 JS 创建 span 元素并定位——但多数场景下,居中扩散已够用。别为了像素级精准,硬上 canvas 或复杂坐标计算。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











