实现按钮水波纹需满足三大前提:按钮设position: relative、容器加overflow: hidden、伪元素含content: ""/position: absolute/border-radius: 50%;transition须精确声明transform和opacity,配合touch事件手动处理及动态CSS变量定位。

用 CSS transition 实现按钮水波纹,关键不是“加动画”,而是让浏览器有“变化过程”可渲染——很多效果一闪而过,是因为样式变更和 DOM 插入挤在同一个渲染帧里,transition 根本没机会触发。
必须满足的三个前提条件
缺一不可,否则波纹不会动:
-
按钮需设
position: relative:伪元素(如::after)才能以按钮为定位基准,否则会相对于body偏移 -
按钮容器加
overflow: hidden:防止波纹放大后溢出圆角或边界,这是视觉“干净”的基础 -
伪元素必须含
content: ""、position: absolute、border-radius: 50%:三者缺一,就不是圆形,也定不了位
transition 写法要精准,不能偷懒
只写 transition: all 是常见错误,会导致意外重排或 Safari 渲染空白帧:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 正确写法:
transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.4s - 初始状态设为:
transform: translate(-50%, -50%) scale(0); opacity: 0.3 - 激活态(如
:active::after)改为:transform: translate(-50%, -50%) scale(3); opacity: 0 - 缓动函数推荐
cubic-bezier(0.25, 0.46, 0.45, 0.94),比ease-out更接近真实水波衰减感
移动端必须手动接管 touch 事件
仅靠 :active 在 iOS Safari 和多数安卓 WebView 中会失效或延迟:
- 给按钮加
touch-action: manipulation,禁用双指缩放判断 - 监听
touchstart(不是click),并立即调用e.preventDefault()(若无需滚动) - 坐标计算必须用
e.touches[0].clientX和button.getBoundingClientRect()相减,不能直接用e.clientX - 动态设置 CSS 自定义属性,如
button.style.setProperty('--x', x + 'px'),CSS 中用left: var(--x)定位
避免多点击堆积和错位
连续点击时旧波纹未结束,新波纹就覆盖上去,看起来混乱:
- 每次触发前清空上次位置:
button.style.removeProperty('--x'); button.style.removeProperty('--y') - 伪元素上加
pointer-events: none,防止遮挡后续点击 - Safari 下建议加
will-change: transform(动画开始时设置,结束时移除),解决首帧空白问题 - 若按钮有
disabled状态,JS 中需提前 return,跳过波纹逻辑

















