纯css无法实现点击哪就从哪扩散的波纹效果,因:active无坐标信息、@keyframes无法读取clientx/clienty,所有纯css方案均固定从中心或左上角触发;必须用js计算点击坐标动态控制::after伪元素的定位、缩放与淡出,并配合position:relative、pointer-events:none及animationend清理等完整机制。

纯 CSS 实现不了真正点击哪就从哪扩散的波纹效果——:active 没有坐标信息,@keyframes 无法读取 clientX/clientY,所有“纯 CSS 波纹”教程里波纹固定从中心或左上角炸开,不是真实交互反馈。
为什么 :active + transition 不行
原因很实在::active 状态在松手瞬间就结束,通常不到 10ms;而一个可感知的波纹动画至少需要 350ms。你写 active:scale-105 或 :active { transform: scale(1.2) },结果就是点下去没反应,或者动画播到一半突然回弹。更关键的是,它完全不知道你点在按钮的哪个像素位置。
-
:active在 iOS Safari 默认被禁用,需额外加touch-action: manipulation或cursor: pointer才可能触发 - 即使启用,
left/top无法在:active中动态计算,只能写死 - 连续点击时,多个
:active状态重叠,JS 无法清理旧动画,渲染层会堆积残留
必须用 ::after + JS 动态定位
核心是让 ::after 成为波纹载体:不占 DOM、支持硬件加速、能用 pointer-events: none 避免拦截后续点击。但前提是按钮本身得设 position: relative,否则 ::after 的 absolute 定位会相对于 body 偏移,点哪都从页面左上角开始炸。
- 按钮必须加
position: relative(Tailwind 就是relative类) -
::after要设content: ""、position: absolute、border-radius: 50%、z-index: -1、pointer-events: none - 圆心定位统一用
transform: translate(x, y),别混用top/left—— Safari 对混合定位合成不稳定 - 每次点击前先清掉旧值:
button.style.setProperty('--x', '0px'),否则新波纹从上一次位置起始
Safari 和移动端的硬坑怎么绕
iOS Safari(尤其 15.4 以下)对 ::after + transform: scale() 有重绘 bug:波纹卡顿、闪烁、甚至不触发。这不是加 -webkit- 能解决的,得靠具体兜底手段。
- 伪元素动态加
will-change: transform(别写在常态 CSS 里,JS 点击时才 set) - 移动端必须监听
touchstart,取e.touches[0].clientX,click在 iOS 上有 300ms 延迟且坐标不准 - 父按钮加
overflow: hidden,否则波纹放大后会撑出圆角边界,Safari 会裁切动画轨迹 - 动画结束必须监听
animationend事件并调用element.remove(),不能靠setTimeout,真机上容易残留
真正难的从来不是写那几行 @keyframes,而是坐标计算的边界约束、Safari 的合成层控制、以及连点时的动画状态清理——漏掉任意一个,真机上就大概率失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











