水波纹效果需用绝对定位伪元素或JS创建的临时节点,锚定点击坐标并以radial-gradient+scale实现扩散动画。关键在动态计算圆心偏移、避免布局干扰、精准监听transitionend、控制并发与性能优化。

水波纹效果的核心是 radial-gradient 动态覆盖
点击时在鼠标位置生成一个从透明到不透明的圆形渐变,再用 transform: scale() 让它向外扩散。关键不是“画个圆”,而是让这个圆始终锚定在点击坐标,且不干扰原有布局——所以得用 position: absolute + pointer-events: none 的伪元素或临时 DOM 节点。
常见错误是直接在目标元素上加 background-image: radial-gradient(...) 并试图动画 background-size,这会导致整个背景重绘、性能差,且无法精确定位圆心。
- 必须用
getBoundingClientRect()算出点击点相对于目标元素左上角的偏移(clientX - rect.left) - 径向渐变的圆心要写成
circle at Xpx Ypx,X/Y 是相对父容器的像素值,不是百分比 - 初始
scale(0)要配合opacity: 0,否则缩放前会闪一下
用 JS 创建水波纹节点比 :hover 伪类更可控
伪类做不到动态定位圆心,也难以控制多个水波纹并发(比如快速连点)。JS 创建临时 <span></span> 或 <div> 是主流做法,每个点击生成一个独立节点,加完动画后自动 <code>remove()。
注意:不要用 document.createElement('div') 后 append 到 body,这样会脱离目标元素的定位上下文;应该 append 到目标元素内部,并设 position: relative(如果还没设的话)。
立即学习“前端免费学习笔记(深入)”;
- 目标元素需有
position: relative,否则绝对定位的水波纹会以页面为基准偏移 - 水波纹节点样式必须含:
position: absolute; border-radius: 50%; pointer-events: none; z-index: 1 - 动画结束监听用
element.addEventListener('transitionend', ...),别用setTimeout,避免时间不准导致残留节点
radial-gradient 颜色扩散的关键参数组合
颜色扩散不是靠改渐变色 stops,而是靠同时缩放圆半径和降低透明度衰减速度。典型写法是:radial-gradient(circle at Xpx Ypx, transparent 0%, #6366f1 40%, transparent 70%) —— 这里 40% 决定高亮区大小,70% 决定扩散边界,两者差值越大,“晕开”感越强。
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
如果只想要单色扩散(比如蓝色变淡),就别写多段 stop,用 transparent 0%, #6366f1 30%, transparent 60% 更干净。硬塞 rgba(99, 102, 241, 0.8) 没意义,因为透明度由渐变控制更自然。
- 起始色必须是
transparent,否则圆心会有一块实心点 - 不要用
%表示圆心位置(如at 50% 50%),那会固定在中心,失去点击定位能力 - 渐变尺寸不用设
background-size,靠transform: scale()控制扩散范围更高效
兼容性与性能陷阱:Safari 和低配设备上的表现
Safari 对 radial-gradient 中带变量的 at 位置支持不稳定,尤其当 X/Y 是小数时可能偏移 1px;另外,大量并发水波纹节点(>5 个/秒)在低端安卓机上容易卡顿,因为每个都触发 layout + paint。
解决方案不是砍功能,而是加限制:用节流控制最小间隔(如 300ms),并给水波纹加 will-change: transform 提前告知浏览器要动画。但别滥用——只加在真正要动的节点上,否则内存占用飙升。
- 避免在
:active里用background模拟水波纹,iOS Safari 不触发 :active 伪类 - 不要用
filter: blur()做扩散,模糊会严重拖慢渲染帧率 - 测试时务必关掉 Chrome 的“paint flashing”,否则误判重绘区域
实际最难调的是圆心坐标的像素对齐和动画时长匹配:scale(3) 配 300ms 看着自然,但若目标元素有 border-radius,水波纹边缘可能被裁切——这时候得把水波纹节点的 overflow: hidden 去掉,或者提前算好最大扩散半径并设 min-width/min-height。

















