波纹效果需用javascript捕获点击坐标并动态设置伪元素left/top,配合@keyframes实现scale与opacity动画;禁用box-shadow模拟,每次点击应新建波纹元素并自动移除。

波纹效果的本质是 CSS 动画叠加伪元素
纯 HTML 无法实现波纹,必须配合 CSS;核心思路是用 ::after 伪元素在点击位置生成圆形遮罩,再通过 transform: scale() 和 opacity 动画扩散。不能依赖 :active 状态,因为它不记录点击坐标,必须用 JavaScript 捕获 clientX/clientY 并动态设置伪元素的 left/top。
用 JavaScript 动态计算波纹圆心位置
直接写死 left: 50% 会导致波纹总从按钮中心开始,和实际点击点不符。正确做法是在 click 事件里获取相对于按钮左上角的偏移:
- 用
getBoundingClientRect()获取按钮位置 - 用
event.clientX - rect.left算出 X 偏移 - 用
event.clientY - rect.top算出 Y 偏移 - 把这两个值设为伪元素的
left和top(注意单位是px)
别忘了给伪元素加 position: absolute 和 pointer-events: none,否则会干扰后续点击。
CSS 动画必须用 @keyframes 而非 transition
transition 只能响应属性变化,但波纹需要从 0 缩放至足够大(比如 scale(4)),且需精确控制透明度衰减。用 @keyframes 更可控:
@keyframes ripple {
0% { transform: scale(0); opacity: 0.7; }
100% { transform: scale(4); opacity: 0; }
}
关键细节:
- 动画时长建议设为
600ms左右,太短显得突兀,太长延迟感强 - 必须加
transform-origin: center,否则缩放中心会偏移 - 伪元素初始
width/height设为0,靠scale()撑开
兼容性与性能陷阱:不要用 box-shadow 模拟波纹
有人尝试用多层 box-shadow 实现扩散效果,这在 Chrome 上可能勉强可行,但在 Safari 和旧版 Edge 中表现极不稳定,且大量阴影会显著拖慢滚动和动画帧率。真实项目中应坚持伪元素 + transform 方案。
另一个常见错误是没清空上一次波纹:每次点击都要先移除已存在的波纹元素或重置伪元素状态,否则多个波纹会叠加卡顿。最稳妥的做法是每次点击都新建一个 span 或 div 作为波纹载体,动画结束后自动 remove()。
波纹的视觉合理性取决于按钮尺寸和圆角——如果按钮带 border-radius,波纹扩散到边缘会被裁剪,这是正常行为,无需强行适配;强行用 overflow: hidden 反而可能遮住动画起始帧。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











