同心圆脉冲效果核心是控制多层border-radius:50%元素在固定原点上按序缩放与透明度变化;水波纹感源于多层叠加、错峰延迟、scale(0)到scale(1.2)回弹;需设transform-origin:center,加will-change:transform,opacity优化性能,避免IE兼容问题。

用 @keyframes 实现同心圆逐层扩散的脉冲效果
核心不是“画圆”,而是控制多个 border-radius: 50% 元素在固定原点上按时间顺序缩放+透明度变化。水波纹感来自:① 多层环形元素叠加;② 每层动画延迟不同;③ 缩放起点为 scale(0),终点略大于 1(如 scale(1.2))以模拟扩散回弹。
推荐用伪元素实现,避免 DOM 膨胀。例如给一个 div.radar 添加 ::before 和 ::after,分别代表第 1 波和第 2 波:
div.radar {
position: relative;
width: 100px; height: 100px;
}
div.radar::before,
div.radar::after {
content: '';
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
border-radius: 50%;
border: 2px solid rgba(0,120,255,0.6);
animation: ripple 3s infinite;
}
div.radar::before {
animation-delay: 0s;
}
div.radar::after {
animation-delay: 1.2s;
}
@keyframes ripple {
0% { transform: scale(0); opacity: 1; }
70% { opacity: 0.4; }
100% { transform: scale(1.2); opacity: 0; }
}
transform-origin 必须设为 center 否则变形偏移
如果父容器不是正方形,或元素用了 margin/position: absolute 偏移,transform 默认以左上角为原点,水波会歪。必须显式重置:
-
transform-origin: center;—— 最简写法,适用于居中定位 - 若需精确到像素(比如雷达图标在按钮右下角),改用
transform-origin: 50px 50px;(对应父容器内的绝对坐标) - 不要依赖
top: 50%; left: 50%; transform: translate(-50%, -50%)来“假装居中”,那会让transform-origin计算混乱
性能关键:用 will-change: transform, opacity 防止重绘卡顿
高频缩放+透明度动画在低端设备上容易掉帧。Chrome/Firefox 对 transform 和 opacity 有硬件加速优化,但需主动提示:
立即学习“前端免费学习笔记(深入)”;
- 加在动画元素上:
will-change: transform, opacity; - 切勿全局加在父容器——会触发不必要的图层提升,反而拖慢渲染
- 动画结束后可 JS 移除该声明(非必需,但更稳妥):
element.style.willChange = 'auto'; - 别用
animation-timing-function: linear模拟匀速扩散——人眼感知的“脉冲感”实际需要缓动,cubic-bezier(0.2, 0.8, 0.2, 1)更自然
兼容性陷阱:IE 不支持 transform 动画中的 scale 关键帧
IE10/11 能解析 @keyframes,但对 transform 的动画支持极弱——scale() 在关键帧里常被忽略,只显示初始态或最终态。真实项目中若需兼容:
- 放弃 IE,用
@supports (animation: ripple) and (transform: scale(1))做特性检测后启用 - 降级方案:用 SVG
<circle></circle>+stroke-dasharray模拟环形扩散(更轻量,且 IE9+ 支持) - 注意 Safari 旧版(≤13.1)对
will-change有内存泄漏风险,生产环境建议加 UA 判断再启用
真正难的不是让圆动起来,是让多层波纹的时间差刚好不机械、缩放曲线不生硬、在各种屏幕缩放比例下都不糊边——这些全靠反复调 animation-delay 和 cubic-bezier 参数,没法一劳永逸。


















