原生 Bootstrap 不支持 ripple 效果,因其 CSS 组件无动态创建和定位圆形波纹元素的逻辑;需通过 JS 监听点击事件、计算坐标、插入带动画的 span,并用 transform/opacity 实现高性能扩散效果。

为什么原生 Bootstrap 不支持 ripple 效果
Bootstrap 官方 CSS 组件(包括 btn 类)本身不包含涟漪(ripple)动画逻辑——它依赖纯 CSS 的 :active 状态或 JavaScript 手动注入元素。所谓“水波扩散”效果需要动态创建一个圆形 span 元素,从点击位置向四周缩放并淡出,而 Bootstrap 的样式层对此完全无感知。
用纯 CSS + 少量 JS 实现可复用的 ripple 效果
核心思路是监听按钮的 click 事件,在点击坐标处插入一个带 ripple 类的 span,再靠 CSS 控制其 transform 和 opacity 动画。关键点在于定位计算和 class 清理时机:
-
position: relative必须加在按钮上(否则absolute子元素无法以按钮为参考系定位) - 点击坐标需转为相对于按钮左上角的偏移:
clientX - button.getBoundingClientRect().left - 动画结束后必须手动
remove()ripple 元素,否则 DOM 泄漏 - 推荐给 ripple 元素加
pointer-events: none,避免干扰后续点击
示例 JS 片段(可绑定到所有 .btn):
document.querySelectorAll('.btn').forEach(btn => {
btn.addEventListener('click', function(e) {
const rect = this.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const ripple = document.createElement('span');
ripple.className = 'ripple';
ripple.style.left = `${x}px`;
ripple.style.top = `${y}px`;
this.appendChild(ripple);
setTimeout(() => ripple.remove(), 600);
});
});
配套的 ripple CSS 动画怎么写才不卡顿
动画性能取决于是否触发重排(reflow)。必须用 transform 和 opacity(它们走 GPU 合成),禁用 width/height 或 top/left 动画。同时要设 border-radius: 50% 和足够大的初始尺寸(否则扩散感弱):
.btn {
position: relative;
overflow: hidden;
}
.ripple {
position: absolute;
border-radius: 50%;
background: rgba(255,255,255,0.6);
transform: scale(0);
pointer-events: none;
animation: ripple 0.6s linear;
}
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
注意:如果按钮有 border-radius(比如 .btn-rounded),ripple 圆形可能被裁切,此时需确保父容器 overflow: hidden 已启用(上面已加)。
移动端点击位置不准?别忘了 touch 事件
在 iOS / Android 上,click 事件的 clientX/clientY 可能因 300ms 延迟或缩放导致偏差。更稳妥的方式是监听 touchstart 并取 touches[0]:
- 用
e.touches && e.touches.length判断是否为触控事件 - 优先取
e.touches[0].clientX,fallback 到e.clientX - 记得同时监听
touchstart和click,兼顾桌面与移动
实际中,很多项目会直接用 pointerdown 事件统一处理(兼容性需查 PointerEvent 支持),但要注意 IE11 需 polyfill。
真正难的不是写出第一版 ripple,而是让多个连续点击不堆叠、不同尺寸按钮下圆心始终精准、缩放比例随按钮大小自适应——这些细节没封装进组件里,光靠 CSS 是压不住的。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











