1. 简介
本节是非规范性的
CSS 过渡 [CSS3-TRANSITIONS] 提供了一种在底层属性变化导致 CSS 属性值变化时对其进行插值的方法。这提供了一种实现简单动画的便捷方式,但动画的开始和结束状态由现有的属性值控制,且过渡无法为作者提供多少关于动画进度方面的控制。
本提案引入了定义好的动画,作者可以将 CSS 属性随时间的变化指定为一组关键帧。动画与过渡类似,它们都是随时间改变 CSS 属性的表现值。主要区别在于:过渡在属性值发生变化时隐式触发,而动画在应用动画属性时显式执行。正因如此,动画需要为被动画化的属性指定显式值。这些值使用下面描述的动画关键帧来指定。
动画的许多方面都可以控制,包括动画循环的次数、是否在开始值和结束值之间交替,以及动画是应该运行还是暂停。动画还可以延迟其开始时间。
1.1. 值定义
本规范遵循 [CSS2] 中的 CSS 属性定义约定,并使用 [CSS-VALUES-3] 中的 值定义语法。本规范中未定义的值类型在 CSS Values & Units [CSS-VALUES-3] 中定义。与其他 CSS 模块的组合可能会扩展这些值类型的定义。
除了定义中列出的属性特定值外,本规范中定义的所有属性也都接受 CSS 全局关键字 作为其属性值。为了可读性,未明确重复列出。
2. 动画
CSS 动画会影响计算后的属性值。这种效果是通过向 CSS 层叠中添加一个指定值 ([CSS3CASCADE])(在 CSS 动画层级)来实现的,该值会为动画的当前状态产生正确的计算值。如 [CSS3CASCADE] 中所定义,动画覆盖所有常规规则,但被 !important 规则所覆盖。
如果某个时间点有多个动画为同一属性指定了行为,则在 animation-name 值中排在最后的动画将覆盖该点处的其他动画。
动画在应用之前(即当元素上设置了 animation-name 属性时)或移除之后,不会影响其计算值。此外,通常情况下,动画在动画延迟过期之前或动画结束后不会影响计算值,但根据 animation-fill-mode 属性可能会有所不同。
在运行时,动画会计算其所动画化属性的值。根据 CSS 层叠 ([CSS3CASCADE]),其他值可能会优先于动画值。
当动画已应用但尚未结束,或者已结束但具有 animation-fill-mode 值 forwards 或 both 时,用户代理必须表现得好像元素上的 will-change 属性 ([css-will-change-1]) 额外包含了该动画所动画化的所有属性。
动画的开始时间是应用动画的样式和相应的 @keyframes 规则都解析完成的时间。如果为元素指定了动画,但相应的 @keyframes 规则尚不存在,则动画无法开始;一旦能解析到匹配的 @keyframes 规则,动画将从头开始。通过动态修改元素样式指定的动画将在该样式解析时开始;在伪样式规则(如 hover)的情况下可能是立即开始,或者在脚本应用样式的情况下是脚本引擎将控制权交还给浏览器时开始。请注意,动态更新关键帧样式规则不会启动或重新启动动画。
如果一个动画的名称作为标识符出现在 animation-name 属性的计算值中,并且该动画使用有效的 @keyframes 规则,则它应用于该元素。一旦动画开始,它就会持续到结束或 animation-name 被移除。在动画运行时更改动画属性的值,其应用方式如同动画自始至终都具有这些值一样。例如,缩短 animation-delay 可能会导致动画向前跳跃,甚至立即结束并派发 animationend 事件。相反,延长 animation-delay 可能会导致动画重新开始并派发 animationstart 事件。
同一个 @keyframes 规则名称可以在 animation-name 中重复。对 animation-name 的更改会通过从后往前遍历新的动画列表来更新现有动画,并为每个动画在现有动画列表中找到最后一个匹配的动画。如果找到匹配项,则使用对应于其在新的动画列表中位置的动画属性来更新现有动画,同时如上所述保持其当前的播放时间。匹配的动画将从现有动画列表中移除,这样它就不会被匹配两次。如果没有找到匹配项,则创建一个新动画。因此,将 animation-name 从 ‘a’ 更新为 ‘a, a’ 将导致 ‘a’ 的现有动画成为列表中的第二个动画,并为列表中的第一项创建一个新动画。
div {
animation-name: diagonal-slide;
animation-duration: 5s;
animation-iteration-count: 10;
}
@keyframes diagonal-slide {
from {
left: 0;
top: 0;
}
to {
left: 100px;
top: 100px;
}
}
这将产生一个动画,将元素在五秒内从 (0, 0) 移动到 (100px, 100px),并重复九次(总共十次迭代)。
将 display 属性设置为 none 将终止应用于该元素及其后代的任何正在运行的动画。如果元素的 display 为 none,则将 display 更新为非 none 的值将启动由 animation-name 属性应用于该元素的所有动画,以及所有应用于 display 非 none 的后代的动画。
虽然作者可以使用动画来创建动态变化的内容,但动态变化的内容可能会导致部分用户癫痫发作。有关如何避免可能导致癫痫发作的内容的信息,请参阅指南 2.3:癫痫发作:不要以已知会导致癫痫发作的方式设计内容 ([WCAG20])。
当渲染媒介不是交互式时(例如打印时),实现可以忽略动画。本规范的未来版本可能会定义如何为这些媒介渲染动画。
3. 关键帧
关键帧用于指定动画化属性在动画过程中各个点的取值。关键帧指定了一个动画周期内的行为;动画可以迭代零次或多次。
关键帧使用 @keyframes at-rule 进行指定,定义如下
@keyframes = @keyframes <keyframes-name> { <rule-list> }
<keyframes-name> = <custom-ident> | <string>
<keyframe-block> = <keyframe-selector># { <declaration-list> }
<keyframe-selector> = from | to | <percentage [0,100]>
@keyframes 内部的 <rule-list> 只能包含 <keyframe-block> 规则。
<keyframe-block> 内部的 <declaration-list> 接受除本规范定义的属性之外的任何 CSS 属性,但它确实接受 animation-timing-function 属性并对其进行特殊解析。没有任何属性会与层叠交互(因此在它们上面使用 !important 是无效的,会导致该属性被忽略)。
@keyframes 块具有一个名称,由其序言中的 <custom-ident> 或 <string> 给定。两种语法在功能上是等价的;名称即 ident 或 string 的值。正如 <custom-ident> 和 <string> 的常规情况一样,名称完全区分大小写;仅当两个名称逐个代码点相等时才相等。<custom-ident> 此外排除了 none 关键字。
@keyframes foo{ /* ... */ } @keyframes "foo" { /* ... */ }
另一方面,以下 @keyframes 规则的名称与前两个规则不同
@keyframes FOO{ /* ... */ }
以下 @keyframes 规则无效,因为它们使用了不允许的 <custom-ident> 值
@keyframes initial{ /* ... */ } @keyframes None{ /* ... */ }
然而,这些名称可以使用 <string> 指定,因此以下内容均有效
@keyframes "initial" { /* ... */ } @keyframes "None" { /* ... */ }
<keyframe-selector> 对于 <keyframe-block> 由逗号分隔的百分比值列表或关键字 from 或 to 组成。选择器用于指定关键帧在动画持续时间中所处的百分比。关键帧本身由在选择器上声明的属性值块指定。关键字 from 等同于值 0%。关键字 to 等同于值 100%。小于 0% 或大于 100% 的值无效,并会导致其 <keyframe-block> 被忽略。
请注意,百分比值必须使用百分比单位说明符。因此,0 是无效的关键帧选择器。
如果未指定 0% 或 from 关键帧,则用户代理使用被动画化属性的计算值构建 0% 关键帧。如果未指定 100% 或 to 关键帧,则用户代理使用被动画化属性的计算值构建 100% 关键帧。
<keyframe-block> 包含属性和值。本规范定义的属性在这些规则中会被忽略,但 animation-timing-function 除外,其行为如下所述。此外,被 !important 修饰的属性无效并被忽略。
如果定义了多个名称相同的 @keyframes 规则,文档流中最后的规则胜出,所有之前的规则都被忽略。
div {
animation-name: slide-right;
animation-duration: 2s;
}
@keyframes slide-right {
from {
margin-left: 0px;
}
50% {
margin-left: 110px;
opacity: 1;
}
50% {
opacity: 0.9;
}
to {
margin-left: 200px;
}
}
上面提到的两个 50% 规则也可以合并为一个等价的单一规则,如下所示
@keyframes slide-right {
from {
margin-left: 0px;
}
50% {
margin-left: 110px;
opacity: 0.9;
}
to {
margin-left: 200px;
}
}
为了确定关键帧集合,选择器中的所有值都会按时间增加的顺序进行排序。然后 @keyframes 规则内部的规则会进行层叠;因此,关键帧的属性可能派生自多个具有相同选择器值的 @keyframes 规则。
如果未为关键帧指定属性,或者指定了但无效,则该属性的动画将如同该关键帧不存在一样进行。在概念上,就像为存在于任何关键帧中的每个属性构建了一组关键帧,并为每个属性独立运行动画一样。
@keyframes wobble {
0% {
left: 100px;
}
40% {
left: 150px;
}
60% {
left: 75px;
}
100% {
left: 100px;
}
}
为名为 "wobble" 的动画指定了四个关键帧。在第一个关键帧(动画周期开始时)中,被动画化的 left 属性值为 100px。到动画持续时间的 40% 时,left 动画变为 150px。在动画持续时间的 60% 时,left 动画回到 75px。在动画周期结束时,left 的值已返回 100px。下方的图表展示了如果给予其 10s 持续时间后的动画状态。
本规范需要定义如何从关键帧确定值,就像 CSS 过渡的 过渡应用 一节所做的那样。
3.1. 关键帧的时间函数
关键帧样式规则还可以声明动画移动到下一个关键帧时所要使用的时间函数。
@keyframes bounce {
from {
top: 100px;
animation-timing-function: ease-out;
}
25% {
top: 50px;
animation-timing-function: ease-in;
}
50% {
top: 100px;
animation-timing-function: ease-out;
}
75% {
top: 75px;
animation-timing-function: ease-in;
}
to {
top: 100px;
}
}
为名为 "bounce" 的动画指定了五个关键帧。在第一个和第二个关键帧之间(即 0% 和 25% 之间)使用了 ease-out 时间函数。在第二个和第三个关键帧之间(即 25% 和 50% 之间)使用了 ease-in 时间函数。以此类推。其效果表现为一个元素在页面上向上移动 50px,在到达最高点时减速,然后在掉回 100px 时加速。动画的后半部分表现类似,但只会将元素向上移动 25px。
在 to 或 100% 关键帧上指定的时间函数会被忽略。
有关更多信息,请参阅 animation-timing-function 属性。
3.2. animation-name 属性
animation-name 属性定义了一个要应用的动画列表。每个名称都用于选择提供动画属性值的关键帧 at-rule。如果名称与任何关键帧 at-rule 不匹配,则没有要动画化的属性,动画将不会执行。此外,如果动画名称为 none,则不会有动画。这可用于覆盖来自层叠的任何动画。如果多个动画试图修改同一个属性,则名称列表中排在最后面的动画胜出。
列出的每个动画名称都应为下面列出的其他动画属性具有相应的值。如果其他动画属性的值列表长度不同,则 animation-name 列表的长度决定了启动动画时检查每个列表中的项数。列表从第一个值开始匹配:末尾多余的值不会被使用。如果其他属性之一没有足够的逗号分隔值来匹配 animation-name 的值的数量,则 UA 必须通过重复值列表直到有足够的数量来计算其使用值。这种截断或重复不会影响计算值。
注意:这类似于 background-* 属性的行为,其中 background-image 类似于 animation-name。
| 名称 | animation-name |
|---|---|
| 值 | [ none | <keyframes-name> ]# |
| 初始值 | none(无) |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 计算值 | 列表,每项要么是一个区分大小写的 css 标识符,要么是关键字 none |
| 规范顺序 | 按语法 |
| 动画类型 | 不可动画 |
animation-name 的值具有以下含义
- none(无)
- 没有指定任何关键帧,因此不会有动画。为该动画指定的任何其他动画属性均无效。
- <keyframes-name>
- 如果存在,动画将使用 <keyframes-name> 指定名称的关键帧。如果不存在该名称的 @keyframes 规则,则没有动画。
3.3. animation-duration 属性
animation-duration 属性定义单个动画周期的持续时间。
| 名称 | animation-duration |
|---|---|
| 值 | <time [0s,∞]># |
| 初始值 | 0s |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 计算值 | 列表,每项是一个持续时间 |
| 规范顺序 | 按语法 |
| 动画类型 | 不可动画 |
- <time [0s,∞]>
- <time> 指定动画完成一个周期所需的时间长度。负的 <time> 是无效的。
如果 <time> 为 0s(初始值),则动画的关键帧不会有任何效果,但动画本身仍然会瞬间发生。具体而言,会触发开始和结束事件;如果 animation-fill-mode 设置为 backwards 或 both,则动画的第一帧(由 animation-direction 定义)将在 animation-delay 期间显示。在 animation-delay 之后,如果 animation-fill-mode 设置为 forwards 或 both,将显示动画的最后一帧(由 animation-direction 定义)。如果 animation-fill-mode 设置为 none,则动画将没有任何可见效果。
3.4. animation-timing-function 属性
animation-timing-function 属性描述了动画在每对关键帧之间将如何进行。时间函数定义在单独的 CSS Easing Functions 模块 [css-easing-1] 中。
使用的 输入进度值 是当前关键帧与下一个关键帧之间经过的时间百分比,在合并了 animation-direction 属性的效果之后。
在 animation-delay 期间,animation-timing-function 不会被应用。
注意:此定义是必要的,否则具有 start 阶梯位置 的 阶梯缓动函数 将产生等于函数中第一步顶部的反向填充。
输出进度值 在当前和下一个关键帧之间插值属性值时用作 p 值。
| 名称 | animation-timing-function |
|---|---|
| 值 | <easing-function># |
| 初始值 | ease |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 计算值 | 列表,每项是一个计算后的 <easing-function> |
| 规范顺序 | 按语法 |
| 动画类型 | 不可动画 |
当在关键帧中指定时,animation-timing-function 定义了动画在排序后的关键帧选择器顺序中,当前关键帧与下一个关键帧之间被动画化属性的进程(可能是一个隐式的 100% 关键帧)。
3.5. animation-iteration-count 属性
animation-iteration-count 属性指定了动画周期播放的次数。初始值为 1,意味着动画将从头到尾播放一次。此属性通常与值为 alternate 的 animation-direction 结合使用,这将导致动画在交替周期中反向播放。
动画处于活动状态的时间窗口(duration x iteration-count)被称为 活动持续时间。
| 名称 | animation-iteration-count |
|---|---|
| 值 | <single-animation-iteration-count># |
| 初始值 | 1 |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 计算值 | 列表,每项要么是一个数字,要么是关键字 infinite |
| 规范顺序 | 按语法 |
| 动画类型 | 不可动画 |
<single-animation-iteration-count> = infinite | <number [0,∞]>
- infinite
- 动画将无限重复。
- <number [0,∞]>
-
动画将重复指定的次数。如果数字不是整数,动画将在其最后一个周期中途结束。负数是无效的。
值为 0 是有效的,类似于 0s 的 animation-duration,会导致动画瞬间发生。
如果动画的持续时间为 0s,则对于 animation-iteration-count 的任何有效值(包括 infinite),它都会瞬间发生。
3.6. animation-direction 属性
animation-direction 属性定义动画是否应在部分或全部周期内反向播放。当动画反向播放时,时间函数也会反转。例如,反向播放时,ease-in 动画看起来就像是一个 ease-out 动画。
| 名称 | animation-direction |
|---|---|
| 值 | <single-animation-direction># |
| 初始值 | normal |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 计算值 | 列表,每一项均为指定的关键字 |
| 规范顺序 | 按语法 |
| 动画类型 | 不可动画 |
<single-animation-direction> = normal | reverse | alternate | alternate-reverse
- normal
- 动画的所有迭代均按指定方式播放。
- reverse
- 动画的所有迭代均以与指定方式相反的方向播放。
- alternate
- 奇数次计数的动画周期迭代以正常方向播放,偶数次计数的动画周期迭代以相反方向播放。
- alternate-reverse(交替反向)
- 奇数次计数的动画周期迭代以相反方向播放,偶数次计数的动画周期迭代以正常方向播放。
注意:出于确定迭代是奇数还是偶数的目的,迭代从 1 开始计数。
3.7. animation-play-state 属性
animation-play-state 属性定义动画是在运行还是已暂停。
| 名称 | animation-play-state |
|---|---|
| 值 | <single-animation-play-state># |
| 初始值 | running |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 计算值 | 列表,每一项均为指定的关键字 |
| 规范顺序 | 按语法 |
| 动画类型 | 不可动画 |
<single-animation-play-state> = running | paused
- running
- 当此属性设置为 running 时,动画按正常方式进行。
- 暂停 (paused)
- 当此属性设置为 paused 时,动画已暂停。动画继续应用于具有暂停前所取得进度的元素。当取消暂停时(设置回 running),它会从离开的地方重新开始,就像控制动画的“时钟”停止并再次启动一样。
如果在动画的延迟阶段属性被设置为 paused,延迟时钟也会暂停,并在 animation-play-state 被设置回 running 后立即恢复。
3.8. animation-delay 属性
animation-delay 属性定义动画何时开始。它允许动画在应用后一段时间开始执行,或者看起来在应用之前一段时间就已经开始执行。
| 名称 | animation-delay |
|---|---|
| 值 | <time># |
| 初始值 | 0s |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 计算值 | 列表,每项是一个持续时间 |
| 规范顺序 | 按语法 |
| 动画类型 | 不可动画 |
- <time>
- <time> 定义了动画开始(当通过这些属性将动画应用于元素时)与开始执行之间的延迟时间长度。0s 的延迟(初始值)意味着动画将在应用后立即执行。
负延迟是有效的。类似于 0s 的延迟,它意味着动画立即执行,但会被自动推进延迟的绝对值,如同动画在过去指定的某个时间点开始一样,因此它看起来像是从其 活动持续时间 的中途开始的。如果动画的关键帧具有隐含的起始值,则这些值取自动画开始的时间,而不是过去的某个时间。
3.9. animation-fill-mode 属性
animation-fill-mode 属性定义了在动画执行时间之外应用哪些值。默认情况下,动画不会影响动画应用时间(在元素上设置 animation-name 属性时)与开始执行时间(由 animation-delay 属性决定)之间的属性值。此外,默认情况下,动画在结束之后(由 animation-duration 和 animation-iteration-count 属性决定)也不会影响属性值。animation-fill-mode 属性可以覆盖此行为。对属性的动态更新将根据需要反映在属性值中,无论是在动画延迟期间还是在动画结束后。
| 名称 | animation-fill-mode |
|---|---|
| 值 | <single-animation-fill-mode># |
| 初始值 | none(无) |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 计算值 | 列表,每一项均为指定的关键字 |
| 规范顺序 | 按语法 |
| 动画类型 | 不可动画 |
<single-animation-fill-mode> = none | forwards | backwards | both
- none(无)
- 动画在应用但未执行时没有效果。
- forwards(向前)
- 动画结束后(由其 animation-iteration-count 决定),动画将应用动画结束时的属性值。当 animation-iteration-count 是大于零的整数时,应用的值将是动画最后一次完成迭代结束时的值(而不是下一次迭代开始时的值)。当 animation-iteration-count 为零时,应用的值将是开始第一次迭代时的值(就像 animation-fill-mode 为 backwards 时一样)。
- backwards(向后)
- 在 animation-delay 定义的期间,动画将应用动画第一次迭代开始时定义在关键帧中的属性值。这些值要么是 from 关键帧的值(当 animation-direction 为 normal 或 alternate 时),要么是 to 关键帧的值(当 animation-direction 为 reverse 或 alternate-reverse 时)。
- both
- forwards 和 backwards 填充的效果同时应用。
3.10. animation 简写属性
animation 简写属性是一个逗号分隔的动画定义列表。列表中的每一项给出了该简写属性所有子属性(即动画属性)值中的一项。(有关当这些属性具有不同长度的列表时会发生什么,请参阅 animation-name 的定义,当使用 animation 简写属性定义时,此问题不会发生。)
| 名称 | animation |
|---|---|
| 值 | <single-animation># |
| 初始值 | 见各个属性 |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 计算值 | 见各个属性 |
| 规范顺序 | 按语法 |
| 动画类型 | 不可动画 |
<single-animation> = <time> || <easing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state> || [ none | <keyframes-name> ]
请注意,在每个动画定义中顺序很重要:每个 <single-animation> 中第一个可以解析为 <time> 的值被分配给 animation-duration,而每个 <single-animation> 中第二个可以解析为 <time> 的值被分配给 animation-delay。
请注意,每个动画定义内部的顺序对于区分 <keyframes-name> 值与其他关键字也非常重要。解析时,对于那些值在简写属性中未更早出现的、除 animation-name 之外属性有效的关键字,必须接受用于这些属性而不是用于 animation-name。此外,序列化时,必须输出其他属性的默认值,至少在必要的情况下用于区分可能属于另一个属性值的 animation-name,在其他情况下也可以输出。
4. 动画事件
通过 DOM 事件系统可以使用几个与动画相关的事件。动画的开始和结束,以及动画的每次迭代结束,都会生成 DOM 事件。一个元素可以同时有多个属性被动画化。这可以通过具有多个属性的关键帧的单个 animation-name 值,或者通过多个 animation-name 值来实现。就事件而言,每个 animation-name 指定一个单一动画。因此,事件将为每个 animation-name 值生成,而不一定为每个被动画化的属性生成。
任何定义了有效关键帧规则的动画都将运行并生成事件;这包括具有空关键帧规则的动画。
动画运行的时间随生成的每个事件一起发送。这允许事件处理器确定循环动画的当前迭代或交替动画的当前位置。此时间不包括动画处于 paused 播放状态的任何时间。
4.1. AnimationEvent 接口
AnimationEvent 接口提供与动画事件关联的具体上下文信息。
4.1.1. IDL 定义
[Exposed =Window ]interface :AnimationEvent Event {constructor (CSSOMString ,type optional AnimationEventInit = {});animationEventInitDict readonly attribute CSSOMString animationName ;readonly attribute double elapsedTime ;readonly attribute CSSOMString pseudoElement ; };dictionary :AnimationEventInit EventInit {CSSOMString = "";animationName double = 0.0;elapsedTime CSSOMString = ""; };pseudoElement
4.1.2. 属性
animationName, 类型为 CSSOMString, 只读- 触发事件的动画的 animation-name 属性值。
elapsedTime, 类型为 double, 只读- 事件触发时,动画已运行的时间量(以秒为单位),不包括动画暂停的任何时间。此成员的精确计算定义在每个事件类型中。
pseudoElement, 类型为 CSSOMString, 只读- 动画在其上运行的 CSS 伪元素的名称(以两个冒号开头)(在这种情况下,事件的目标是该伪元素对应的元素),如果动画在元素上运行,则为空字符串(这意味着事件的目标是该元素)。
AnimationEvent(type, animationEventInitDict) 是一个 事件构造函数。
4.2. AnimationEvent 的类型
可能发生的各类动画事件包括
animationstartanimationstart事件发生在动画开始时。如果有 animation-delay,此事件将在延迟期满后触发一次。负延迟将导致事件触发,其
elapsedTime等于延迟的绝对值,并以动画的 活动持续时间 为上限,即min(max(-animation-delay, 0), 活动持续时间);在这种情况下,无论 animation-play-state 设置为 running 还是 paused,事件都将触发。- 冒泡:是
- 可取消:否
- 上下文信息:animationName, elapsedTime, pseudoElement
animationendanimationend事件发生在动画结束时。在这种情况下,事件的elapsedTime成员的值等于 活动持续时间。- 冒泡:是
- 可取消:否
- 上下文信息:animationName, elapsedTime, pseudoElement
animationiterationanimationiteration事件发生在动画每次迭代结束时,除非此时会触发 animationend 事件。这意味着此事件不会发生在迭代次数为一次或更少的动画中。在这种情况下,
elapsedTime成员等于 当前迭代 和 animation-duration 的乘积,其中 当前迭代 是新迭代的从零开始的索引。例如,假设没有负的 animation-delay,在一次迭代完成后,当前迭代 将为一。- 冒泡:是
- 可取消:否
- 上下文信息:animationName, elapsedTime, pseudoElement
animationcancelanimationcancel事件发生在动画以不触发animationend事件的方式停止运行时,例如更改 animation-name 从而移除了动画,或者动画化元素或其祖先之一变为 display:none。此事件的
elapsedTime成员表示动画取消时自动画开始以来经过的秒数。这不包括动画暂停的任何时间。如果动画具有负的 animation-delay,则动画开始的时刻等于动画实际触发之前 animation-delay 秒的绝对值。或者,如果动画具有正的 animation-delay 并且在动画延迟过期之前触发了事件,则elapsedTime将为零。- 冒泡:是
- 可取消:否
- 上下文信息:animationName, elapsedTime, pseudoElement
4.3. 元素、Document 对象和 Window 对象上的事件处理器
以下是所有 HTML 元素 必须支持的 事件处理器(及其对应的 事件处理器事件类型),既作为 事件处理器内容属性 也作为 事件处理器 IDL 属性;且必须由所有 Document 和 Window 对象作为 事件处理器 IDL 属性 支持。
| 事件处理器 | 事件处理器事件类型 |
|---|---|
onanimationstart
| animationstart
|
onanimationiteration
| animationiteration
|
onanimationend
| animationend
|
onanimationcancel
| animationcancel
|
5. DOM 接口
CSS 动画通过一对描述关键帧的新接口暴露给 CSSOM。
注意:下面定义的接口反映了截至本规范级别可用的互操作 API。未来的级别可能会弃用此 API 的部分内容并扩展其他内容。
5.1. CSSRule 接口
以下两种规则类型被添加到 CSSRule 接口中。它们为新的关键帧和关键帧规则提供了标识。
5.1.1. IDL 定义
partial interface CSSRule {const unsigned short = 7;KEYFRAMES_RULE const unsigned short = 8; };KEYFRAME_RULE
5.2. CSSKeyframeRule 接口
CSSKeyframeRule 接口表示单个关键点的样式规则。
5.2.1. IDL 定义
[Exposed =Window ]interface :CSSKeyframeRule CSSRule {attribute CSSOMString keyText ; [SameObject ,PutForwards =cssText ]readonly attribute CSSStyleDeclaration style ; };
5.2.2. 属性
keyText, 类型为 CSSOMString- 此属性将关键帧选择器表示为逗号分隔的百分比值列表。from 和 to 关键字分别映射到 0% 和 100%。
如果使用无效的关键帧选择器更新 keyText,则必须抛出 SyntaxError 异常,且 keyText 的值必须保持不变。
style, 类型为 CSSStyleDeclaration, 只读- 必须返回关键帧规则的
CSSStyleDeclaration对象,并具有以下属性- 只读标志
- 未设置。
- declarations
- 规则中声明的声明,按 指定顺序。
- 父 CSS 规则
- 上下文对象(即此
CSSKeyframeRule)。 - 所有者节点
- Null。
5.3. CSSKeyframesRule 接口
CSSKeyframesRule 接口表示单个动画的一组完整关键帧。
5.3.1. IDL 定义
[Exposed =Window ]interface :CSSKeyframesRule CSSRule {attribute CSSOMString name ;readonly attribute CSSRuleList cssRules ;readonly attribute unsigned long length ;getter CSSKeyframeRule (unsigned long index );undefined appendRule (CSSOMString rule );undefined deleteRule (CSSOMString select );CSSKeyframeRule ?findRule (CSSOMString select ); };
5.3.2. 属性
name, 类型为 CSSOMString- 此属性是关键帧的名称,由 animation-name 属性使用。
cssRules, 类型为 CSSRuleList, 只读- 此属性允许访问列表中的关键帧。
length, 类型为 unsigned long, 只读- 此属性是列表中关键帧的数量。
5.3.3. 索引属性获取器
该 索引属性获取器 从关键帧列表中返回指定位置的 CSSKeyframeRule。
参数
index类型为unsigned long- 要返回规则的从零开始的索引。
返回值
CSSKeyframeRule- 找到的规则,如果指定索引处没有规则,则为
undefined。
无异常
5.3.4. appendRule 方法
appendRule 方法将传入的 CSSKeyframeRule 追加到关键帧规则的末尾。
参数
rule类型为CSSOMString- 要追加的规则,以与 @keyframes 规则中单个条目相同的语法表示。有效规则总是会被追加,例如即使其关键帧选择器已存在。
无返回值
无异常
5.3.5. deleteRule 方法
deleteRule 方法删除匹配指定关键帧选择器的最后声明的 CSSKeyframeRule。如果没有匹配的规则,该方法不执行任何操作。
参数
select类型为CSSOMString- 要删除规则的关键帧选择器:0% 到 100% 之间的逗号分隔百分比值列表,或分别解析为 0% 和 100% 的关键字 from 或 to。
指定关键帧选择器中值的数量和顺序必须与目标关键帧规则的值匹配。匹配对列表值周围的空格不敏感。
无返回值
无异常
5.3.6. findRule 方法
findRule 返回匹配指定关键帧选择器的最后声明的 CSSKeyframeRule。如果没有匹配的规则,该方法不执行任何操作。
参数
select类型为CSSOMString- 要查找的规则的关键帧选择器:由逗号分隔的 0% 到 100% 之间的百分比值列表,或者关键字 from 或 to,它们分别解析为 0% 和 100%。
指定关键帧选择器中值的数量和顺序必须与目标关键帧规则的值匹配。匹配对列表值周围的空格不敏感。
返回值
CSSKeyframeRule- 找到的规则。
无异常
@keyframes colorful-diagonal-slide {
from {
left: 0;
top: 0;
}
10% {
background-color: blue;
}
10% {
background-color: green;
}
25%, 75% {
background-color: red;
}
100% {
left: 100px;
top: 100px;
}
}
假设变量 anim 持有该动画的 CSSKeyframesRule 对象的引用,那么
anim.deleteRule('10%');
var tenPercent = anim.findRule('10%');
将首先删除最后的 10% 规则,即绿色背景颜色规则;然后找到剩余的蓝色背景规则并将其返回给 tenPercent。
以下代码
var red = anim.findRule('75%');
将把 red 设置为 null。必须使用红色背景颜色规则的完整选择器来代替
var red = anim.findRule('25%,75%');
由于 from 映射到 0%,而 to 映射到 100%,我们可以使用任一值找到这些规则
var from = anim.findRule('0%'); // Returns from { left: 0; top: 0; } rule
var to = anim.findRule('to'); // Returns 100% { left: 100px; top: 100px; } rule
5.4. GlobalEventHandlers 接口混入的扩展
本规范扩展了 HTML 中的 GlobalEventHandlers 接口混入,以添加 事件处理器 IDL 属性,用于 动画事件,具体定义见 § 4.3 元素、Document 对象和 Window 对象上的事件处理器。
5.4.1. IDL 定义
partial interface mixin GlobalEventHandlers {attribute EventHandler ;onanimationstart attribute EventHandler ;onanimationiteration attribute EventHandler ;onanimationend attribute EventHandler ; };onanimationcancel
6. 隐私注意事项
本规范未收到任何隐私问题报告。
7. 安全注意事项
本规范未收到任何安全问题报告。
8. 更改记录
8.1. 自 2018 年 10 月 11 日工作草案以来的变更
进行了以下实质性变更
- 为 CSSKeyframesRule 定义了索引属性 getter
- 在 AnimationEvent 的定义中添加了构造函数类型
- 在范围表示法中添加了所需的单位
- 将范围定义表示法应用于描述符和规则的前奏值
- 将范围定义表示法应用于属性值
- 将事件定义与它们的 EventHandler 容器关联起来
- 改进了产品定义的标记
- 修正了拼写错误(要查找的规则,而不是要删除的规则)
- 使值定义引用与其他 CSS 规范保持一致
- IDL 与 Web IDL 规范对齐
- 向构造函数添加了默认字典值
- 重写了令人困惑的示例 (#4118)
- 澄清了零持续时间动画的处理方式
- 使用“不可动画 (not animatable)”而非“无 (none)”
- 缓动函数 (easing functions) 现在被称为缓动函数
- 将 GlobalEventHandlers 更改为混入
9. 致谢
特别感谢 Tab Atkins、Brian Birtles、Shane Stephens、Carine Bournez、Christian Budde、Anne van Kesteren、Øyvind Stenhaug、Estelle Weyl 以及所有其他 www-style 社区成员提供的反馈。
10. 其他待解决问题
需要指定关键帧如何交互。
11. 等待编辑的工作组决议
本节为提示性内容且是临时的。
编辑人员目前在编辑本规范方面有所滞后。以下工作组决议仍需编辑加入
- 2014-09-09 会议记录 (Antibes 面对面会议)
- 问题(7335):详述关键帧值的计算方式/时间;使用 dbaron 邮件中的 G.beta
-
一致同意转换和动画都应为所有属性设置动画。由 css-transitions 定义非交互/离散值的动画。它们在缓动函数进度 50% 以下时取起始值,在 50% 以上时取结束值 -
对动画属性/关键帧的动态更改。由 Tab 提出决议。(Bug 14713) -
负的 animation-delay 值作用于动画的活跃持续时间,即 (animation-duration*animation-iteration-count)。因此,延迟可能会吞掉不会触发迭代事件的迭代。开始/结束事件仍会触发。即使在延迟 == (-1*active_duration) 时 -
当 animation-duration 为零时触发动画开始/结束事件,elapsedTime 为 0 -
如果 animation-iteration-count 为无限且持续时间为 0,则将迭代次数视为有限,并运行 0 秒(Brian 邮件中的选项 A) -
如果带有负动画延迟的动画最初处于暂停状态,开始事件仍会触发
- 2012-10-29 会议记录
-
将动画属性更改为可动态更改 -
@keyframes 可以动态更改 -
当遇到重复的动画名称时,以最后一个为准。 -
使 *动画* 转换 *所有* 属性。除非另有说明,离散属性在缓动函数进度 50% 以下取起始值,在 50% 以上取结束值。
-
- 2012-12-12 会议记录及中间评论
和 2012-12-19 会议记录 - 2013-02-20 会议记录
-
接受 Øyvind 的澄清 -
关键帧规则层叠 (cascade) -
将 pseudoElement 标记为有风险
-
- 2013-05-30 会议记录
-
对非交互式媒体中动画的预期
-
- 2014-01-27 会议记录
-
删除关于等待文档加载的文本
-