心跳动效核心是scale与opacity三段式错峰联动:0%收缩变暗(scale0.8/opacity0.7)、50%猛弹趋亮(scale1.2/opacity0.95)、100%回位全显(scale1/opacity1),需infinite循环、cubic-bezier缓动及forwards保态,ios需加translatez(0)防闪烁。

心跳动效的核心原理是scale和opacity联动
纯CSS实现心跳效果,本质是让元素在“收缩—扩张—微回弹”过程中同步改变透明度,模拟真实心跳的搏动感。关键不在动画时长多精确,而在两个属性的节奏是否错开:scale变化要快而有力,opacity变化要稍缓、带呼吸感,否则会像机械抖动。
-
scale(0.8)是收缩起点(不能到0,否则元素消失,破坏连续性) -
opacity从0.7开始降,到0.95回升,避免全程不透明失去“搏动”层次 - 动画时长建议
0.6s–0.8s,太短像抽搐,太长失去心跳节奏感
@keyframes里scale和opacity必须分段控制
很多人直接写 from { scale: 1; opacity: 1; } to { scale: 1.2; opacity: 1; },结果只有膨胀没心跳——缺了收缩和透明度过渡。真正的心跳是三段式:压下 → 猛弹 → 微稳。
- 0%:
transform: scale(0.8); opacity: 0.7;(压下,略暗) - 50%:
transform: scale(1.2); opacity: 0.95;(猛弹,接近全亮) - 100%:
transform: scale(1); opacity: 1;(回位,完全恢复) - 别用
ease-in-out全局缓动,收缩段用ease-in,弹出段用ease-out更真实
animation属性容易漏掉的三个配置项
只写 animation: heartbeat 0.7s; 会导致动效卡顿、不循环或初始状态错乱。心跳必须持续、平滑、无跳变。
- 必须加
infinite,否则只跳一次就停 - 必须加
linear或自定义cubic-bezier(.2,1.2,.5,1),默认ease在 0%→50% 段太慢,压不住节奏 - 必须加
animation-fill-mode: forwards;,否则动画结束后会闪回初始scale(1)状态,破坏连续感
真机上iOS Safari常出现scale闪烁问题
iOS 15+ 的 WebKit 对 transform: scale() 单独动画有渲染优化 Bug,尤其配合 opacity 时,第一帧可能突兀放大或透明度跳变。
立即学习“前端免费学习笔记(深入)”;
- 临时解法:给元素加
transform: translateZ(0);强制硬件加速 - 更稳方案:把
scale换成transform: scale(0.8) translateZ(0);,所有关键帧都带上translateZ(0) - 别依赖
will-change: transform, opacity;,它在低端安卓上反而引发重绘撕裂
0.5 或 0 看似对比强,但人眼对明暗变化比形变更敏感,过低会让心跳看起来像故障闪烁。调到 0.7 左右,才是既明显又自然的临界点。










