多数情况下点击无波纹是因非表单元素未触发可激活状态,需加tabindex="0"或role="button",推荐直接使用语义化;波纹中心扩散实为transform-origin:center的视觉欺骗;动画卡顿需控制时长≤150ms或改用js控制类名;移动端延迟需viewport meta+touch-action:manipulation及-webkit-tap-highlight-color:transparent。

点击时波纹不出现,:active 伪类完全没反应
多数情况是元素没有触发“可激活”状态:HTML 中 <div>、<code><span></span> 等非表单元素默认无法获得 :active,除非加 tabindex="0" 或设为 role="button"。更稳妥的做法是直接用 <button></button> —— 它原生支持 :active,且语义正确、键盘可聚焦、无障碍友好。
另外检查是否被其他 CSS 覆盖:比如父级设置了 pointer-events: none,或自身有 user-select: none 但漏掉了 -webkit-tap-highlight-color: transparent(iOS Safari 下会遮盖波纹)。
波纹从点击位置中心扩散,不是鼠标/手指落点
:active 本身不提供坐标信息,纯 CSS 无法动态计算点击位置。所谓“中心波纹”其实是视觉欺骗:把伪元素 ::after 的 transform-origin 设为 center,再配合 scale 动画,看起来像从中心炸开。真要实现落点定位波纹,必须用 JavaScript 监听 click 或 touchstart,读取 clientX/clientY,动态创建带 left/top 的波纹元素。
如果坚持只用 CSS,可接受的折中方案是:
- 给容器设
position: relative - 用
button::after创建圆形伪元素,width/height设为固定值(如120px) -
transform-origin: center+transform: scale(0)初始态 -
button:active::after中改为transform: scale(1),配合transition
:active 波纹动画卡顿或一闪而过
根本原因是 :active 状态在鼠标松开或触控结束时立即消失,动画来不及播完。解决方案只有两个:
- 把动画时长控制在
150ms以内(人眼感知阈值),并用transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1)模拟 Material 波纹的缓入缓出 - 放弃
:active,改用 JavaScript 控制类名(如is-rippling),在setTimeout中延时移除,确保动画完整播放
注意:不要对 transform 和 opacity 外的属性(如 width、height)做过渡,会触发重排,导致掉帧。
移动端点击延迟导致波纹响应迟钝
iOS Safari 和部分安卓浏览器存在 300ms 点击延迟,:active 样式会等延迟结束后才生效。最简单解法是加 meta 标签:
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">并配合
touch-action: manipulation(作用于按钮本身)。
若仍需兼容老版本,可用 fastclick 库,或监听 touchstart 手动添加临时类 —— 但这已超出纯 CSS 范畴。
真正难处理的是 iOS 上 :active 在 <button></button> 上有时被系统高亮覆盖,必须加 -webkit-tap-highlight-color: transparent,且该声明需写在 :active 规则之外的同一选择器下才生效。











