CSS 视图转换模块 第2级

W3C 工作草案,

关于本文档的更多详情
此版本:
https://www.w3.org/TR/2024/WD-css-view-transitions-2-20241113/
最新发布版本:
https://www.w3.org/TR/css-view-transitions-2/
编辑草案:
https://drafts.csswg.org/css-view-transitions-2/
历史记录:
https://www.w3.org/standards/history/css-view-transitions-2
反馈:
CSSWG 问题仓库
规范内联
编辑:
Noam Rosenthal (Google)
Khushal Sagar (Google)
Vladimir Levin (Google)
Tab Atkins-Bittner (Google)
为此规范建议修改:
GitHub 编辑器

摘要

本模块定义了视图转换 API 如何与跨文档导航配合工作。

CSS 是一种用于描述结构化文档(如 HTML 和 XML)在屏幕、纸张等媒介上渲染的语言。

本文档状态

本节描述了本文档在发布时的状态。 当前 W3C 出版物列表 以及本技术报告的最新修订版 可在 W3C 技术报告索引 https://www.w3.org/TR/ 中找到。

本文档由 CSS 工作组 作为工作草案 使用 推荐标准 流程 发布。 作为工作草案发布 并不意味着获得 W3C 及其成员的认可。

这是一份草案文档, 随时可能被其他文档更新、替换 或废弃。 将本文档引用为进行中的工作以外的内容是不合适的。

请通过 在 GitHub 提交问题(首选)发送反馈, 在标题中包含规范代码 "css-view-transitions",如下所示: "[css-view-transitions] …评论摘要…"。 所有问题和评论都已 存档。 或者,反馈可以发送到(已存档)公共邮件列表 www-style@w3.org

本文档受 2023年11月3日 W3C 流程文档 管辖。

本文档由在 W3C 专利政策 下运作的工作组制作。 W3C 维护一个 与该工作组交付成果相关的专利披露公开列表; 该页面还包含披露专利的说明。 实际了解包含 基本权利要求 专利的个人必须根据 W3C 专利政策第6节 披露信息。

1. 介绍

本节为非规范性内容。

视图转换,如 [css-view-transitions-1] 中所规定的,是一个允许开发者 在文档的视觉状态之间创建动画转换的功能。

第2级扩展了该规范,通过添加必要的 API 和生命周期来启用 跨同源跨文档导航的转换,以及一些让编写具有更丰富视图转换的页面变得更容易的附加功能。

第2级定义了以下内容:

2. 跨文档视图转换

2.1. 概述

本节为非规范性内容。

2.1.1. 激活

对于同文档视图转换,作者通过调用 startViewTransition 使用 JavaScript 来启动视图转换。 在跨文档视图转换中,触发视图转换的是两个文档之间的导航,只要满足以下条件:

详细信息请参见生命周期部分。

2.1.2. 等待新状态稳定

在同文档视图转换中,作者可以使用传递给 startViewTransition 的回调来指示转换的新状态何时处于稳定状态。 由于跨文档视图转换是声明性的,因此没有这样的显式承诺。相反,用户代理依赖渲染阻塞机制来决定文档何时达到稳定状态。 通过这种方式,作者可以使用 blocking 属性来延迟转换,直到:

注意:过度使用渲染阻塞机制可能会使 旧状态长时间保持冻结,导致用户体验不佳。 为了避免这种情况,建议确保渲染阻塞元素能及时可用。

在这个例子中,旧文档的最后一帧将会显示,动画将被延迟, 直到满足以下所有条件:

<!DOCTYPE html>
<html>
    <head>
        < !-- 这将默认阻塞渲染 -->
        <link rel="stylesheet" href="style.css">

        < !-- 由于这个脚本修复了布局,将其标记为渲染阻塞将
                确保在视图转换激活之前运行它 -->
        <script async href="fixup.js" blocking="render"></script>

        < !-- 等待 main-article 元素被看到并完全解析后
                再激活转换 -->
        <link rel="expect" href="#main-article" blocking="render">
    </head>
    <body>
        <header>...</header>
        <main>
            <article id="main-article">...</article>
        </main>
        <article id="secondary-article">...</article>
    </body>
</html>

2.1.3. 自定义

ViewTransition 对象允许在脚本中自定义转换。 同文档视图转换使用从 startViewTransition 调用返回的单个 ViewTransition 对象来处理整个生命周期。 跨文档视图转换有两个 ViewTransition 对象,一个在旧文档中,一个在新文档中。
2.1.3.1. 在旧文档中处理视图转换

pageswap 事件在文档即将被卸载并被另一个文档替换之前的最后时刻触发。 它可以用来了解视图转换是否即将发生,使用 types 自定义它, 对捕获的元素做最后的更改,或在必要时跳过它。 PageSwapEvent 接口有一个 viewTransition 对象,当导航符合视图转换条件时,该对象将为非 null, 以及一个 activation 对象,提供有关导航的便用信息,如重定向后的 URL。 转换的 finished 承诺可以用于在转换后进行清理,以防文档稍后从 BFCache 中恢复。

2.1.3.2. 在新文档中处理视图转换

pagereveal 事件在呈现新文档的第一帧之前触发。 它可以用来通过查询 viewTransition 属性来了解视图转换是否仍然有效。 类似于同文档视图转换,作者现在可以选择不同的 types, 对捕获的元素做最后的更改,等待转换ready 以便为其添加动画,或完全跳过它。

2.1.4. 生命周期

本节为非规范性内容。

成功的跨文档视图转换会经过以下阶段:

  1. 在旧的 Document 中:

    1. 用户发起导航,例如点击链接、提交表单、按浏览器的后退按钮等。

      注意:某些导航不会触发视图转换,例如在 URL 栏中输入新地址。

    2. 当新的 Document 准备好被激活时,pageswap 事件被触发。

    3. 如果导航是同源的,没有跨源重定向, 并且旧的 Document选择了跨文档视图转换,事件的 viewTransition 属性将是 一个 ViewTransition 对象。

    4. 作者现在可以自定义转换,例如通过改变其 types, 或完全skip 它。

    5. 如果 ViewTransition 没有被跳过,旧文档的状态将被捕获

    6. 导航继续:旧的 Document 被卸载,新的 Document 现在处于活动状态。

  2. 然后,在新的 Document 中:

    1. 当新的 Document 准备好进行第一次渲染机会时,一个名为 pagereveal 的事件在新的 Document 上触发, 带有一个 viewTransition 属性。

    2. 这个 ViewTransitionupdateCallbackDone 承诺已经解决, 其捕获的元素从旧的 Document 中填充。

    3. 这是作者自定义转换的另一个机会,例如通过改变其 types, 或完全skip 它。

    4. 新文档的状态被捕获作为转换的"新"状态。

    5. 从这一点开始,转换以类似于同文档转换的方式继续,按照激活视图转换

2.2. 示例

要生成与第一个示例中相同的交叉淡入淡出 CSS View Transitions 1 § 1.6 示例, 但跨文档进行,我们不需要 JavaScript。

相反,我们在页面1和页面2中都选择在导航时触发视图转换:

// 在两个文档中:
@view-transition {
    navigation: auto;
}

从页面1到页面2或从页面2的链接将生成示例1的交叉淡入淡出转换。 要实现示例2、3和4的效果,只需将伪元素的 CSS 放在两个文档中。

注意 @view-transition 规则可以 与媒体查询一起使用。 例如,这将只在屏幕宽度大于以下值时执行转换:
@view-transition {
    navigation: auto;
}

@media (max-width: 600px) {
    navigation: none;
}
要实现示例5中的效果,我们必须做几件事:

在两个页面中:

@view-transition {
    navigation: auto;
}
在旧页面中:
addEventListener('click', event => {
    sessionStorage.setItem("lastClickX", event.clientX);
    sessionStorage.setItem("lastClickY", event.clientY);
});

在新页面中:

// 这将在初始加载和从 BFCache 重新激活时运行。
addEventListener("pagereveal", async event => {
    if (!event.viewTransition)
        return;

    const x = sessionStorage.getItem("lastClickX") ?? innerWidth / 2;
    const y = sessionStorage.getItem("lastClickY") ?? innerHeight / 2;

    const endRadius = Math.hypot(
        Math.max(x, innerWidth - x),
        Math.max(y, innerHeight - y)
    );

    await event.viewTransition.ready;

    // 为新文档的视图添加动画
    document.documentElement.animate(
        {
            clipPath: [
                <code data-opaque bs-autolink-syntax='`circle(0 at ${x}px ${y}px)`'>circle(0 at ${x}px ${y}px)</code>,
                <code data-opaque bs-autolink-syntax='`circle(${endRadius}px at ${x}px ${y}px)`'>circle(${endRadius}px at ${x}px ${y}px)</code>,
            ],
        },
        {
            duration: 500,
            easing: 'ease-in',
            pseudoElement: '::view-transition-new(root)'
        }
    );
})
要根据导航的属性以及某些图像是否已加载来选择要捕获哪些元素:

在旧页面中:

window.addEventListener("pageswap", event => {
    // 例如,页面被隐藏,或导航是跨文档的。
    if (!event.viewTransition)
        return;

    // 如果您不希望前进/后退导航使用视图转换...
    if (event.activation.navigationType === "traverse") {
        event.viewTransition.skipTransition();
    }

    const newURL = new URL(event.activation.entry.url);
    if (newURL.pathname === "/details" && thumbnail.complete) {
        thumbnail.classList.add("transition-to-hero");

        // 如果页面从 BFCache 恢复,这将清理状态。
        event.viewTransition.finished.then(() => {
            thumbnail.classList.remove("transition-to-hero");
        });
    }

});

在新页面中:

window.addEventListener("pagereveal", event => {
    // 例如,页面被隐藏,导航是跨文档的,或转换在旧文档中被跳过。
    if (!event.viewTransition)
        return;

    const oldURL = new URL(navigation.activation.from.url);
    if (newURL.pathname === "/list") {
        event.viewTransition.types.add("coming-from-list");

        // 这将显示缩略图直到视图转换完成。
        if (!hero.complete) {
            setToThumbnail(hero);
            event.viewTransition.finished.then(() => {
                setToFullResolution(hero);
            })
        }
    }
});

2.3. 选择跨文档视图转换

2.3.1. @view-transition 规则

@view-transition 规则被文档用来指示跨文档导航 应该设置并激活一个 ViewTransition

@view-transition 规则具有以下语法:

@view-transition {
    <declaration-list>
}

@view-transition 规则接受 navigationtypes 描述符。

注意:按照默认行为,@view-transition 规则可以嵌套在条件组规则内,如 @media@supports

Document document@view-transition 规则发生变化时,用户代理必须更新出站转换的选择状态给定 document

注意:这需要在布尔值中缓存,因为在导航时需要并行读取结果。

2.3.2. navigation 描述符

名称: navigation
适用于: @view-transition
值: auto | none
初始值: none

'navigation' 描述符选择在执行某种类型的导航时自动启动视图转换。 必须在新旧文档中都存在。

none

不会有转换。

auto

如果导航是同源的,没有跨源重定向,并且其 NavigationType 是以下之一,转换将被启用

注意:auto 排除的导航例如,通过 URL 地址栏导航或点击书签,以及任何形式的用户或脚本发起的 reload

此 at-rule 符合 CSS 的向前兼容解析要求; 不理解这些规则的符合标准的解析器将忽略它们而不出错。 任何给定用户代理不识别或未实现的描述符, 或其值不匹配此处或本规范未来版本中给出的语法的描述符, 必须完全忽略; 它们不会使 @view-transition 规则无效。

2.3.3. 使用 CSSOM 访问 @view-transition 规则

CSSViewTransitionRule 表示一个 @view-transition 规则。

[Exposed=Window]
interface CSSViewTransitionRule : CSSRule {
    readonly attribute CSSOMString navigation;
    [SameObject] readonly attribute FrozenArray<CSSOMString> types;
};

navigation getter 步骤是如果存在相应的 navigation 描述符则返回其值,否则返回空字符串。

types getter 步骤是如果存在相应的 types 描述符则返回其值,否则返回空列表

3. 选择性视图转换

3.1. 概述

本节为非规范性内容。

对于简单页面和单一视图转换,在参与元素上设置 view-transition-name 属性应该就足够了。 然而,在更复杂的场景中,作者可能希望声明各种视图转换,并只同时运行其中一个。 例如,在点击导航栏时滑动整个页面,在拖拽列表项时对列表进行排序。

为了确保每个视图转换只捕获其所需的内容,并且不同的转换不会相互干扰, 本规范引入了活动类型的概念,以及 :active-view-transition:active-view-transition-type() 伪类。

:active-view-transition文档元素具有活动视图转换时匹配,而 :active-view-transition-type() 在选择器中的类型与文档元素活动视图转换活动类型匹配时匹配。

ViewTransition活动 类型通过以下方式之一填充:

  1. 作为 startViewTransition(callbackOptions) 的参数传递

  2. 随时使用转换的 types 进行修改

  3. 使用 types 描述符为跨文档视图转换声明。

3.2. 示例

例如,开发者可以通过以下方式启动转换:
document.startViewTransition({update: updateTheDOMSomehow, types: ["slide-in", "reverse"]});

这将激活以下任何选择器:

:root:active-view-transition-type(slide-in) {}
:root:active-view-transition-type(reverse) {}
:root:active-view-transition-type(slide-in, reverse) {}
:root:active-view-transition-type(slide-in, something-else) {}
:root:active-view-transition {}

而不提供转换类型启动转换时,只会激活 ':active-view-transition':

document.startViewTransition(updateTheDOMSomehow);
// 或
document.startViewTransition({update: updateTheDOMSomehow});
/* 这将被激活 */
:root { }
:root:active-view-transition {}

/* 这将不会被激活 */
:root:active-view-transition-type(slide-in) {}
:root:active-view-transition-type(any-type-at-all-except-star) {}

3.3. 基于活动视图转换的选择

3.3.1. :active-view-transition 伪类

:active-view-transition 伪类应用于文档的根元素,如果它具有活动视图转换

:active-view-transition特异性是一个伪类选择器。

:active-view-transition 伪类在其节点 文档具有非空活动视图转换时匹配文档元素

3.3.2. :active-view-transition-type() 伪类

:active-view-transition-type() 伪类应用于文档的根元素,如果它具有匹配的活动视图转换。 它具有以下语法定义:

:active-view-transition-type(<custom-ident>#)

:active-view-transition-type()特异性是一个伪类选择器。

:active-view-transition-type() 伪类在其节点 文档具有非空活动视图转换, 且其活动类型 包含至少一个 <custom-ident> 参数时匹配文档元素

3.4. 更改正在进行的视图转换的类型

ViewTransition 接口扩展如下:

[Exposed=Window]
interface ViewTransitionTypeSet {
    setlike<DOMString>;
};

[Exposed=Window]
partial interface ViewTransition {
    attribute ViewTransitionTypeSet types;
};

ViewTransitionTypeSet 对象表示一个字符串集合,没有特殊语义。

注意:ViewTransitionTypeSet 可以包含对 :active-view-transition-type 无效的字符串,例如 不是 <custom-ident> 的字符串。

types getter 步骤是返回 this活动类型

3.5. 为跨文档视图转换激活转换类型

types 描述符

名称: types
适用于: @view-transition
值: none | <custom-ident>+
初始值: none

'types' 描述符为转换设置活动类型, 在捕获或执行转换时,等同于使用该 types 调用 startViewTransition(callbackOptions)

注意:types 描述符仅应用于 定义它的 Document。 作者有责任在两个文档中使用其选择的类型集。

4. 在视图转换伪元素之间共享样式

4.1. 概述

本节为非规范性内容。

在以类似方式设置 DOM 中多个元素的样式时,通常使用 属性: 设置一个在多个元素之间共享的名称,然后使用 类选择器 来声明共享样式。

视图转换伪元素(例如 view-transition-group())不是在 DOM 中定义的,而是通过使用 view-transition-name 属性定义的。 为此,view-transition-class CSS 属性为视图转换提供了等同于 HTML 的功能。 当具有 view-transition-name 的元素也具有 view-transition-class 值时,该类可以通过伪元素选择, 如 示例 所示。

4.2. 示例

此示例创建一个转换,其中每个框都以其自己的名称参与,同时对所有框的动画应用 1 秒的持续时间:
<div class="box" id="red-box"></div>
<div class="box" id="green-box"></div>
<div class="box" id="yellow-box"></div>
div.box {
    view-transition-class: any-box;
    width: 100px;
    height: 100px;
}
#red-box {
    view-transition-name: red-box;
    background: red;
}
#green-box {
    view-transition-name: green-box;
    background: green;
}
#yellow-box {
    view-transition-name: yellow-box;
    background: yellow;
}

/* 以下样式将应用于所有框,感谢 'view-transition-class' */
::view-transition-group(*.any-box) {
    animation-duration: 1s;
}

4.3. view-transition-class 属性

名称: view-transition-class
值: none | <custom-ident>+
初始值: none
适用于: 所有元素
继承性:
百分比: 不适用
计算值: 按指定值
规范顺序: 按语法
动画类型: 离散

view-transition-class 可用于将相同的样式规则应用于多个 命名视图转换伪元素,这些元素可能具有不同的 view-transition-name。 虽然 view-transition-name 用于匹配旧状态中的元素与其在新状态中对应的元素, view-transition-class 仅用于使用视图转换伪元素应用样式 (::view-transition-group()::view-transition-image-pair()::view-transition-old()::view-transition-new())。

请注意,view-transition-class 本身不会将元素标记为捕获,它仅用作 为已经具有 view-transition-name 的元素设置样式的附加方式。

none

不会有类应用于为此元素生成的 命名视图转换伪元素

<custom-ident>+

所有指定的 <custom-ident> 值(除了 none)在用于 命名视图转换伪元素选择器时会被应用。 none 对于 view-transition-class 是无效的 <custom-ident>,即使与另一个 <custom-ident> 组合使用也是如此。

每个"视图转换类"都是一个 树作用域名称

注意:如果在转换的旧状态和新状态中都为元素指定了相同的 view-transition-name, 则仅应用来自新状态的 view-transition-class 值。这也适用于跨文档视图转换: 来自旧文档的类仅在其对应的 view-transition-name 未在新文档中指定时才会应用。

4.4. 命名视图转换伪元素的扩展

命名视图转换伪元素view-transition-group()view-transition-image-pair()view-transition-old()view-transition-new()) 被扩展以支持以下语法:

::view-transition-group(<pt-name-and-class-selector>)
::view-transition-image-pair(<pt-name-and-class-selector>)
::view-transition-old(<pt-name-and-class-selector>)
::view-transition-new(<pt-name-and-class-selector>)

其中 <pt-name-selector> 的工作方式如之前定义的,而 <pt-name-and-class-selector> 具有以下语法定义:

<pt-name-and-class-selector> = <pt-name-selector> <pt-class-selector>? | <pt-class-selector>
<pt-class-selector> = ['.' <custom-ident>]+

在解释上述语法时,禁止使用空白:

在其 <pt-class-selector> 中具有一个或多个 <custom-ident> 值的 命名视图转换伪元素 选择器 仅在伪元素的 view-transition-name命名元素 中的 类列表包含 所有这些值时才匹配元素。

具有以下任一情况的 命名视图转换伪元素 选择器特异性

等同于 类型选择器

具有 * 参数且具有空 <pt-class-selector>命名视图转换伪元素 选择器特异性 为零。

5. 扩展 document.startViewTransition()

dictionary StartViewTransitionOptions {
    ViewTransitionUpdateCallback? update = null;
    sequence<DOMString>? types = null;
};

partial interface Document {
    ViewTransition startViewTransition(optional (ViewTransitionUpdateCallback or StartViewTransitionOptions) callbackOptions = {});
};
startViewTransition(callbackOptions)方法步骤如下:
  1. updateCallback 为 null。

  2. 如果 callbackOptions 是一个 ViewTransitionUpdateCallback, 将 updateCallback 设置为 callbackOptions

  3. 否则,如果 callbackOptions 是一个 StartViewTransitionOptions, 则将 updateCallback 设置为 callbackOptionsupdate

  4. 如果 this活动视图转换 不为 null 且其 出站后捕获步骤 不为 null, 则:

    1. preSkippedTransitionthis相关域 中的一个新 ViewTransition, 其 更新回调updateCallback

      注意:此处忽略 preSkippedTransitiontypes, 因为转换从未被激活。

    2. 使用 "InvalidStateError" DOMException 跳过 preSkippedTransition

    3. 返回 preSkippedTransition

    注意:这确保在触发 pageswap 后启动的同文档转换被跳过。

  5. viewTransition 为运行 startViewTransition(updateCallback)方法 步骤,传入 updateCallback 的结果。

  6. 如果 callbackOptions 是一个 StartViewTransitionOptions, 将 viewTransition活动类型 设置为 types 作为集合克隆

  7. 返回 viewTransition

6. 自动确定 view-transition-name

6.1. 概述

本节为非规范性内容。

要让元素参与视图转换,需要为其分配一个唯一的 view-transition-name。 当多个元素涉及同一个视图转换时,这可能变得繁琐和冗长,特别是在许多元素都是相同元素转换的情况下, 即元素在旧状态和新状态中具有相同的 view-transition-name

为了简化这一过程,将 view-transition-name 设置为 auto 将为元素生成一个 view-transition-name,或者如果元素存在 id 属性则使用该值。

6.2. 示例

在此示例中,视图转换用于以动画方式对列表进行排序:
<ul>
    <li>项目 1</li>
    <li>项目 2</li>
    <li>项目 3</li>
    <li>项目 4</li>
    ...
</ul>

通常情况下,每个项目都必须接收一个唯一的 view-transition-name

li:nth-child(1) { view-transition-name: item1; }
li:nth-child(2) { view-transition-name: item2; }
li:nth-child(3) { view-transition-name: item3; }
li:nth-child(4) { view-transition-name: item4; }
...

使用 auto,这段 CSS 就能够工作:

li {
    view-transition-name: auto;
}

6.3. view-transition-name 的扩展

除了现有值之外,view-transition-name 还接受一个 auto 关键字。 要解析 elementview-transition-name已用值

  1. computedview-transition-name计算值

  2. 如果 computednone,返回 null。

  3. 如果 computed 是一个 <custom-ident>,返回 computed

  4. 断言:computedauto

  5. 如果 element 具有关联的 id,且 computedelement 关联的根相同,则返回 elementid 值。

    注意:这意味着 ::part() 伪元素不会解析为其匹配元素的 id

  6. 返回一个唯一字符串。该字符串应该对此元素和 Document 保持一致且唯一,至少在 element节点文档活动视图转换 的生命周期内。

    注意:此字符串不是 Web 可观察的,用于在内部算法中寻址元素。

    注意:当在跨文档视图转换中使用时,生成的 auto 值永远不会匹配,从而产生独立的 ::view-transition-group() 伪元素, 一个退出,一个进入。

auto 生成的 view-transition-name 是一个 树作用域名称

7. 嵌套视图转换

7.1. 概述

本节为非规范性内容。

默认情况下,在多个元素上设置 view-transition-name 会生成一个扁平的 视图转换树,其中所有的 ::view-transition-group() 伪元素都是 ::view-transition 伪元素的子元素。 这对许多简单的用例来说是足够的,但有一些样式用例无法通过扁平树实现。 最突出的用例是裁剪:在扁平树中,所有伪元素都被裁剪到 快照包含块,因此在正常树中裁剪元素会在视图转换期间失去裁剪效果,导致视觉效果错误。 在扁平树中可能产生意外视觉效果的效果有:

为了启用这些用例,本规范引入了嵌套视图转换伪元素的概念。通过使用 view-transition-group CSS 属性, 作者可以为生成的 ::view-transition-group() 伪元素分配一个"父组",在 视图转换树中创建层次结构。

7.2. 示例

此示例创建一个转换,其中 视图转换树是嵌套的而不是扁平的:
<section class="container">
    <article>内容</article>
</section>
.container {
    view-transition-name: container;
}

.container,
::view-transition-group(container) {
    clip-path: circle();
}

article {
    view-transition-name: article;
    view-transition-group: container;
}

通过将 clip-path 同时应用于包含元素及其生成的伪元素,我们在转换期间保持了裁剪效果, 通过将 view-transition-group 应用于引用容器的内部元素,我们使树以能够应用此裁剪的方式"嵌套"。

7.3. view-transition-group 属性

名称: view-transition-group
值: normal | contain | nearest | <custom-ident>
初始值: normal
适用于: 所有元素
是否继承:
百分比: 不适用
计算值: 按指定值
规范顺序: 按语法
动画类型: 离散

view-transition-group 属性可以与 view-transition-name 结合使用,生成 命名视图转换伪元素的层次结构。

view-transition-group已用值解析为其祖先链中的 view-transition-name,或者解析为 none。当生成 命名视图转换伪元素时,具有该名称的 ::view-transition-group() 将是为此元素的 ::view-transition-group() 生成的父元素,该元素为此元素的 view-transition-name 生成。

8. 分层捕获

8.1. 概述

本节是非规范性的。

[css-view-transitions-1] 中,新旧状态被捕获为快照,并捕获初始和最终几何图形, 默认情况下创建交叉淡入淡出动画。这是一个简单的模型,通常能够创建所需的结果。

然而,交叉淡入淡出两个扁平化的快照并不总是最具表现力的动画。CSS 允许为边框、渐变背景、filterbox-shadow 等添加动画, 根据所需的用户体验,这可能比交叉淡入淡出感觉更具表现力和自然性。

此外,当使用 嵌套视图转换 时,当 CSS 属性被扁平化为快照时,一些动画可能看起来"错误"。 这包括树状效果,例如 opacitymaskclip-pathfilter,以及 使用 overflow 的剪切。 这些效果被设计为应用于整个元素树,而不仅仅是一个元素及其内容。

通过分层捕获,所有影响整个树的 CSS 属性以及盒装饰都被捕获为样式,并作为组的一部分进行动画。

这种行为应该通过 CSS 属性选择加入/退出吗?参见 issue 11078

8.2. 捕获的 CSS 属性表 {#layered-captured-css-properties}

以下 分层捕获属性 列表定义了参与分层捕获的 CSS 属性。 当捕获元素的新旧状态时,这些属性被捕获为样式,用户代理必须在忽略该属性的情况下渲染快照:

9. 算法

9.1. 数据结构

9.1.1. Document 的扩展

Document 另外具有:
入站视图转换参数

一个 视图转换参数,或 null。 初始值为 null。

可以启动出站视图转换

一个布尔值。 初始值为 false。

注:此值可以在导航时并行读取。

9.1.2. ViewTransition 的扩展

ViewTransition 另外具有:
活动类型

一个 ViewTransitionTypeSet, 初始为空。

出站后捕获步骤

null 或一组步骤,初始为 null。

9.1.3. 可序列化的 视图转换参数

视图转换参数 是一个 结构体,其目的是在文档间序列化视图转换信息。 它有以下 项目
命名元素

一个 映射,其键为字符串,值为 捕获的元素

初始快照包含块大小

一个包含两个数字(宽度和高度)的 元组

9.2. 视图转换页面可见性变化步骤的扩展

以下步骤被附加到任务 视图转换页面可见性变化步骤给定 document,在队列任务中的当前步骤之后:
  1. document入站视图转换参数设置为 null。

注:这是从 HTML 规范中调用的。

9.2.1. 捕获元素扩展

捕获的元素结构体应该包含这些字段,除了现有的字段之外:
类列表

一个字符串 列表,初始为空。

包含组名称

null 或一个字符串,初始为 null。

旧分层捕获样式

一个字符串。

从快照包含块的变换

一个 矩阵, 初始为 恒等变换函数

旧盒属性
新盒属性

一个 分层盒属性或 null,初始为 null。

分层盒属性是一个结构体,包含以下字段:

盒模型

border-boxcontent-box

内容盒
内边距盒

一个矩形,以 CSS 像素单位,相对于边框盒。

9.3. 解析 @view-transition 规则

要为 Document document 解析 @view-transition 规则

注:这在新旧文档中都会调用。

  1. 如果 document可见性状态为"hidden", 则返回"跳过转换"。

  2. matchingRuledocument 中最后一个 @view-transition 规则。

  3. 如果没有找到 matchingRule,则返回"跳过转换"。

  4. 如果 matchingRulenavigation 描述符的 计算值none,则返回 "跳过转换"。

  5. 断言:matchingRulenavigation 描述符的 计算值auto

  6. typesDescriptormatchingRuletypes 描述符。

  7. 如果 typesDescriptor计算值none,则返回一个 集合「 」。

  8. 返回一个对应于 typesDescriptor计算值的字符串 集合

9.4. 在旧 Document 中设置视图转换

9.4.1. 检查出站跨文档视图转换的资格

要检查给定 Document oldDocumentDocument newDocumentNavigationType navigationType 和布尔值 isBrowserUINavigation导航是否可以触发跨文档视图转换?

注:这在导航期间调用,可能是并行的。

  1. 如果用户代理决定显示实现定义的导航体验,例如后退导航的基于手势的转换, 用户代理可以忽略作者定义的视图转换。如果是这种情况,返回 false。

  2. 如果 oldDocument可以启动出站视图转换为 false,则返回 false。

  3. 如果 navigationTypereload, 则返回 false。

  4. 如果 oldDocumentnewDocument不是同源,则返回 false。

  5. 如果 newDocument 是通过跨源重定向创建的newDocument最新条目为 null,则返回 false。

    注:如果这是一个新的导航,而不是从 BFCache 恢复,Document最新条目将为 null。

  6. 如果 navigationTypetraverse, 则返回 true。

  7. 如果 isBrowserUINavigation 为 true,则返回 false。

  8. 返回 true。

9.4.2. 准备交换页面时设置出站转换

要给定 Document oldDocumentDocument newDocumentproceedWithNavigation(一个不接受任何参数的算法)设置跨文档视图转换

注:这是从 HTML 规范中调用的。

  1. 断言: 这些步骤作为在 oldDocument 上排队的任务的一部分运行。

  2. 如果 oldDocument可以启动出站视图转换为 false,则返回 null。

  3. transitionTypesFromRule 为为 oldDocument 解析 @view-transition 规则的结果。

  4. 断言transitionTypesFromRule 不是"跳过转换"。

    注:我们还不知道 newDocument 是否已选择加入,因为它可能还没有解析。 我们在触发 pagereveal 事件时检查 newDocument 的选择加入。

  5. 如果 oldDocument活动视图转换不为 null, 则使用 "AbortError" DOMExceptionoldDocument相关领域跳过 oldDocument活动视图转换

    注:这意味着当文档准备卸载时,任何正在运行的转换都会被跳过。

  6. outboundTransitionoldDocument相关领域中的新 ViewTransition 对象。

  7. outboundTransition活动类型设置为 transitionTypesFromRule

    注:活动类型 不在文档间共享。 在新文档中操作 types 不会影响 newDocument 中的类型, 后者将在 newDocument 显示后从 types 描述符中读取。

    注:一旦旧文档被隐藏,ViewTransition 就会被跳过。

  8. outboundTransition出站后捕获步骤设置为给定 视图转换参数或 null params 的以下步骤:

    1. newDocument入站视图转换参数 设置为 params

      注:入站转换在分发 pagereveal 之后激活,以确保在此事件中进行的突变应用于捕获的新状态。

    2. 为了在超时后跳过转换,用户代理可以并行执行以下步骤:

      1. 等待实现定义持续时间

      2. 在给定 newDocument相关全局对象DOM 操作任务源排队全局任务以执行以下步骤:

        1. 如果 newDocument入站视图转换参数params,则将 newDocument入站视图转换参数设置为 null。

    3. 调用 proceedWithNavigation

  9. oldDocument活动视图转换设置为 outboundTransition

    注:流程在 执行待处理转换操作中继续。

  10. 用户代理应该显示当前显示的帧,直到以下任一情况发生:

    注:这是为了确保在显示新旧状态之间没有意外的闪烁,以保持转换的平滑性。

  11. 返回 outboundTransition

9.4.3. 更新选择加入标志以反映当前状态

要为 Document document 更新出站转换的选择加入状态
  1. 如果 document 已被显示,且解析 @view-transition 规则的结果不是"跳过转换", 则将 document可以启动出站视图转换设置为 true。

  2. 否则,将 document可以启动出站视图转换设置为 false。

9.4.4. 如果视图转换被跳过则继续导航

将以下步骤附加到给定 ViewTransition transition跳过视图转换
  1. 如果 transition出站后捕获步骤不为 null,则使用 null 运行 transition出站后捕获步骤

注:这是以猴子补丁的方式编写的,一旦 L1 规范毕业,将被合并到算法中。

9.4.5. 捕获旧状态后继续跨文档视图转换

将以下步骤前置到给定 Document document执行待处理转换操作算法:
  1. 如果 document活动视图转换不为 null 且其 出站后捕获步骤不为 null,则:

    1. 断言:document活动视图转换阶段为 "pending-capture"。

    2. viewTransitionParams 为 null;

    3. document视图转换的渲染抑制设置为 true。

      虽然 捕获旧状态在这里显示为同步步骤,但实际上它是异步步骤, 因为将元素渲染到图像中无法同步完成。这在 L1 规范中应该更明确。

    4. transition 捕获旧状态

    5. 如果成功,则将 viewTransitionParams 设置为新的 视图转换参数,其 命名元素transition命名元素克隆, 其 初始快照包含块大小transition初始快照包含块大小

    6. document视图转换的渲染抑制设置为 false。

    7. 使用 viewTransitionParams 调用 transition出站后捕获步骤

注:这是以猴子补丁的方式编写的,一旦 L1 规范毕业,将被合并到算法中。

9.5. 在新 Document 中激活视图转换

要为 Document document 解析入站跨文档视图转换
  1. 断言document完全活动的

  2. 断言document 已被显示为 true。

  3. document 更新出站转换的选择加入状态

  4. inboundViewTransitionParamsdocument入站视图转换参数

  5. 如果 inboundViewTransitionParams 为 null,则返回 null。

  6. document入站视图转换参数设置为 null。

  7. 如果 document活动视图转换不为 null,则返回 null。

    注:这意味着在显示文档之前启动同文档转换将取消待处理的跨文档转换。

  8. document 解析 @view-transition 规则,设 resolvedRule 为结果。

  9. 如果 resolvedRule 为"跳过转换",则返回 null。

  10. transitiondocument相关领域中的新 ViewTransition, 其 命名元素inboundViewTransitionParams命名元素初始快照包含块大小inboundViewTransitionParams初始快照包含块大小

  11. document活动视图转换设置为 transition

  12. 解析 transition更新回调完成承诺为 undefined。

  13. transition阶段设置为"update-callback-called"。

  14. transition活动类型设置为 resolvedRule

  15. 返回 transition

9.6. 捕获 view-transition-class

当为元素捕获新旧状态时,给定 捕获的元素 capture元素 element,执行以下步骤:
  1. 如果 elementview-transition-class计算值element节点文档关联,则将 capture类列表设置为该计算值。

注:这是以猴子补丁的方式编写的,一旦 L1 规范毕业,将被合并到算法中。

9.7. 捕获和应用 view-transition-group

9.7.1. 解析 view-transition-group

要获取 Element element文档范围的视图转换组,执行以下步骤:
  1. computedGroup 为元素的 view-transition-group 属性的 计算值

  2. 如果 computedGroupelement节点文档关联,则返回 computedGroup

  3. 返回 normal

9.7.2. 解析包含组名称

要解析 Element element最近包含组名称,给定 ViewTransition viewTransition,执行以下步骤:

  1. 断言:element 参与 viewTransition

  2. ancestorGroupelement 的最近的 扁平树 祖先,它参与 viewTransition 并且其 文档范围的视图转换组不是 normal

  3. 如果 ancestorGroup 存在,则返回 ancestorGroup文档范围的视图转换名称

  4. 返回 none

9.7.3. 解析组名称

要解析 Element element已用组名称,给定 ViewTransition transition,执行以下步骤:
  1. 断言:element 参与 transition

  2. groupelement文档范围的视图转换组

  3. containingGroupNameelement最近包含组名称,给定 transition

  4. 根据 group 返回第一个匹配的语句:

normal
contain

containingGroupName

注:具有 contain 的元素成为其后代的 最近包含组名称

nearest

参与 transition 的元素最近的 扁平树 祖先的 文档范围的视图转换名称

<custom-ident>

如果元素有一个 扁平树 祖先,其 文档范围的视图转换名称group 并参与 transition,则返回 group;否则返回 containingGroupName

9.7.4. 计算旧的 view-transition-group

为元素捕获旧状态时,给定 捕获的元素 capturedElementViewTransition transition元素 element,执行以下步骤:
  1. capturedElement包含组名称设置为 element已用组名称,给定 transition

9.7.5. 计算新的 view-transition-group

为元素捕获新状态时,给定 捕获的元素 capturedElementViewTransition transition元素 element,执行以下步骤:
  1. capturedElement包含组名称设置为 element已用组名称,给定 transition

9.7.6. ::view-transition-group() 重新父级化到其指定的包含组

当为 捕获的元素 capturedElement 设置转换伪元素时,给定 transitionNametransition
  1. containingGroupNamecapturedElement包含组名称

  2. 如果 containingGroupName 不为 null,则:

    1. groupContainerElementtransition命名元素[containingGroupName]。

    2. group::view-transition-group(), 其 视图转换名称设置为 transitionName

    3. parentGroup::view-transition-group(), 其 视图转换名称设置为 containingGroupName

    4. group 附加到 parentGroup

    5. 当设置动画关键帧时,给定 transform调整嵌套组变换transform,给定 groupContainerElement旧变换groupContainerElement旧宽度groupContainerElement旧高度,以及 groupContainerElement旧盒属性

注:当新旧组不匹配时如何解决这个问题有待确定。参见问题 10631

9.7.7. 调整组的 transform 相对于其包含的 ::view-transition-group()

更新转换伪元素的样式时,在设置 组样式规则之前,给定 捕获的元素 capturedElementtransformViewTransition transition,执行以下步骤:
  1. capturedElement从快照包含块的变换设置为 transform

  2. 如果 capturedElement包含组名称不为 null,则:

    1. groupContainerElementtransition命名 元素[capturedElement包含组名称]。

    2. 如果 capturedElement文档元素,设 containerRect快照包含块; 否则,设为 capturedElement边框盒

    3. 调整嵌套组变换transform,给定 groupContainerElement从快照包含块的变换containerRect 的宽度、 containerRect 的高度,以及 groupContainerElement新盒属性

9.8. 捕获分层 CSS 属性

9.8.1. 计算分层捕获样式

要计算 Element element分层捕获样式
  1. propertiesToCapture 为与 分层捕获属性对应的新 列表

  2. 规定 overflow 和包含的行为。参见问题 11079

  3. styles 为 « »。

  4. 对于 propertiesToCapture 中的每个 property附加以下各项的 连接:« property":"elementproperty计算值";" » 到 styles

  5. 返回 styles连接

要计算 Element element分层捕获几何,返回一个新的 分层盒属性, 其 盒模型element计算的 box-sizing内边距盒element内边距盒, 其 内容盒element内容盒

要计算给定 element默认组大小,如果 element计算的 box-sizingcontent-box,则返回 element内容盒的大小;否则返回 element边框盒的大小。

9.8.2. 捕获旧的分层属性

为元素捕获旧状态时,给定 捕获的元素 capturedElement元素 element,执行以下步骤:
  1. capturedElement旧分层捕获样式设置为 element分层捕获样式

  2. capturedElement旧盒属性设置为 element分层捕获几何

  3. capturedElement 的(旧宽度旧高度)设置为 element默认组大小

9.8.3. 图像捕获大小的调整

捕获图像时,图像的 自然尺寸将基于元素的 内容盒的大小,而不是基于 边框盒

9.8.4. 使用分层捕获渲染快照

当将元素捕获到快照中时,只绘制 元素内容,而不包括元素的效果和盒装饰。 具体而言,元素的 backgroundborderborder-imagebox-shadowoutline 不被绘制,其 border-radiusclip-pathfiltermaskopacity 不被应用。

9.8.5. 调整嵌套组变换

调整嵌套组变换,给定 矩阵 transform矩阵 parentTransformborderBoxWidthborderBoxHeight分层盒属性 boxProperties,执行以下步骤:
  1. transform 乘以 parentTransform 的逆矩阵。

  2. 设 (left, top) 为基于 boxProperties内边距盒在 (borderBoxWidth, borderBoxHeight) 内的边框边缘。

  3. transform 平移 (-left, -top)。

    注:这些操作确保此嵌套组的默认位置相当于原始元素的位置,因为默认情况下嵌套的 ':view-transition-group' 将相对于父元素的 内边距边缘定位。

9.8.6. 将旧的分层捕获属性应用到 ::view-transition-group() 关键帧

当为 捕获的元素 capturedElement 设置转换伪元素时,给定 transitionName
  1. keyframesName 为 « -ua-view-transition-group-anim-transitionName » 的 连接

  2. capturedElement旧分层捕获样式附加到 keyframesName 的构造规则中。

9.8.7. 将新的分层捕获属性应用到 ::view-transition-group()

更新转换伪元素的样式时,在设置组样式规则之前执行以下步骤,给定 transitionNamecapturedElementwidthheightElement element

注:这可能会改变 widthheight

  1. styleelement分层捕获样式

  2. capturedElement新盒属性设置为 element分层捕获属性

  3. 将 (width, height) 设置为 element默认组大小

  4. 连接的以下字符串追加到构造的用户代理样式表中: "::view-transition-group("transitionName") {"style"}"

  5. 设 (oldContentWidth, oldContentHeight) 为:如果 capturedElement旧盒属性为 null,则为 (capturedElement旧宽度capturedElement旧高度);否则为 capturedElement旧盒属性内容盒的大小。

  6. 设 (newContentWidth, newContentHeight) 为:如果新盒属性为 null,则为 (width, height);否则为 capturedElement新盒属性内容盒的大小。

  7. 将下一个字符串(替换变量后)追加到用户代理样式表中:

    @keyframes -ua-view-transition-content-geometry-transitionName {
      from {
        width: oldContentWidth;
        height: oldContentHeight;
      }
    }
    
    :root::view-transition-image-pair(transitionName) {
      position: relative;
      inset: unset;
      width: newContentWidth;
      height: newContentHeight;
      animation-name: -ua-view-transition-transitionName;
      animation-direction: inherit;
      animation-timing-function: inherit;
      animation-iteration-count: inherit;
      animation-duration: inherit;
    }
    

注:':view-transition-image-pair' 伪元素使用relative定位,以便组的padding能够生效。

隐私注意事项

本规范不引入新的隐私注意事项。

安全注意事项

为了防止跨源问题,目前跨文档视图转换只能在同源导航中启用。如WICG/view-transitions#200中讨论的,这仍然存在两个潜在威胁:

  1. 两个文档中的跨源隔离能力可能不同。 这可能导致跨源隔离Document 能够读取非跨源隔离文档的图像数据。这在[[css-view-transitions-1#sec]中已经得到缓解,因为对于捕获的跨源iframe也适用相同的限制。

  2. 同源导航仍可能通过跨源重定向发生,例如 https://example.com链接到https://auth-provider.com/,然后重定向回 https://example.com/loggedin

    这可能导致(轻微的)情况,即跨源方将用户重定向到意外的第一方URL,导致意外的转换并模糊存在重定向的事实。 为了缓解这种情况,如果Document 是通过跨源重定向创建的,目前视图转换会在导航时被禁用。 请注意,当Document 正在被重新激活时,此检查不适用,因为在这种情况下跨源重定向已经发生。

    注:这仅适用于服务器端重定向。客户端重定向,例如使用 [^meta/http-equiv/refresh^],等同于新的导航。

  3. 此功能向CSS暴露了更多信息,因为到目前为止CSS不知道任何与导航相关的内容。 这可能引起对第三方CSS安全性的担忧。然而,作为一般规则,第三方样式表首先应该来自可信来源,因为CSS可以通过多种方式了解文档或更改文档。

详细讨论请参见Issue #8684WICG/view-transitions#200

附录 A. 变更

本附录为信息性内容

2024-05-16 工作草案以来的变更

一致性

文档约定

一致性要求通过描述性断言和RFC 2119术语的组合来表达。在本文档的规范性部分中,关键词"MUST"、 "MUST NOT"、"REQUIRED"、"SHALL"、"SHALL NOT"、"SHOULD"、"SHOULD NOT"、 "RECOMMENDED"、"MAY"和"OPTIONAL"应按照RFC 2119中的描述进行解释。 但是,为了可读性,这些词在本规范中不会全部以大写字母出现。

本规范的所有文本都是规范性的,除了明确标记为非规范性的部分、示例和注释。[RFC2119]

本规范中的示例用"例如"一词引入,或者用class="example"从规范性文本中分离出来, 如下所示:

这是一个信息性示例的例子。

信息性注释以"注"一词开始,并用class="note"从规范性文本中分离出来,如下所示:

注,这是一个信息性注释。

建议是规范性部分,样式用于引起特别注意,并用<strong class="advisement">从其他规范性文本中分离出来,如下所示:用户代理必须提供可访问的替代方案。

一致性类别

本规范的一致性定义了三个一致性类别:

样式表
一个CSS样式表
渲染器
解释样式表语义并渲染使用它们的文档的UA
创作工具
编写样式表的UA

如果样式表中使用本模块中定义的语法的所有语句都根据通用CSS语法和本模块中定义的每个特性的单独语法有效,则该样式表符合本规范。

如果渲染器除了按照适当规范定义的方式解释样式表外,还通过正确解析本规范定义的所有特性并相应地渲染文档来支持这些特性,则该渲染器符合本规范。但是,由于设备限制而无法正确渲染文档的UA并不会使该UA不符合要求。(例如,UA不需要在单色显示器上渲染颜色。)

如果创作工具编写的样式表在语法上根据通用CSS语法和本模块中每个特性的单独语法都是正确的,并且满足本模块中描述的样式表的所有其他一致性要求,则该创作工具符合本规范。

部分实现

为了让作者能够利用向前兼容的解析规则来分配回退值,CSS渲染器必须将任何它们没有可用支持级别的@规则、属性、属性值、关键字和其他语法结构视为无效(并适当地忽略)。特别是,用户代理不得选择性地忽略不支持的组件值并在单个多值属性声明中支持受支持的值:如果任何值被认为是无效的(不支持的值必须如此),CSS要求忽略整个声明。

不稳定和专有特性的实现

为了避免与未来稳定的CSS特性冲突,CSSWG建议遵循最佳实践来实现不稳定特性和CSS的专有扩展

非实验性实现

一旦规范达到候选推荐标准阶段,非实验性实现就成为可能,实现者应该发布任何他们可以证明根据规范正确实现的CR级特性的无前缀实现。

为了建立和维护CSS在各实现中的互操作性,CSS工作组要求非实验性CSS渲染器在发布任何CSS特性的无前缀实现之前,向W3C提交实现报告(如有必要,还要提交用于该实现报告的测试用例)。提交给W3C的测试用例需要接受CSS工作组的审查和修正。

有关提交测试用例和实现报告的更多信息,可以从CSS工作组网站https://www.w3.org/Style/CSS/Test/找到。 问题应直接发送到public-css-testsuite@w3.org邮件列表。

索引

本规范定义的术语

引用定义的术语

参考文献

规范性参考文献

[CSS-BACKGROUNDS-3]
Elika Etemad; Brad Kemper. CSS 背景和边框模块 3 级. 2024年3月11日. CR. URL: https://www.w3.org/TR/css-backgrounds-3/
[CSS-BORDERS-4]
CSS 边框和盒装饰模块 4 级. 编辑草案. URL: https://drafts.csswg.org/css-borders-4/
[CSS-BOX-4]
Elika Etemad. CSS 盒模型模块 4 级. 2024年8月4日. WD. URL: https://www.w3.org/TR/css-box-4/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS 层叠和继承 5 级. 2022年1月13日. CR. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-COLOR-4]
Chris Lilley; Tab Atkins Jr.; Lea Verou. CSS 颜色模块 4 级. 2024年2月13日. CR. URL: https://www.w3.org/TR/css-color-4/
[CSS-CONTAIN-2]
Tab Atkins Jr.; Florian Rivoal; Vladimir Levin. CSS 包含模块 2 级. 2022年9月17日. WD. URL: https://www.w3.org/TR/css-contain-2/
[CSS-IMAGES-3]
Tab Atkins Jr.; Elika Etemad; Lea Verou. CSS 图像模块 3 级. 2023年12月18日. CR. URL: https://www.w3.org/TR/css-images-3/
[CSS-MASKING-1]
Dirk Schulze; Brian Birtles; Tab Atkins Jr.. CSS 遮罩模块 1 级. 2021年8月5日. CR. URL: https://www.w3.org/TR/css-masking-1/
[CSS-OVERFLOW-3]
Elika Etemad; Florian Rivoal. CSS 溢出模块 3 级. 2023年3月29日. WD. URL: https://www.w3.org/TR/css-overflow-3/
[CSS-SCOPING-1]
Tab Atkins Jr.; Elika Etemad. CSS 作用域模块 1 级. 2014年4月3日. WD. URL: https://www.w3.org/TR/css-scoping-1/
[CSS-SIZING-3]
Tab Atkins Jr.; Elika Etemad. CSS 盒尺寸模块 3 级. 2021年12月17日. WD. URL: https://www.w3.org/TR/css-sizing-3/
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin. CSS 语法模块 3 级. 2021年12月24日. CR. URL: https://www.w3.org/TR/css-syntax-3/
[CSS-TRANSFORMS-1]
Simon Fraser; et al. CSS 变换模块 1 级. 2019年2月14日. CR. URL: https://www.w3.org/TR/css-transforms-1/
[CSS-TRANSFORMS-2]
Tab Atkins Jr.; et al. CSS 变换模块 2 级. 2021年11月9日. WD. URL: https://www.w3.org/TR/css-transforms-2/
[CSS-UI-4]
Florian Rivoal. CSS 基本用户界面模块 4 级. 2021年3月16日. WD. URL: https://www.w3.org/TR/css-ui-4/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS 值和单位模块 4 级. 2024年3月12日. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-VIEW-TRANSITIONS-1]
Tab Atkins Jr.; Jake Archibald; Khushal Sagar. CSS 视图过渡模块 1 级. 2024年3月28日. CR. URL: https://www.w3.org/TR/css-view-transitions-1/
[CSS22]
Bert Bos. 层叠样式表 2 级修订版 2 (CSS 2.2) 规范. 2016年4月12日. WD. URL: https://www.w3.org/TR/CSS22/
[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez. CSS 对象模型 (CSSOM). 2021年8月26日. WD. URL: https://www.w3.org/TR/cssom-1/
[DOM]
Anne van Kesteren. DOM 标准. 现行标准. URL: https://dom.spec.whatwg.org/
[FILTER-EFFECTS-1]
Dirk Schulze; Dean Jackson. 滤镜效果模块 1 级. 2018年12月18日. WD. URL: https://www.w3.org/TR/filter-effects-1/
[GEOMETRY-1]
Simon Pieters; Chris Harrelson. 几何接口模块 1 级. 2018年12月4日. CR. URL: https://www.w3.org/TR/geometry-1/
[HR-TIME-3]
Yoav Weiss. 高分辨率时间. 2023年7月19日. WD. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; et al. HTML 标准. 现行标准. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. 基础架构标准. 现行标准. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. RFC 中用于表示需求级别的关键词. 1997年3月. 最佳当前实践. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SELECTORS-3]
Tantek Çelik; et al. 选择器 3 级. 2018年11月6日. REC. URL: https://www.w3.org/TR/selectors-3/
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. 选择器 4 级. 2022年11月11日. WD. URL: https://www.w3.org/TR/selectors-4/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 标准. 现行标准. URL: https://webidl.spec.whatwg.org/

参考性参考文献

[CSS-CONDITIONAL-3]
Chris Lilley; David Baron; Elika Etemad. CSS 条件规则模块 3 级. 2024年8月15日. CR. URL: https://www.w3.org/TR/css-conditional-3/
[CSS-POSITION-3]
Elika Etemad; Tab Atkins Jr.. CSS 定位布局模块 3 级. 2024年8月10日. WD. URL: https://www.w3.org/TR/css-position-3/
[CSS-SHADOW-PARTS-1]
Tab Atkins Jr.; Fergal Daly. CSS 阴影部件. 2018年11月15日. WD. URL: https://www.w3.org/TR/css-shadow-parts-1/

属性索引

名称 初始值 适用于 继承 百分比 动画类型 标准顺序 计算值
view-transition-class none | <custom-ident>+ none 所有元素 不适用 离散 按语法 按指定
view-transition-group normal | contain | nearest | <custom-ident> normal 所有元素 不适用 离散 按语法 按指定

@view-transition 描述符

名称 初始值
navigation auto | none none
types none | <custom-ident>+ none

IDL 索引

[Exposed=Window]
interface CSSViewTransitionRule : CSSRule {
  readonly attribute CSSOMString navigation;
  [SameObject] readonly attribute FrozenArray<CSSOMString> types;
};

[Exposed=Window]
interface ViewTransitionTypeSet {
  setlike<DOMString>;
};

[Exposed=Window]
partial interface ViewTransition {
  attribute ViewTransitionTypeSet types;
};

dictionary StartViewTransitionOptions {
  ViewTransitionUpdateCallback? update = null;
  sequence<DOMString>? types = null;
};

partial interface Document {
  ViewTransition startViewTransition(optional (ViewTransitionUpdateCallback or StartViewTransitionOptions) callbackOptions = {});
};

问题索引

这个行为是否应该通过CSS属性进行选择加入/退出?参见问题11078
虽然捕获旧状态 在这里显示为同步步骤,但实际上是异步步骤, 因为将元素渲染为图像无法同步完成。这在L1规范中应该更明确。
指定overflow和包含的行为。参见问题11079