浅谈 CSS3 新特性:动画

1,134 阅读5分钟

@keyframes

@keyframes(关键帧),用来创建动画,它通过在动画序列中定义关键帧的样式来控制 CSS 动画序列中的中间步骤。和 transition 相比,@keyframes 可以控制动画序列的中间步骤。

语法:

@keyframes <keyframes-name> {
  <keyframes-selector> {
    <css-styles>
  };
}

  • <keyframes-name>:必需的。定义 keyframes 的名称。
  • <keyframes-selector>:必需的,动画持续时间。
    • from,等价于 0%。
    • to,等价于 100%。
    • <percentage>,动画序列中触发关键帧的时间点,使用百分值来表示。
  • <css-styles>:CSS 属性
@keyframes slidein {
  from {
    transform: translateX(0%);
  }

  to {
    transform: translateX(100%);
  }
}

没有指定动画的开始或结束状态

如果一个关键帧规则没有指定动画的开始或结束状态(也就是,0%/from100%/to,浏览器将使用元素的现有样式作为起始/结束状态。这可以用来从初始状态开始元素动画,最终返回初始状态。

重复定义

  • 多个关键帧使用同一个名称,以最后一次定义的为准(覆盖之前的)。

    /* ❌ 无效 */
    @keyframes mymove {
      to {
        transform: translateX(50%);
      }
    }
    /* ✅ 有效 */
    @keyframes mymove {
      to {
        transform: translateX(100%);
      }
    }
    
  • 在一个 @keyframes 内,关键帧的百分比存在重复的情况,这合并为一个。

    @keyframes mymove {
      to {
        background-color: blue;
      }
      to {
        transform: translateX(100%);
      }
    }
    
    /* 合并后 */
    @keyframes mymove {
      to {
        background-color: blue;
        transform: translateX(100%);
      }
    }
    
  • 同一关键帧中,相同属性被重复定义,以最后一次定义的属性为准(覆盖之前的)。

    @keyframes identifier {
      50% {
        top: 30px; /* ❌ 无效 */
        left: 20px;
      }
      50% {
        top: 10px; /* ✅ 有效 */
      }
    }
    

关键帧中的 !important。

关键帧中出现的 !important 将会被忽略。

@keyframes important1 {
  from {
    margin-top: 50px;
  }
  50% {
    margin-top: 150px !important; /* 忽略 */
  }
  to {
    margin-top: 100px;
  }
}

CSSKeyframesRule

JavaScript 可以通过 CSSKeyframesRule 访问 @keyframes

let myRules = document.styleSheets[0].cssRules;
let keyframes = myRules[0]; // a CSSKeyframesRule

animation

@keyframes 创建完动画后,把它绑定到一个选择器,动画才会生效。

animation 属性是 animation-nameanimation-durationanimation-timing-functionanimation-delayanimation-iteration-countanimation-directionanimation-fill-modeanimation-play-state 属性的一个简写属性形式。

语法:

animation: name duration timing-function delay iteration-count direction
  fill-mode play-state;
  • 每个动画定义中的属性值的顺序很重要:可以被解析为 <time> 的第一个值被分配给 animation-duration, 第二个分配给 animation-delay

animation-name(必需)

animation-name,指定动画的名称,每个名称代表一个由 @keyframes 定义的动画序列。

语法:

animation-name: keyframename|none;
  • none:无关键帧(使动画失效)。
  • keyframename:关键帧名称。

animation-duration(必需)

animation-duration,指定一个动画周期的时长,默认是 0s。

语法:

animation-duration: time;
  • time:一个动画周期的时长,单位为秒(s)或者毫秒(ms),无单位值无效。

animation-timing-function

animation-timing-function,指定动画将如何完成一个周期(速度曲线)。默认是 "ease"。关于 timing-function 可以参照 transition-timing-function 部分。

animation-delay

animation-delay 属性定义动画什么时候开始,默认是 0s。

提示: 允许负值,-2s 使动画马上开始,但跳过 2 秒进入动画。

语法:

animation-delay: time;

animation-iteration-count

animation-iteration-count,定义动画应该播放多少次,默认是 1 次。

语法:

animation-iteration-count: value;
  • infinite:无限循环播放动画。
  • <number>:动画播放的次数;默认值为 1。
    • 可以用小数定义循环,来播放动画周期的一部分:例如,0.5 将播放到动画周期的一半。
    • 不可为负值。

animation-direction

animation-direction,指示动画是否反向播放,默认是 normal

  • normal,默认值。动画按正常播放。
  • reverse,动画反向播放,每周期结束动画由尾到头运行。
  • alternate,动画折返运行。也就是说,动画在奇数次(1、3、5...)正向播放,在偶数次(2、4、6...)反向播放。
  • alternate-reverse,动画反向折返运行。也就是说,动画在奇数次(1、3、5...)反向播放,在偶数次(2、4、6...)正向播放。

animation-fill-mode

animation-fill-mode,设置动画在执行之前和之后的状态(应用到元素的样式)。

  • none:默认值,没有状态的保留或处理。

  • forwards:保留动画执行过程中的最后一个关键帧计算值。

    最后一个关键帧取决于 animation-directionanimation-iteration-count 的值:

    animation-directionanimation-iteration-count最后一个关键帧
    normal/100% or to
    reverse/0% or from
    alternate偶数0% or from
    alternate奇数100% or to
    alternate-reverse偶数100% or to
    alternate-reverse奇数0% or from
  • backwards:动画第一个关键帧,并在 animation-delay 期间保留此值。

    第一个关键帧取决于 animation-direction 的值:

    animation-direction第一个关键帧
    normal or alternate0% or from
    reverse or alternate-reverse100% or to
  • both:动画将遵循 forwardsbackwards 的规则,从而在两个方向上扩展动画属性。

animation-play-state

animation-play-state,动画是否正在运行或暂停。默认是 running

语法:

animation-play-state: paused|running;
  • paused:当前动画已停止。
  • running:当前动画正在运行。

在 JS 中,可以通过查询它来确定动画是否正在运行,也可以根据修改它来控制动画的暂停。比如控制 .active

.animate {
  animation-play-state: paused;
}
.active.animate {
  animation-play-state: running;
}

恢复一个已暂停的动画,将从它开始暂停的时候,而不是从动画序列的起点开始在动画。

浅谈 CSS3 新特性