需为每层伪元素设置递增的 animation-delay(如0s、0.2s、0.4s),统一 animation-duration(推荐2s+),使用 linear 缓动,父容器设 position: relative,并配合 transform: translatez(0)、backface-visibility: hidden 等优化渲染。

伪元素层级叠加时动画不同步怎么办
多层 ::before 和 ::after 做波浪扩散,最常遇到的问题是各层动画起始时间一致、看起来像“叠在一起炸开”,而不是逐层向外荡开。根本原因是没加 animation-delay,或者延时值太小、单位写错(比如用了 ms 却漏了数字)。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 每层延时递增,推荐从
0s开始,以0.2s为步长:第一层animation-delay: 0s,第二层0.2s,第三层0.4s - 动画时长(
animation-duration)建议统一设为2s或更长,否则延时还没起效,动画就结束了 - 别用
ease-in-out一类缓动——它会让波峰出现时间偏移,破坏“同心圆扩散”的节奏感,老老实实用linear - 如果某层突然消失或错位,检查是否忘了给父容器设
position: relative,否则伪元素的absolute定位会相对于整个页面偏移
CSS transform scale 动画卡顿或边缘锯齿
用 transform: scale() 模拟波浪扩散时,放大过程中容易出现模糊、闪烁甚至卡在某一层不动,尤其在 Safari 或低端安卓机上明显。这不是代码写错了,而是浏览器对非整数缩放的光栅化处理不一致。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 强制开启硬件加速:给每一层伪元素加上
transform: translateZ(0)或will-change: transform - 避免从
scale(0)直接起步——有些浏览器渲染引擎对 0 缩放有优化跳过行为,改用scale(0.01) - 如果波纹边缘发虚,加
backface-visibility: hidden,同时确保伪元素有明确背景色或border(哪怕border: 1px solid transparent) - 别用
%值做width/height配合scale,二者叠加会导致计算误差放大;统一用px或rem定死初始尺寸
如何控制波浪只朝一个方向扩散(比如只向下)
默认用 scale() 是中心点等比放大,但实际项目中常需要“水滴落点式”效果:从顶部开始,波纹只向下蔓延,上面不留痕迹。这时候不能只靠 transform-origin 调整锚点,还得配合裁剪和定位逻辑。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 把伪元素的
transform-origin设为top center,再配合scaleY()单独控制纵向拉伸 - 父容器加
overflow: hidden,伪元素本身用top: 0+height: 0起始,动画中只变height和transform: scaleY() - 如果要保留“弧形”而非直线扩散,改用
clip-path: inset(0 0 100% 0)配合animation-timing-function: cubic-bezier(.33,.9,.56,.14)控制裁剪进度 - 注意:Safari 对
clip-path的inset()支持较晚(iOS 15.4+),老版本得回退到mask+ SVG,但那样就得额外引入 base64 或内联 SVG
移动端 touch 触发后波浪不响应或延迟高
点击按钮触发波浪动画,在 iOS 上经常点下去没反应,或要等半秒才动一下。不是 JS 绑定问题,而是 CSS 动画被浏览器的“点击延迟”或“被动事件监听”机制阻塞了。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 给触发元素加
touch-action: manipulation,告诉浏览器这个区域只做轻触反馈,不用等 300ms 判断是否双击 - 别用
:active伪类直接驱动动画——移动端:active持续时间极短且不可靠,改用 JS 添加 class(如.is-rippling),再用 CSS 监听该 class - 动画启动用
animation-play-state: running切换,而不是反复删加 class;否则快速连点会因 class 移除太快导致动画中断 - 如果用
requestAnimationFrame手动控制帧,务必在touchstart里调用,别等到click,后者在 iOS 上可能被吞掉
真正麻烦的不是写几层 ::before,而是每层的 transform-origin、animation-delay、will-change 和父容器 overflow 必须严丝合缝。少一个 relative,或者延时差了 0.05s,波纹就不是“荡开”,而是“崩开”。










