应优先用 css @keyframes 控制 opacity 和 box-shadow 实现呼吸动画,避免 js setinterval 手动修改样式,因其导致 cpu 重绘、后台耗电及与 transition 冲突;关键帧需按 0%/70%/100% 设置 opacity 与 box-shadow 变化,并用 ease-in-out 曲线模拟自然呼吸节奏。

直接用 CSS @keyframes 控制 opacity 和 box-shadow 就够了,JavaScript 不仅没必要,还容易导致掉帧、切后台耗电、与其它动画冲突。
为什么别用 JS 的 setInterval 改 style.opacity
有人把图片包一层 <div>,再用 <code>setInterval 每 50ms 手动改 opacity,结果在低端安卓机上明显卡顿。原因有三:
- 浏览器无法将这类 JS 驱动的 opacity 变化交给 GPU 合成,强制走 CPU 重绘
- 页面切到后台时,
setInterval不自动暂停,持续跑定时器白耗电 - 若该图片同时用了
transition(比如 hover 缩放),JS 直接写style.opacity会触发 layout,打断硬件加速
@keyframes 中 opacity 和 box-shadow 要怎么配才自然
只调 opacity 看起来像“开关灯”,加一层呼吸感得靠光晕扩散节奏。关键不是数值堆砌,而是变化逻辑:
- 起始帧(0%):
opacity: 0.5+box-shadow: 0 0 0 0 rgba(120, 180, 255, 0)(无光晕) - 峰值帧(70%):
opacity: 1+box-shadow: 0 0 0 12px rgba(120, 180, 255, 0.2)(光晕最大最透) - 收尾帧(100%):
opacity: 0.5+box-shadow: 0 0 0 0 rgba(120, 180, 255, 0)(完全收敛) - 必须用
ease-in-out,不能用linear——呼吸是慢吸、快满、慢呼,线性变化太机械
图片本身带透明背景时要注意什么
如果用的是 PNG 图片且自身已有 alpha 通道(比如图标边缘半透),直接套呼吸动画会出现两层透明叠加,导致暗区过深、光晕发虚:
- 解决办法:给图片容器加
background-color: #000或其他纯色底,切断底层透出干扰 - 更稳妥做法:不用图片本体动画,而是用伪元素
::after在其上方画一层呼吸光晕(position: absolute+z-index: 1),图片保持静止 - OLED 屏幕上慎用高饱和蓝/绿光晕(如
#00aaff),纯黑背景下易出现子像素溢出,视觉上像毛边;可降饱和度或改用暖黄(#ffcc66)缓解
多个图片不同步呼吸的 trick
同一页面多个状态灯(比如服务健康指示器),如果全用相同 animation-duration 和默认起始时间,会集体脉动,反像系统异常:
- 给每个图片容器加不同
animation-delay,例如-0.3s、-1.1s、-2.4s,错开相位 - 不要用正数 delay(如
0.5s),否则首帧会空白等待,影响初始感知 - 若需响应式适配,可用 CSS 自定义属性动态改:
style="--breath-delay: -1.2s",再在 keyframes 里引用animation-delay: var(--breath-delay)
真正难的不是写出来,而是让呼吸节奏不抢眼、不干扰、不耗电——所有参数都要为这个服务,而不是堆效果。











