设计稿里按钮按下去,要从指尖散开一圈浅色波纹。用背景图加 transition 做了一版,波纹总是从正中间冒出来,点边角的时候很假,动画还带点拖影。

伪元素加缩放是最轻的做法

按钮设成相对定位,加上 overflow: hidden,再用 ::after 铺一个圆,初始 transform: scale(0)、opacity 0.4。点击时加个类,改成 scale(1)、opacity 0,配 0.6 秒的缓动。整个过程只动 transform 和 opacity,浏览器走合成层,几十个按钮一起动也不掉帧。

点击位置靠 CSS 变量传进去

监听 click,拿到事件对象的 offsetX 和 offsetY,把值写进元素的行内样式,变量名取 --x、--y。伪元素里 left 和 top 引用这两个变量,再各减掉半径。这样波纹从指下开始扩,不是从中心。键盘触发的回车事件没有坐标,取元素中心兜底。

别用宽度撑开

改 width 和 height 会触发重排,动画期间每一帧都要重新算布局,低端机直接掉到十几帧。缩放不影响布局,半径按按钮对角线的一半算一次就够,写死 200 像素也能覆盖大多数尺寸。圆角按钮记得同步 radius,不然扩散边缘会被裁。

一圈结束记得收拾

动画结束用 animationend 或 setTimeout 把类去掉,否则连点几次会叠好几层。用伪元素就不必建 DOM,改个类名即可,比 append 一个 span 干净。定时器要在组件卸载时清掉,不然报错时动画永远停不下来。

深色背景上的波纹要换色

白色波纹铺在深色按钮上,透明度 0.4 太亮,看着像一块污渍。深底改成白色低透明度,浅底用黑色低透明度,比例都往下压。品牌色按钮就用白色叠一层,别用同色系的深色,扩开时边界看不清。多主题站点,把颜色写进变量,跟着主题走。

触摸屏上要区分点击和滑动

手指按下滑动去滚动列表,也会触发 click,波纹跟着冒出来,看着很乱。移动端改用触摸事件,记录按下的坐标,抬起时判断位移超过 10 像素就不加波纹。桌面端保留 click,两套逻辑分开写,别互相干扰。

波纹好不好看,八成取决于起点对不对。坐标传进去,剩下只是缓动曲线的微调。