涟漪点击按钮(Ripple Effect 水波纹 CSS + JS)
涟漪点击按钮 3 款:主色、描边、深色,点击时水波纹从手指落点扩散,JS 约 15 行、无任何依赖,适合按钮与卡片点击反馈场景。
效果演示(真实可交互)
Material Design 风格的涟漪反馈:点击按钮任意位置,一个半透明圆形水波会从手指落点扩散并淡出,让每一次点击都有「被响应」的感觉。演示区 3 款分别为主色渐变、描边、深色风格,水波颜色自动适配按钮底色。
点击任意位置,涟漪从点击处扩散 💧
完整代码
HTML:
<button class="ripple-btn">涟漪按钮</button>
CSS(涟漪关键样式):
.ripple-btn { position: relative; overflow: hidden; border: 0; padding: 13px 30px;
border-radius: 12px; background: linear-gradient(135deg, #6c8cff, #b388ff);
color: #fff; font-weight: 600; cursor: pointer; }
/* 涟漪本体:scale(0) 起飞,动画结束时 scale(1) 并透明 */
.ripple-ink {
position: absolute; border-radius: 50%;
background: rgba(255,255,255,.6);
transform: scale(0);
animation: ripple .6s ease-out forwards;
pointer-events: none; /* 不让水波拦截点击 */
}
@keyframes ripple { to { transform: scale(1); opacity: 0; } }
JS(约 15 行,零依赖):
document.querySelectorAll('.ripple-btn').forEach((btn) => {
btn.addEventListener('pointerdown', (e) => {
const rect = btn.getBoundingClientRect();
const size = Math.max(rect.width, rect.height) * 2.2; // 水波直径
const ink = document.createElement('span');
ink.className = 'ripple-ink';
ink.style.width = ink.style.height = size + 'px';
ink.style.left = e.clientX - rect.left - size / 2 + 'px';
ink.style.top = e.clientY - rect.top - size / 2 + 'px';
btn.appendChild(ink);
ink.addEventListener('animationend', () => ink.remove());
});
});
原理三步:pointerdown 取点击坐标 → 创建圆形 span 定位到该点 → 动画结束自动移除。描边与深色变体只需改 .ripple-ink 的 background 颜色(见演示区 .rp-* 系列)。
参数说明
| 参数 | 位置 | 说明 |
|---|---|---|
| 水波颜色 | .ripple-ink 的 background | 浅色按钮用深色水波,深色按钮用白色水波 |
| 扩散时长 | animation: ripple .6s | 300-800ms 皆可,太快没存在感 |
| 水波大小 | size = 宽高较大值 × 2.2 | 系数越大覆盖越广 |
| 触发事件 | pointerdown | 比 click 响应更快;移动端也支持 |
| 缓动 | ease-out | 先快后慢,符合物理直觉 |
兼容性与性能
- 使用原生
pointerdown事件,桌面与移动端统一,兼容所有现代浏览器 - 动画仅 transform 与 opacity,GPU 加速;每个水波动画结束后立即从 DOM 移除,不堆积节点
- 连点场景下水波最多同时存在 2-3 个,性能无忧
- 若需要更克制的反馈,可在
prefers-reduced-motion时直接禁用水波动画
常见问题
Q: 能商用吗? 可以。本组件为粤喵自研,免费商用无需署名。
Q: 水波颜色怎么和按钮对比更明显? 深色或彩色按钮用 rgba(255,255,255,.5-.7) 白波;白色或浅色按钮改用 rgba(0,0,0,.15) 或主题色半透明。
Q: 水波溢出按钮外了? 检查按钮是否有 overflow: hidden。水波是按钮的子元素,没有它就会画出边界,这是最常见的漏配。
Q: 想在卡片、列表项上也加涟漪? 直接把 .ripple-btn 替换成任意容器选择器即可,JS 逻辑完全通用,只需保证容器 position: relative; overflow: hidden。
许可与来源
- 许可证:自研原创 —— 粤喵自研原创,可免费用于个人与商业项目,无需署名。查看来源公示与许可清单
- 来源:粤喵团队原创自研(从效果思路到代码实现均为独立完成,未直接复制第三方代码)
- 首次发布:2026-09-01 · 最近更新:2026-09-01
- 修改日志:2026-09-01 首次发布;2026-09-13 补充许可证与来源标注、复制按钮说明与法务页入口
- 纠错:联系页面 / min@cactus.asia,2 个工作日内核实处理
常见问题
这个组件可以商用吗?
可以。本组件为粤喵自研原创,可免费用于个人和商业项目,无需署名。
浏览器兼容性如何?
支持所有现代浏览器(Chrome / Firefox / Safari / Edge 最新版本)。旧版 IE 不支持 CSS 动画相关特性。
怎么修改动画参数?
直接调整 CSS 中的 animation-duration(时长)、animation-timing-function(缓动曲线)等属性即可,代码中有注释说明。