纯 css 的 :active 做不出真实水波纹,因其无法获取点击坐标,伪元素圆心固定于中心;必须用 getboundingclientrect() 计算相对坐标,结合 css 自定义属性与 ::after 实现精准定位的水波纹效果。

为什么纯 CSS 的 :active 做不出真实水波纹
因为 :active 只能触发全局状态,无法知道你点在左上角还是正中心。写 button:active::after 永远从按钮中心扩散,哪怕你用 radial-gradient(circle at center),圆心也固定死——这不是 bug,是 CSS 机制限制。更糟的是,Safari 对 :active 中动态更新 clip-path 或 background-position 支持极差,连基本动画都可能不触发。
必须用 getBoundingClientRect() 算点击坐标
所有“点哪波纹就从哪起”的效果,都依赖这个 API。不调它,e.clientX - e.target.offsetLeft 在滚动页、缩放视口、父容器带 transform 时必错位。
- 先执行
const rect = btn.getBoundingClientRect() - 再算
const x = e.clientX - rect.left和const y = e.clientY - rect.top - 这两个值才是按钮内部的像素坐标,可直接塞进
left/top或 CSS 自定义属性
用 CSS 自定义属性 + ::after 最轻量
不用每次新建 span,复用伪元素,性能好、DOM 干净。关键在 JS 只设坐标,动画仍由 CSS 驱动。
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
- 按钮必须设
position: relative和overflow: hidden -
::after要有content: ""、position: absolute、border-radius: 50%、pointer-events: none - JS 动态写入:
btn.style.setProperty('--x', `${x}px`)、btn.style.setProperty('--y', `${y}px`) - CSS 里用
left: var(--x); top: var(--y); transform: translate(-50%, -50%) scale(0),激活时改scale(1)
移动端必须监听 touchstart,不是 click
click 在 iOS 上有 300ms 延迟,且某些快速连点会丢失事件。只绑 click,用户点完没反馈,体验直接掉档。
- 同时监听
touchstart和mousedown,用e.touches ? e.touches[0] : e统一取坐标 - 加
-webkit-tap-highlight-color: transparent关掉 Safari 默认点击高亮 - 别忘了给按钮加
cursor: pointer,否则部分 Android 浏览器不触发touchstart
真实水波纹的复杂点不在动画本身,而在坐标计算的鲁棒性——滚动、缩放、嵌套 transform、iframe 内点击,每种场景都要重新验证 getBoundingClientRect() 返回值是否可用。很多人卡在“明明写了 left/top 却偏了”,其实是漏掉了 rect 之后那一行减法。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










