悬停波纹必须用radial-gradient或clip-path实现,:before伪元素无法响应鼠标坐标;radial-gradient需动态设置background-position和background-size,clip-path需注意兼容性与缩放偏移;移动端须监听touchstart/pointerdown并重置状态。

链接悬停时波纹从点击点扩散?:before做不到,得用radial-gradient或clip-path
纯:before伪元素无法响应鼠标位置生成以光标为中心的径向波纹——它没有坐标感知能力。真要“从鼠标点扩散”,必须用background-image: radial-gradient()配合background-position动态设置,或者用clip-path: circle()配transform-origin。用:before只能做固定中心(比如居中)的波纹,且需手动控制尺寸和过渡。
- 固定中心波纹:把
:before设为绝对定位、宽高覆盖父元素,transform: scale(0)初始态,transition: transform 0.4s,悬停时transform: scale(1) - 但这样波纹永远从中间炸开,和鼠标位置无关
- 若强行用
left/top定位:before再配合transform: scale(),会因布局流干扰、定位基准不一致导致错位,尤其在行内链接里极易偏移
radial-gradient实现鼠标点触发波纹的关键三步
核心是把背景渐变当“波纹层”,用background-position锚定鼠标坐标,再靠background-size控制扩散半径。必须搭配background-repeat: no-repeat和background-origin: padding-box避免重复和偏移。
- HTML里给
<a></a>加class="ripple",CSS中设position: relative(为后续JS定位铺垫) - CSS初始态:
background-image: radial-gradient(circle, rgba(0,0,0,0.2) 0%, transparent 70%);background-size: 0 0;background-position: center;transition: background-size 0.5s, background-position 0s - JS监听
mouseenter,读取e.offsetX/e.offsetY,设el.style.backgroundPosition = `${e.offsetX}px ${e.offsetY}px`,再设el.style.backgroundSize = '300px 300px'(值越大波纹越远)
为什么不用clip-path: circle()?兼容性与性能差异
clip-path: circle()做波纹动画更简洁(直接改circle(0 at X Y)),但IE全系不支持,Safari旧版有渲染闪烁问题。Chrome/Firefox下clip-path动画性能略优于radial-gradient(GPU加速更稳定),但radial-gradient在缩放/高DPI屏上边缘更平滑。
- 若项目需兼容 Safari 13.1 以下或 iOS 13.3 以下,避开
clip-path动画 -
clip-path在transform: scale()容器内行为异常,父级有缩放时波纹中心会偏移 - 用
clip-path时,transition必须写全:clip-path 0.4s cubic-bezier(0.4, 0, 0.2, 1),省略贝塞尔曲线会导致 Chrome 下卡顿
移动端点击无波纹?别漏掉touchstart和pointer-events
移动端默认不触发mouseenter,只认touchstart或pointerdown。且部分安卓浏览器对:hover支持弱,纯CSS方案在触摸设备上基本失效。
立即学习“前端免费学习笔记(深入)”;
- 必须同时监听
touchstart和pointerdown(iOS Safari 需touchstart,Chrome Android 推荐pointerdown) - 给
<a></a>加style="pointer-events: auto",防止父容器pointer-events: none阻断事件 - 波纹动画结束后记得重置
background-size为0 0,否则下次悬停会从上次结束尺寸开始,造成“越点越大”现象
offsetX/Y的稳定性——这些地方一错,波纹就飘到链接外边去了。










