伪元素波纹动画用::after而非::before,因其层叠顺序更靠上且易配合z-index控制;需同时动画transform和opacity,使用Material Design缓动函数;点击坐标需JS动态计算;移动端需添加cursor:pointer、touch-action等兼容样式。

伪元素波纹动画为什么用 ::after 而不是 ::before
因为 ::before 默认渲染在内容底层,波纹容易被文字或子元素遮挡;::after 在默认层叠顺序中更靠上,配合 z-index 更易控制。实际项目中若父容器已有 position: relative,直接给 ::after 设 position: absolute 就能精准覆盖点击区域。
transform: scale() 和 opacity 必须同时动画才自然
只缩放不渐隐,波纹会“硬停”在最大尺寸;只透明不缩放,看起来像淡入淡出而非扩散。关键点是两者共用同一 transition,且起始/结束状态严格对应:
button {
position: relative;
overflow: hidden;
}
button::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
background: rgba(0,0,0,0.15);
border-radius: 100%;
transform: translate(-50%, -50%) scale(0);
transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.4s;
}
button:focus::after,
button:active::after {
transform: translate(-50%, -50%) scale(3);
opacity: 0;
}
注意:cubic-bezier(0.25, 0.46, 0.45, 0.94) 是 Material Design 推荐的缓动,比 ease-out 更有“弹出感”。
点击坐标不准?必须用 JS 动态设置 top/left
纯 CSS 无法读取鼠标位置,所以固定 top: 50%; left: 50% 只适用于居中触发(如圆形按钮)。真实场景需 JS 计算点击偏移:
- 监听
mousedown(不是click,避免延迟) - 用
e.clientX - rect.left算出相对于按钮左上角的 X 坐标 - 动态设
style.setProperty('--x', x + 'px'),CSS 中用left: var(--x) - 别忘了
transition要写在伪元素上,JS 只负责初始定位
移动端点击无响应?缺了 cursor: pointer 和 touch-action
iOS Safari 默认对非可点击元素禁用 :active 伪类,导致波纹不触发。必须加:
button {
cursor: pointer;
-webkit-tap-highlight-color: transparent;
touch-action: manipulation;
}
其中 touch-action: manipulation 允许浏览器优化触摸反馈,避免 300ms 延迟;-webkit-tap-highlight-color 去掉 iOS 点击高亮,否则会和波纹叠加出奇怪色块。
真正难的是处理不同尺寸按钮的波纹半径适配——scale(3) 在小按钮上可能溢出,在大卡片上又显小,得根据 clientWidth 动态算最大缩放值。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











