css-animations

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CSS Animations for HyperFrames

适用于HyperFrames的CSS动画

HyperFrames can seek CSS keyframe animations through its
css
runtime adapter. Use this for simple repeated motifs, background motion, shimmer, glow, masks, and non-sequenced decoration.
For scene choreography, GSAP is usually clearer. CSS animations work best when the motion belongs to one element and has a fixed duration.
HyperFrames可通过其
css
运行时适配器定位CSS关键帧动画。适用于简单重复图案、背景动效、闪光、光晕、遮罩以及非序列装饰效果。
对于场景编排,GSAP通常更清晰直观。当动效仅属于单个元素且具有固定时长时,CSS动画的表现最佳。

Contract

约定

  • Put the animated element in the DOM before runtime initialization finishes.
  • Give timed elements a
    data-start
    value so local animation time matches the clip.
  • Use finite
    animation-duration
    and
    animation-iteration-count
    because the negative-delay fallback cannot represent unbounded duration in environments without WAAPI-backed CSS animations.
  • Prefer
    animation-fill-mode: both
    so seeked states hold before and after active motion.
  • Avoid wall-clock JavaScript, hover-triggered state, and class toggles that depend on user events.
The adapter discovers elements with computed
animation-name
, seeks their browser
Animation
handles when available, and falls back to pausing with negative
animation-delay
.
  • 在运行时初始化完成前,将带动效的元素放入DOM中。
  • 为定时元素设置
    data-start
    值,使本地动画时间与片段匹配。
  • 使用有限的
    animation-duration
    animation-iteration-count
    ,因为在不支持WAAPI驱动的CSS动画的环境中,负延迟回退方案无法表示无界时长。
  • 优先使用
    animation-fill-mode: both
    ,以便在动效激活前后都能保持定位后的状态。
  • 避免使用基于系统时钟的JavaScript、悬停触发状态以及依赖用户事件的类切换。
该适配器会查找带有计算后
animation-name
的元素,在可用时定位其浏览器
Animation
句柄,否则回退到使用负
animation-delay
来暂停动画。

Basic Pattern

基础模式

html
<div
  id="pulse-ring"
  class="clip pulse-ring"
  data-start="0"
  data-duration="4"
  data-track-index="2"
></div>

<style>
  .pulse-ring {
    width: 280px;
    height: 280px;
    border: 4px solid rgba(255, 255, 255, 0.7);
    border-radius: 50%;
    animation-name: pulse-ring;
    animation-duration: 1200ms;
    animation-timing-function: cubic-bezier(0.2, 0, 0, 1);
    animation-iteration-count: 3;
    animation-fill-mode: both;
  }

  @keyframes pulse-ring {
    from {
      opacity: 0;
      transform: scale(0.82);
    }
    35% {
      opacity: 1;
    }
    to {
      opacity: 0;
      transform: scale(1.18);
    }
  }
</style>
html
<div
  id="pulse-ring"
  class="clip pulse-ring"
  data-start="0"
  data-duration="4"
  data-track-index="2"
></div>

<style>
  .pulse-ring {
    width: 280px;
    height: 280px;
    border: 4px solid rgba(255, 255, 255, 0.7);
    border-radius: 50%;
    animation-name: pulse-ring;
    animation-duration: 1200ms;
    animation-timing-function: cubic-bezier(0.2, 0, 0, 1);
    animation-iteration-count: 3;
    animation-fill-mode: both;
  }

  @keyframes pulse-ring {
    from {
      opacity: 0;
      transform: scale(0.82);
    }
    35% {
      opacity: 1;
    }
    to {
      opacity: 0;
      transform: scale(1.18);
    }
  }
</style>

Stagger Pattern

交错模式

Use CSS custom properties to avoid duplicating keyframes:
html
<div class="clip dots" data-start="1" data-duration="3" data-track-index="3">
  <span style="--i: 0"></span>
  <span style="--i: 1"></span>
  <span style="--i: 2"></span>
</div>

<style>
  .dots span {
    display: inline-block;
    width: 18px;
    height: 18px;
    margin-right: 10px;
    border-radius: 50%;
    background: currentColor;
    animation: dot-pop 900ms ease-out both;
    animation-delay: calc(var(--i) * 120ms);
  }

  @keyframes dot-pop {
    from {
      opacity: 0;
      transform: translateY(18px) scale(0.75);
    }
    to {
      opacity: 1;
      transform: translateY(0) scale(1);
    }
  }
</style>
使用CSS自定义属性避免重复编写关键帧:
html
<div class="clip dots" data-start="1" data-duration="3" data-track-index="3">
  <span style="--i: 0"></span>
  <span style="--i: 1"></span>
  <span style="--i: 2"></span>
</div>

<style>
  .dots span {
    display: inline-block;
    width: 18px;
    height: 18px;
    margin-right: 10px;
    border-radius: 50%;
    background: currentColor;
    animation: dot-pop 900ms ease-out both;
    animation-delay: calc(var(--i) * 120ms);
  }

  @keyframes dot-pop {
    from {
      opacity: 0;
      transform: translateY(18px) scale(0.75);
    }
    to {
      opacity: 1;
      transform: translateY(0) scale(1);
    }
  }
</style>

Good Uses

适用场景

  • Decorative loops with a known repeat count.
  • Mask, glow, shimmer, grain, and subtle parallax layers.
  • Simple one-element entrances where a full JS timeline would be excessive.
  • 具有已知重复次数的装饰性循环动效。
  • 遮罩、光晕、闪光、颗粒感以及微妙的视差图层。
  • 简单的单元素入场动效,此时使用完整的JS时间线过于冗余。

Avoid

避坑指南

  • Infinite CSS animations unless you have verified the browser exposes seekable WAAPI-backed CSS animation handles. Prefer a finite iteration count covering the visible duration.
  • Animating layout properties like
    top
    ,
    left
    ,
    width
    , or
    height
    when transforms work.
  • Relying on hover, focus, scroll, or media queries to trigger render-critical motion.
  • Changing animation classes after startup unless another deterministic timeline controls that change.
  • 除非已确认浏览器暴露了可定位的WAAPI驱动CSS动画句柄,否则避免使用无限循环的CSS动画。优先选择覆盖可见时长的有限迭代次数。
  • 当transform属性可实现效果时,避免为
    top
    left
    width
    height
    等布局属性添加动画。
  • 避免依赖悬停、聚焦、滚动或媒体查询来触发对渲染至关重要的动效。
  • 除非由另一个确定性时间线控制,否则启动后不要修改动画类。

Validation

验证

After editing CSS animation compositions:
bash
npx hyperframes lint
npx hyperframes validate
编辑完CSS动画组合后:
bash
npx hyperframes lint
npx hyperframes validate

Credits And References

致谢与参考