1. 引言
本节不具规范性。
本文档介绍了用于实现隐式过渡的新 CSS 特性,用来描述如何让 CSS 属性在给定的持续时间内,从一个值平滑地变化为另一个值。
测试
crashes
- delete-image-set.html (实时测试) (源码)
- size-container-transition-crash.html (实时测试) (源码)
- transition-during-style-attr-mutation.html (实时测试) (源码)
- transition-large-word-spacing-001.html (实时测试) (源码)
1.1. 值定义
本规范遵循CSS 属性定义约定,并使用来自值定义语法。 未在本规范中定义的值类型,可在 CSS Values & Units [CSS-VALUES-3] 中查阅。 与其他 CSS 模块结合时,这些值类型的定义可能会被扩展。
除了在属性定义中列出的特定值外,本规范中定义的所有属性也接受CSS 通用关键字 作为属性值。为了易读性,这些内容没有被显式重复。
2. 过渡
通常当 CSS 属性的值发生变化时,渲染结果会立刻更新,被影响的元素会立即从旧属性值变为新属性值。本节描述了如何使用新的 CSS 属性来指定渐变过渡,能让属性值在一段时间内平滑地从旧状态变为新状态。
例如,假设在left 和 background-color 属性上定义了一秒钟的过渡。下图展示了更新这些属性时的效果,此时元素向右移动,背景色从红色变为蓝色。假定其他过渡参数仍为默认值。
过渡是一种表现效果。已计算值会在旧值与新值之间随时间变化。如果脚本在过渡期间查询一个属性的已计算值(或依赖该属性的数据),将会获取到一个当前动画的中间值。
每个用于定义过渡的属性都通过新的 CSS 属性实现。例如:
div {
transition-property: opacity;
transition-duration: 2s;
}
上方示例为 opacity
属性定义了一个过渡,当为其赋值时,将在两秒时间里平滑地从旧值过渡到新值。
每个过渡属性都可以接受逗号分隔的值列表,从而允许定义多个过渡,每条过渡作用于不同的属性。在这种情况下,每个过渡的参数都取自所有列表中的同一索引。例如:
div {
transition-property: opacity, left;
transition-duration: 2s, 4s;
}
此示例会使 opacity
属性在两秒内平滑变化,left 属性则在四秒内平滑变化。
当 transition 属性中的值列表长度不一致时,transition-property 列表的长度决定了启动过渡时各列表匹配的项数。列表从头开始对应:多余的值会被丢弃。如果某一属性值表长度不足以和 transition-property 匹配,用户代理需循环使用该表的值直到足够。这一截断或循环不会影响计算值。 注意:这与 background-* 属性的行为类似,background-image 类似于 transition-property。
div {
transition-property: opacity, left, top, width;
transition-duration: 2s, 1s;
}
上例为 opacity
属性定义了 2 秒过渡,为 left 属性定义了 1
秒过渡,
top 属性为 2 秒过渡,
width
属性为 1 秒过渡。
虽然作者可用过渡创建动态内容,动态变化的内容可能会引发部分用户癫痫发作。关于如何避免可能诱发癫痫的内容,请参见 指南 2.3: 癫痫发作: 不要以已知可引发癫痫的方式设计内容 ([WCAG20])。
测试
- animate-with-color-mix.html (实时测试) (源码)
- color-transition-premultiplied.html (实时测试) (源码)
- text-shadow-composition.html (实时测试) (源码)
- text-shadow-interpolation.html (实时测试) (源码)
- vertical-align-composition.html (实时测试) (源码)
- vertical-align-interpolation.html (实时测试) (源码)
- z-index-interpolation.html (实时测试) (源码)
- idlharness.html (实时测试) (源码)
- inherit-background-color-transition.html (实时测试) (源码)
- inheritance.html (实时测试) (源码)
- properties-value-001.html (实时测试) (源码)
- properties-value-002.html (实时测试) (源码)
- properties-value-003.html (实时测试) (源码)
- properties-value-implicit-001.html (实时测试) (源码)
- retargetted-transition-with-box-sizing.html (实时测试) (源码)
- shadow-root-insertion.html (实时测试) (源码)
- transition-base-response-001.html (实时测试) (源码)
- transition-base-response-002.html (实时测试) (源码)
- transition-base-response-003.html (实时测试) (源码)
- transition-in-iframe-001.html (实时测试) (源码)
2.1. transition-property 属性
transition-property 属性用于指定应用过渡的 CSS 属性名称。
| 名称: | transition-property |
|---|---|
| 值: | none | <single-transition-property># |
| 初始值: | all |
| 适用于: | 所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 关键字 none 或标识符列表 |
| 规范顺序: | 按语法 |
| 动画类型: | 不可动画 |
测试
- move-after-transition.html (实时测试) (源码)
- transition-end-event-shorthands.html (实时测试) (源码)
- transition-property-computed.html (实时测试) (源码)
- transition-property-invalid.html (实时测试) (源码)
- transition-property-valid.html (实时测试) (源码)
- pseudo-element-transform.html (实时测试) (源码)
- pseudo-elements-001.html (实时测试) (源码)
- pseudo-elements-002.html (实时测试) (源码)
- transition-background-position-with-edge-offset.html (实时测试) (源码)
- transition-property-001.html (实时测试) (源码)
- transition-property-002.html (实时测试) (源码)
- transition-property-003-manual.html (人工测试) (源码)
- transition-property-004-manual.html (人工测试) (源码)
- transition-property-005-manual.html (人工测试) (源码)
- transition-property-006-manual.html (人工测试) (源码)
- transition-property-007-manual.html (人工测试) (源码)
- transition-property-008-manual.html (人工测试) (源码)
- transition-property-009-manual.html (人工测试) (源码)
- transition-property-010-manual.html (人工测试) (源码)
- transition-property-011-manual.html (人工测试) (源码)
- transition-property-012-manual.html (人工测试) (源码)
- transition-property-013-manual.html (人工测试) (源码)
- transition-property-014-manual.html (人工测试) (源码)
- transition-property-015-manual.html (人工测试) (源码)
- transition-property-016-manual.html (人工测试) (源码)
- transition-property-017-manual.html (人工测试) (源码)
- transition-property-018-manual.html (人工测试) (源码)
- transition-property-019-manual.html (人工测试) (源码)
- transition-property-020-manual.html (人工测试) (源码)
- transition-property-021-manual.html (人工测试) (源码)
- transition-property-022-manual.html (人工测试) (源码)
- transition-property-023-manual.html (人工测试) (源码)
- transition-property-024-manual.html (人工测试) (源码)
- transition-property-025-manual.html (人工测试) (源码)
- transition-property-026-manual.html (人工测试) (源码)
- transition-property-027-manual.html (人工测试) (源码)
- transition-property-028-manual.html (人工测试) (源码)
- transition-property-029-manual.html (人工测试) (源码)
- transition-property-030-manual.html (人工测试) (源码)
- transition-property-031-manual.html (人工测试) (源码)
- transition-property-032-manual.html (人工测试) (源码)
- transition-property-033-manual.html (人工测试) (源码)
- transition-property-034-manual.html (人工测试) (源码)
- transition-property-035-manual.html (人工测试) (源码)
- transition-property-036-manual.html (人工测试) (源码)
- transition-property-037-manual.html (人工测试) (源码)
- transition-property-038-manual.html (人工测试) (源码)
- transition-property-039-manual.html (人工测试) (源码)
- transition-property-040-manual.html (人工测试) (源码)
- transition-property-041-manual.html (人工测试) (源码)
- transition-property-042-manual.html (人工测试) (源码)
- transition-property-043-manual.html (人工测试) (源码)
- transition-property-044-manual.html (人工测试) (源码)
- transition-property-045-manual.html (人工测试) (源码)
- transition-test.html (实时测试) (源码)
- transition-zero-duration-with-delay.html (实时测试) (源码)
none 的值表示不进行任何属性过渡。其它情况下需指定将要进行过渡的属性列表,或指定关键字 all,表示所有属性都要进行过渡。
如果列表中的标识符有不是已知属性名,实际实现仍需在该列表的可动画属性上应用对应索引处的持续时长、延迟和时间函数。换句话说,未识别的属性必须保留在列表中以保证序号对应。
<custom-ident> 在 <single-transition-property> 的生成式还排除了 none,以及所有被 <custom-ident> 排除的关键字。这意味着 none、inherit 和 initial 不允许出现在多个标识符的列表中,出现则语法无效。
关键字 all 出现时,或者指定的是简写属性,浏览器实现需对所有长属性(或 all 时为所有属性)依序应用时长、延迟和时间函数。
如果某个属性在 transition-property 的值中被多次指定(如直接写多次、被包含在简写、或通过 all),则以该属性在 transition-property 列表中最后一次出现的索引所对应的时长、延迟和时间函数为准。
注:all 和 all 简写的工作方式类似,all 值等价于覆盖所有属性的一个简写属性。
2.2. transition-duration 属性
transition-duration 属性定义了过渡所需的事件时长。
| 名称: | transition-duration |
|---|---|
| 值: | <time [0s,∞]># |
| 初始值: | 0s |
| 适用于: | 所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 列表,每项为时长 |
| 规范顺序: | 按语法 |
| 动画类型: | 不可动画 |
测试
- infinite-duration-crash.html (实时测试) (源码)
- transition-duration-computed.html (实时测试) (源码)
- transition-duration-invalid.html (实时测试) (源码)
- transition-duration-valid.html (实时测试) (源码)
- transition-duration-001.html (实时测试) (源码)
- transition-duration-002-manual.html (人工测试) (源码)
- transition-duration-003-manual.html (人工测试) (源码)
- transition-duration-004-manual.html (人工测试) (源码)
- transition-duration-shorthand.html (实时测试) (源码)
此属性指定从旧值到新值的过渡持续时间。默认值为 0s,即过渡立即发生(无动画)。transition-duration 的负值会导致声明无效。
2.3. transition-timing-function 属性
transition-timing-function 属性用于描述过渡期间中间值的计算方式。它允许在整个过渡时长内改变速度。这种效果通常被称为 缓动 函数。
时间函数在独立的 CSS 缓动函数模块 [css-easing-1] 定义。 使用的 输入进度值 是过渡时长的百分比,输出进度值 则作为插值属性值的 p 值使用(参见 第4节 过渡应用)。
| 名称: | transition-timing-function |
|---|---|
| 值: | <easing-function># |
| 初始值: | ease |
| 适用于: | 所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 按指定 |
| 规范顺序: | 按语法 |
| 动画类型: | 不可动画 |
测试
- transition-timing-function.html (实时测试) (源码)
- transition-timing-function-computed.html (实时测试) (源码)
- transition-timing-function-invalid.html (实时测试) (源码)
- transition-timing-function-valid.html (实时测试) (源码)
- transition-timing-function-002-manual.html (人工测试) (源码)
- transition-timing-function-003-manual.html (人工测试) (源码)
- transition-timing-function-004-manual.html (人工测试) (源码)
- transition-timing-function-005-manual.html (人工测试) (源码)
- transition-timing-function-006-manual.html (人工测试) (源码)
- transition-timing-function-010-manual.html (人工测试) (源码)
2.4. transition-delay 属性
transition-delay 属性定义了过渡的开始时间。它允许在应用后经过一段时间再启动过渡。当 transition-delay 的值为 0s 时,属性值发生变化后立即执行过渡。否则,数值指定从属性变化到过渡启动间的延时时间。
如果 transition-delay ���值是负时间,则属性变化后立即执行过渡,但会表现为过渡已在指定偏移处运行,即过渡从动画周期的中间插入。如果该过渡有隐式的起始值且 transition-delay 为负,则起始值取自属性值变化的时刻。
| 名称: | transition-delay |
|---|---|
| 值: | <time># |
| 初始值: | 0s |
| 适用于: | 所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 列表,每项为时长 |
| 规范顺序: | 按语法 |
| 动画类型: | 不可动画 |
测试
- transition-delay-computed.html (实时测试) (源码)
- transition-delay-invalid.html (实时测试) (源码)
- transition-delay-valid.html (实时测试) (源码)
- transition-delay-000-manual.html (人工测试) (源码)
- transition-delay-001.html (实时测试) (源码)
- transition-delay-002-manual.html (人工测试) (源码)
- transition-delay-003-manual.html (人工测试) (源码)
2.5. transition 简写属性
transition 简写属性将上述四个属性合并为一个属性。
| 名称: | transition |
|---|---|
| 值: | <single-transition># |
| 初始值: | 见各自属性 |
| 适用于: | 所有元素 |
| 继承性: | no |
| 百分比: | N/A |
| 计算值: | 见各自属性 |
| 动画类型: | 不可动画 |
| 规范顺序: | 按语法 |
测试
注意,该属性中各值的顺序很重要:能够被解析为时间的第一个值赋给 transition-duration,第二个赋给 transition-delay。
如果简写中有多个 <single-transition>,且某个子项的 <single-transition-property> 为 none,则声明无效。
3. 过渡的开始
实现必须维护一组正在运行的过渡, 每个过渡应用于特定的元素和非简写属性。每个过渡还具有开始时间、结束时间、起始值、结束值、反转调整起始值,以及反转缩短因子。 过渡的添加见本节说明,完成或要求取消时从集合中移除。关于 反转调整起始值与反转缩短因子的原理,见§ 3.1 中断过渡的快速反转。
实现还必须维护一组已完成的过渡, 每个(如正在运行的过渡) 也是应用于特定元素和非简写属性。本规范保证同一属性和元素不会同时存在正在运行的过渡和已完成的过渡。
如果元素不再在文档中,实现必须取消其上的任何正在运行的过渡以及从已完成的过渡集合中移除该元素的过渡。
维护已完成过渡集合可以防止某些情况下过渡反复重启, 即维持本规范要保证的不相关样式变化不会触发过渡的规则。
例如,对于一个继承属性的过渡, 父元素为该属性设置了较长期限的过渡(如transition: 4s text-indent), 而子元素继承父属性值但又为同属性设置了较短时长的过渡(如 transition: 1s text-indent)。 如果不维护已完成的过渡集合,则每次子元素一秒过渡结束后,实现会再为该子元素重新启动过渡。
多种操作可能导致元素属性的已计算值 发生变化, 包括元素在文档树的插入或移除(影响是否有已计算值,还可能由于选择器匹配影响其他元素样式), 文档树结构变化引发选择器匹配变化、样式表或 style 属性变化等。 本规范不规定何时更新已计算值, 只要求实现不得在 CSS 级联、值计算和继承流程结果未更新已计算值时使用、展示或显示结果 (也就是说,不能以未更新已计算值为由规避规范要求,变更样式时必须更新)。 不过,当实现针对某个元素属性的已计算值发生这些变化时, 或某元素新加到文档树时计算其已计算值, 必须同步更新所有属性与元素的已计算值,保证看起来所有属性都同时变化 (至少不能被检测出是不同步变化)。 这组同时发生的样式变更处理称为样式更改事件。 (通常实现会将样式更改事件与期望的屏幕刷新率对应, 当脚本 API 需要最新的计算样式或布局信息时进行。)
由于本规范不定义样式更改事件的发生时机, 因此哪些已计算值变化被视为同时发生是未定义的。 作者应注意,若在可能产生过渡的属性变化后短时间内又修改任何过渡相关属性,可能导致不同实现间表现差异,因为某些实现会认为是同时变化,某些则不会。
当发生样式更改事件时,实现必须针对该事件发生变化的已计算值启动过渡。 若元素在本次或上次样式更改事件时不在文档树,则本事件不为该元素启动过渡。 否则,定义变化前样式为 元素在上一次样式更改事件时所有属性的已计算值, 只是将由 CSS 过渡、CSS 动画 ([CSS3-ANIMATIONS])、SMIL 动画([SMIL-ANIMATION],[SVG11]) 产生的动画样式更新到当前时刻。 同样,变化后样式定义为 元素在本次样式更改事件开始时,根据当时信息计算出的所有属性已计算值, 但动画相关属性(animation-*)采用变化前样式值, 且排除过渡样式,继承父元素的变化后样式。 注意,这意味着变化后样式不会因新建或取消 CSS 动画而与变化前样式不同。
测试
注意:对变化后样式的定义意味着一次变化可能在同一属性上 同时为祖先和后代都启动过渡。 当属性变化由带transition-*属性的元素继承到另一个同样带transition-*属性的元素时会发生这种情况。
这时会同时运行两条过渡,后代的过渡会根据 CSS 级��和继承规则 覆盖祖先的过渡([CSS3CASCADE])。
如果后代的过渡早于祖先的过渡完成,则后代会继续继承 父级仍在过渡中的值。 这样的效果通常不是设计者所希望的,但这实际上正好做了作者要求的事。
对于每个既有变化前样式又有变化后样式的元素,以及每个属性(非简写), 定义匹配的 transition-property 值为 元素变化后样式中 transition-property 最后一个与该属性匹配的值, 具体见§ 2.1 transition-property 属性。 若存在该值,则对应有匹配的 transition duration、 匹配的 transition delay 和 匹配的 transition timing function, 分别取自变化后样式的transition-duration、transition-delay 和 transition-timing-function(参见关于列表匹配的规则)。 定义该过渡的组合时长 为 max(匹配的 transition duration, 0s) 与 匹配的 transition delay 之和。
当比较某属性的变化前样式和变化后样式时, 若该属性值的动画类型既不是不可动画 也不是离散, 则被认为是可过渡。
注意:即使某属性定义的动画类型并不是离散, 某个特定的属性值对也可能动画类型为离散。 例如,box-shadow属性的动画类型为阴影列表, 其定义中如果有一个值没有inset关键字而另一个有,则使用离散动画。 因此0px 0px black和inset 10px 10px black不是可过渡的。
每个元素和属性,实现应按如下流程处理:
-
如同时满足以下条件:
- 元素没有该属性的正在运行的过渡,
- 该属性的变化前样式与 变化后样式不同,且两值为可过渡值,
- 元素没有该属性的已完成的过渡 或结束值与变化后样式不同,
- 存在匹配的 transition-property 值,
- 组合时长大于0s,
- 否则,如元素有该属性的已完成的过渡,且结束值与变化后样式值不同, 则从已完成的过渡集合中移除该过渡。
- 若元素有正在运行的过渡或已完成的过渡,但不存在匹配的 transition-property 值, 则实现必须取消正在运行的过渡或移除已完成的过渡。
-
如果元素有该属性的正在运行的过渡,存在匹配的
transition-property 值,且
结束值与
变化后样式值不等,则:
- 若该属性的当前值 等于变化后样式的值, 或二者不是可过渡, 实现必须取消正在运行的过渡。
- 否则,若组合时长小于等于0s, 或 当前值与 变化后样式值不可过渡, 则实现必须取消正在运行的过渡。
-
否则,若反转调整起始值
等于变化后样式(具体缘由见过渡反转小节),
实现必须取消正在运行的过渡并启动新过渡,其:
- 反转调整起始值为 结束值 (表示逻辑上的起始状态,允许某些计算忽略实际过渡启动的时刻,有助于反复反转操作能正确表现)
- 反转缩短因子 为下式绝对值后截断到[0,1]的结果: 表示旧过渡已穿越过的区间比例(数值空间,不是时间),绝对值和截断用于处理计时函数y1或y2超[0,1]的情形。
-
开始时间为
样式更改事件时间加上:
- 如匹配的 transition delay为非负, 则取匹配的 transition delay
- 若为负,则取新过渡反转缩短因子与 匹配的 transition delay的积
- 结束时间为 开始时间加上 匹配的 transition duration与新过渡反转缩短因子的积
- 起始值为 当前值
- 结束值为 变化后样式值
- 否则,实现应取消正在运行的过渡并启动新过渡,其:
注意,上述规则意味着 当可动画属性的已计算值改变时, 启动的过渡基于 transition-property、 transition-duration、 transition-timing-function 和 transition-delay 的当前值。 换言之,如果某个 transition-* 属性与可能触发过渡的属性同步变化,使用的是新值。
这样,作者可以为“正向”和“反向”过渡分别指定不同的 transition-* 属性取值(但若为未完成的过渡被打断,见下文反转机制)。可以在定义触发过渡的规则里定义 transition-duration、transition-timing-function 或 transition-delay,也可与目标属性同时更改。因为使用的是这些属性的新值,所以过渡总是向目标状态使用新值。例如:
li {
transition: background-color linear 1s;
background: blue;
}
li:hover {
background-color: green;
transition-duration: 2s; /* 作用于到 :hover 状态的过渡 */
}
当列表项进入 :hover 状态时,transition-duration 此时是 2s, 所以 background-color 从 blue 到 green 过渡需2秒。 离开:hover 后,green 到 blue 只需1秒。
注意:一旦某属性的过渡启动(包括延时阶段),即使transition-timing-function、transition-duration 或 transition-delay 变化,动画仍按原值运行。若transition-property变为使当前过渡不应发生,则动画终止(属性立即变为最终值)。
注意:上述规则也意味着 声明式动画导致属性计算值变化时不会触发过渡。 因为变化前样式里包含了动���的最新样式。
测试
- before-load-001.html (实时测试) (源码)
- changing-while-transition-001.html (实时测试) (源码)
- changing-while-transition-002.html (实时测试) (源码)
- changing-while-transition-003.html (实时测试) (源码)
- changing-while-transition-004.html (实时测试) (源码)
- currentcolor-animation-001.html (实时测试) (源码)
- disconnected-element-001.html (实时测试) (源码)
- dynamic-root-element.html (实时测试) (源码)
- historical.html (实时测试) (源码)
- inherit-height-transition.html (实时测试) (源码)
- non-rendered-element-001.html (实时测试) (源码)
- non-rendered-element-002.html (实时测试) (源码)
- properties-value-inherit-001.html (实时测试) (源码)
- properties-value-inherit-002.html (实时测试) (源码)
- properties-value-inherit-003.html (实时测试) (源码)
- starting-of-transitions-001.html (实时测试) (源码)
- root-color-transition.html (实时测试) (源码)
- transition-after-animation-001.html (实时测试) (源码)
- transition-remove-and-change-immediate.html (实时测试) (源码)
- transition-reparented.html (实时测试) (源码)
- transitions-retarget.html (实时测试) (源码)
- zero-duration-multiple-transition.html (实时测试) (源码)
3.1. 中断过渡的快速反转
许多常见的过渡效果涉及在两个状态之间进行转换,比如当鼠标指针移入某个界面元素又移出时的过渡。在这些效果中,过渡常常在尚未完成前被打断,属性会被重置为该过渡的起始值。比如一个元素的悬停效果,指针进入元素时触发过渡,效果尚未结束之前指针移出。如果离开和进入的过渡都按各自指定的时长和计时函数执行,第二次过渡会在较短的距离内也耗费整个时长,显得很不协调。因此本规范规定,第二次过渡应适当缩短时长。
上述规则采纳的机制包括 反转缩短因子 和 反转调整起始值。尤其是当 反转缩短因子 小于 1 时,就体现出反转行为。
注意,这些规则并未完全解决涉及多于两个状态的过渡模式问题。
注意,这些规则会让新过渡完整使用其计时函数,而不是直接跳转到计时函数的中途,以避免动画突兀感。
这是工作组讨论的诸多方案之一,具体可参考 反转演示,并据此于2013-06-07达成决议、2013-11-11做出修订。
4. 过渡的应用
当元素上的某个属性正在经历过渡(即,过渡已开始且尚未到 结束时间 时),过渡会在 [CSS3CASCADE] 中 CSS 过渡规定的级联层级新增一个叫做 当前值 的样式。
注意:这意味着由 CSS 过渡产生的已计算值像其它已计算值一样可以被后代继承。通常,继承属性的过渡也会影响其后代元素,跟作者预期一致。
仅当该属性当前没有在该元素上经历 CSS 动画([CSS3-ANIMATIONS])时,实现才应把它加入级联。
注意:同一元素同一属性若有动画正在运行,则过渡不会加入级联,但这不影响过渡本身是否已启动或已结束。向外暴露过渡是否正在运行的 API(如 transition 事件)仍会报告过渡正在运行。
如果当前时刻等于或早于过渡的 开始时间(即处于延迟阶段),此时 当前值 是会被计算为过渡 起始值 的指定样式。
如果当前时刻晚于过渡的 开始时间(即处于持续阶段),当前值 是会被计算为如下插值结果的指定样式:
5. 过渡的完成
正在运行的过渡 会在等于或晚于其结束时间,但位于首个大于等于该结束时间的 样式更改事件之前 完成。 当过渡完成时,实现必须将此刻完成的所有过渡从 正在运行的过渡 集合移动到 已完成的过渡 集合,并为这些完成的过渡触发 事件。(注意:如果顺序相反,比如事件先于转移集合前触发,可能导致必要过渡未完成时就发生样式更改事件,因为事件处理如果请求样式或布局会产生样式更改事件。)
6. 过渡事件
CSS 过渡的创建、开始、完成和取消会产生对应的 DOM 事件。每个属性的过渡会将事件 派发 给发生过渡的那个元素,让开发者可以针对过渡同步执行操作。
每个事件都会提供发生过渡的属性名及该过渡的持续时间。
6.1.
接口 TransitionEvent
接口 TransitionEvent
提供与过渡相关的特定上下文信息。
6.1.1. IDL 定义
[Exposed =Window ]interface :TransitionEvent Event {constructor (CSSOMString ,type optional TransitionEventInit = {});transitionEventInitDict readonly attribute CSSOMString propertyName ;readonly attribute double elapsedTime ;readonly attribute CSSOMString pseudoElement ; };dictionary :TransitionEventInit EventInit {CSSOMString = "";propertyName double = 0.0;elapsedTime CSSOMString = ""; };pseudoElement
6.1.2. 属性
propertyName, 类型为 CSSOMString,只读-
与过渡关联的 CSS 属性名。
注:这里总是长属性名。关于如何指定简写属性会引起长属性过渡,见 transition-property。
elapsedTime, 类型为 double,只读-
事件触发时过渡已运行的时间(秒),不包含延迟阶段。该成员的计算方法随各自事件类型定义。
pseudoElement, 类型为 CSSOMString,只读-
发生过渡的 CSS 伪元素名称(以两冒号开头),如果是元素本身则为空字符串,这意味着事件目标为该元素。
是一个 事件构造函数。TransitionEvent(type, transitionEventInitDict)
6.2. TransitionEvent 的类型
可能发生的过渡事件类型包括:
transitionrun-
transitionrun事件在创建过渡(即加入 正在运行的过渡 集合时)触发。若 transition-delay 为负,事件的
elapsedTime等于 delay 的绝对值,并受动画 transition-duration 限制,即min(max(-transition-delay, 0), transition-duration)。- 冒泡:是
- 可取消:否
- 上下文信息:propertyName、elapsedTime、pseudoElement
transitionstart-
transitionstart事件在过渡延迟阶段结束时触发。elapsedTime的值与transitionrun事件一致。- 冒泡:是
- 可取消:否
- 上下文信息:propertyName、elapsedTime、pseudoElement
transitionend-
transitionend事件在过渡完成时触发。如果过渡未完成即移除(如取消 transition-property),则不会触发此事件。该事件的
elapsedTime值等于 transition-duration。- 冒泡:是
- 可取消:否
- 上下文信息:propertyName、elapsedTime、pseudoElement
transitioncancel-
transitioncancel事件在过渡被 取消 时触发。elapsedTime是从过渡延迟结束到取消时所运行的秒数。 如果过渡为负 transition-delay, 则过渡起点为实际触发前 transition-delay 的绝对值秒的时刻。 如果为正 transition-delay 且事件在延迟期内触发,则elapsedTime为零。- 冒泡:是
- 可取消:否
- 上下文信息:propertyName、elapsedTime、pseudoElement
6.3. 元素、Document 对象和 Window 对象上的事件处理程序
下表是所有 事件处理程序(及对应 事件处理事件类型)的支持要求:所有 HTML 元素必须同时支持 事件处理内容属性和 事件处理 IDL 属性,所有 Document
和 Window
也必须以 事件处理 IDL 属性 形式支持:
| 事件处理程序 | 事件类型 |
|---|---|
ontransitionrun
| transitionrun |
ontransitionstart
| transitionstart |
ontransitionend
| transitionend |
ontransitioncancel
| transitioncancel |
7. DOM 接口
本规范扩展了 HTML 的 GlobalEventHandlers
接口混入,新增 事件处理 IDL 属性,用于 过渡事件,详见
§ 6.3 元素、Document 和 Window
上的事件处理程序。
7.1. IDL 定义
partial interface mixin GlobalEventHandlers {attribute EventHandler ;ontransitionrun attribute EventHandler ;ontransitionstart attribute EventHandler ;ontransitionend attribute EventHandler ; };ontransitioncancel
8. 安全性注意事项
本节不具规范性。
本规范的安全风险有限,不会使网页内容获得以前无法实现的能力。它只是支持将脚本能做的事声明式表达,便于实现(如帧率和CPU优化)。
实现可做的主要优化之一是让某些关键属性(如 transform 和 opacity)的动画可以在浏览器的合成线程或进程中运行,无需在主线程更新样式与布局(除非确需最新样式数据)。这种优化往往需要为动画元素分配图形内存。实现时应注意防止通过大量动画或超大区域动画(面积可指变换前后)诱发不安全的内存溢出处理。
9. 隐私注意事项
本节不具规范性。
本规范的隐私风险有限,不会使网页内容获得以前无法实现的能力。
本规范可能会增加一些机制,有助于识别用户硬件或软件特征。然而,判断性能特征是许多Web技术的普遍能力,本规范未引入新途径。
如 § 10 可访问性注意事项 所述,实现可为有障碍的用户提供防护。这些防护有可能被网页内容检测到,因此受益用户或需在保护隐私与获得便利之间平衡。
10. 可访问性注意事项
本节不具规范性。
10.1. 动画与运动
本规范为原需脚本实现的动画提供了声明式机制。声明式机制一方面更易制作并有助于动画普及,另一方面也让用户代理更易于根据用户无障碍需求对动画做出调整。
因此,对于对运动敏感或需要更多阅读和理解时间的用户,可通过用户代理的功能禁用或减慢动画获得便利。(但关于此类防护的隐私影响,见 § 9 隐私注意事项)
用户代理开发者应注意,网页内容可能依赖 过渡事件 的触发,因此防护机制可能希望即使未展示过渡动画也触发事件。但网页内容依赖此类事件通常不是良好实践。
10.2. 级联
CSS 的 级联 是允许用户需求与作者样式交互的通用机制。本规范与级联机制配合,但原则上仅允许在级联规则现有值之间做动画,不妨碍用户强制 CSS 属性取特定值。
级联同样允许用户通过覆盖过渡属性来完全禁用过渡。
11. 变更
11.1. 自 2018 年 10 月 11 日工作草案以来的变更
自 2018 年 10 月 11 日工作草案 以来的实质性变更如下:
-
明确
GlobalEventHandlers是一个 mixin。 -
用 <easing-function> 替换了废弃的
<timing-function>。 -
为
transitionEventInitDict字典增加了默认值。 -
移除 <single-transition-property> 语法中的尾部分号。
-
将事件定义与其
GlobalEventHandlers容器关联。 -
为属性值增加了范围定义标记。
-
增加了 Web Platform Tests 覆盖。
-
细微的编辑修正与改进。
关于上述变更的更多详情,见版本控制 变更日志。
11.2. 早期变更
欲知早期工作草案的变更:
-
欲知更多变更详情,参考版本控制变更日志(因文件重命名分为多部分):
12. 致谢
特别感谢 Tab Atkins, Carine Bournez, Aryeh Gregor, Vincent Hardy, Anne van Kesteren, Cameron McCormack, Alex Mogilevsky, Jasper St. Pierre, Estelle Weyl, 以及 www-style 社区的所有成员的反馈。
测试
与本规范后续级别相关的测试
- allow-discrete-auto-inset.html (实时测试) (源码)
- custom-property-and-allow-discrete.html (实时测试) (源码)
- display-none-no-animations.html (实时测试) (源码)
- idlharness-2.html (实时测试) (源码)
- inert-while-transitioning-to-display-none.html (实时测试) (源码)
- starting-style-parsing.html (实时测试) (源码)
- transition-behavior.html (实时测试) (源码)
- starting-style-adjustment.html (实时测试) (源码)
- starting-style-cascade.html (实时测试) (源码)
- starting-style-first-letter-crash.html (实时测试) (源码)
- starting-style-name-defining-rules.html (实时测试) (源码)
- starting-style-rule-basic.html (实时测试) (源码)
- starting-style-rule-none.html (实时测试) (源码)
- starting-style-rule-pseudo-elements.html (实时测试) (源码)
- starting-style-size-container.html (实时测试) (源码)
- transition-behavior.html (实时测试) (源码)
- transition-behavior-events.html (实时测试) (源码)