CSS 包含模块第2级

W3C 工作草案,

更多关于本文件的信息
此版本:
https://www.w3.org/TR/2022/WD-css-contain-2-20220917/
最新发布的版本:
https://www.w3.org/TR/css-contain-2/
编辑草案:
https://drafts.csswg.org/css-contain-2/
之前的版本:
历史记录:
https://www.w3.org/standards/history/css-contain-2
测试套件:
https://test.csswg.org/harness/results/css-contain-1_dev/
https://wpt.fyi/results/css/css-contain/
反馈:
CSSWG 问题存储库
编辑:
Tab Atkins (Google)
Florian Rivoal (代表 Bloomberg)
(Google)
建议编辑此规范:
GitHub 编辑器

摘要

这个CSS模块描述了 contain 属性,该属性表明元素的子树与页面的其他部分是独立的。 当合理使用时,这可以使用户代理进行大幅度的优化。

CSS 是一种描述结构化文档(如HTML和XML)在屏幕、纸张等介质上呈现方式的语言。

本文档的状态

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

本文档由 CSS工作组 作为 工作草案 发布,使用的是 推荐路径。 作为工作草案发布并不意味着 W3C 及其成员的认可。

这是一个草案文件,可能随时被更新、替换或由其他文件取代。 不宜将此文件引用为其他正在进行的工作。

请通过 在GitHub中提交问题(优选)来提供反馈, 在标题中包括规范代码“css-contain”,例如:“[css-contain] …评论摘要…”。 所有问题和评论都被 归档。 另外,也可以通过(已归档)公共邮件列表 www-style@w3.org 发送反馈。

本文档受 2021年11月2日W3C流程文件 管辖。

本文档由在 W3C专利政策 下运作的小组制作。 W3C维护了一个 公开的专利披露列表,该列表中列出了与小组交付物相关的任何专利披露; 该页面还包含了披露专利的说明。 知道自己所掌握的专利中包含 必要声明 的个人,必须根据 W3C专利政策第6节 披露信息。

1. 简介

高效渲染网站依赖于用户代理能够检测页面的哪些部分正在显示,哪些部分可能会影响当前显示的部分,以及哪些部分可以忽略。

有各种启发式方法可以用来判断某个给定的子树在某种程度上是否独立于页面的其他部分,但它们很脆弱,因此对页面的无害更改可能会无意中使其无法通过此类启发式测试,导致渲染进入慢速代码路径。 还有许多事情值得隔离,但很难或不可能以启发式方式检测到。

为缓解这些问题并允许从页面的其他部分强烈且可预测地隔离子树,本规范定义了一个 contain 属性。

为了进一步优化屏幕外内容,本规范还定义了一个 content-visibility 属性, 使用户代理在不需要时能够完全跳过元素的布局和绘制。

1.1. 模块交互

本文档定义了早期规范中不存在的新特性。此外,它旨在一旦稳定后替换并取代 [CSS-CONTAIN-1]

1.2. 值定义

本规范遵循 CSS 属性定义约定,来自 [CSS2],并使用 值定义语法,来自 [CSS-VALUES-3]。 未在本规范中定义的值类型在 CSS Values & Units [CSS-VALUES-3] 中定义。 与其他 CSS 模块的结合可能会扩展这些值类型的定义。

除了在定义中列出的特定于属性的值外,本规范中定义的所有属性还接受 CSS 宽泛关键字 作为其属性值。 为了可读性,它们没有被明确重复。

2. 强包含: contain 属性

名称: contain
值: none | strict | content | [ size || layout || style || paint ]
初始值: none
适用于: 参见 下文
继承:
百分比: 不适用
计算值: 关键字 nonesize, layout, paint 中的一个或多个
规范顺序: 按语法顺序
动画类型: 不可动画

用户代理应支持在所有媒体(包括非视觉媒体)上使用此属性。

contain 属性允许作者指示一个元素及其内容在尽可能大的程度上与文档树的其余部分独立。 这使得用户代理在正确使用 contain 时能够在渲染页面时利用更强的优化,并使作者可以确信其页面不会因无害的更改而意外地进入慢速代码路径。

none
此值表示该属性没有效果。 元素正常渲染,没有应用任何包含效果。
strict
此值计算为 size layout paint style,因此为该元素开启所有形式的 包含
content
此值计算为 layout paint style,因此为该元素开启所有形式的 包含除了 尺寸包含

注意: contain: content 在广泛应用时是相对“安全”的; 其效果在实际中相对较小,并且大多数内容不会触犯其限制。 然而,由于它不适用于 尺寸包含,因此元素仍然可以响应其内容的大小,这可能导致布局失效传播到树中比预期更远的地方。 在可能的情况下,使用 contain: strict 以获得尽可能多的包含。

size
该值为元素开启 尺寸包含。 这确保了 包含盒 可以布局而不需要检查其后代。
layout
此值为元素开启 布局包含。 这确保了 包含盒 在布局时完全不透明; 外部的任何东西都不能影响其内部布局,反之亦然。
style
此值为元素开启 样式包含。 这确保了对于可能对不仅仅是元素及其后代产生影响的属性,这些影响不会超出元素。
paint
此值为元素开启 绘制包含。 这确保了 包含盒 的后代不会在其边界外显示,因此如果一个元素处于屏幕外或其他不可见的位置,其后代也将保证不可见。

此属性通常适用于所有元素(包括 CSS 伪元素 4 § 4.1 生成内容伪元素: ::before 和 ::after, 尽管某些类型的包含对某些元素没有影响, 详细信息请参见 § 3 包含类型。 此外,对于 [SVG2]contain 属性仅适用于 具有关联CSS布局盒的 svg 元素。

contain 在页面上广泛使用时很有用, 特别是在页面包含大量彼此独立的“小部件”时。

例如,假设一个微帖子社交网络的标记类似于以下内容:

<body>
    <aside>...</aside>
    <section>
        <h2>Messages</h2>
        <article>
          Lol, check out this dog: images.example.com/jsK3jkl
        </article>
        <article>
          I had a ham sandwich today. #goodtimes
        </article>
        <article>
          I have political opinions that you need to hear!
        </article></section>
    </body>
    

站点上可能会显示很多消息,但每条消息都是独立的,不会影响站点上的其他内容。 因此,每条消息都可以用 contain: content 标记以将此信息传达给用户代理,以便它可以优化页面并跳过大量屏幕外消息的计算。 如果提前知道每条消息的大小,可以应用 contain: strict 以传达进一步的限制。

此外,当任何 包含 激活在 HTML htmlbody 元素上时, 从 body 元素向 初始包含块、视口或 画布背景 的属性传播将被禁用。 尤其是,这会影响:

注意: 设置在 html 元素本身上的属性不会影响其向 初始包含块、视口或 画布背景 的传播。

注意: 除了 contain 之外, 还有几种属性可以为元素开启各种 包含。 这些属性不会影响 contain 的值; 例如,一个元素可以具有 contain: none,但仍然可以通过 content-visibility 为其开启 布局包含

3. 容器类型

一个元素可能受到几种不同类型的容器的限制,从而以不同方式限制其后代对页面其余部分的影响。容器使用户代理能够进行更强大的优化,并帮助作者将页面组合成功能单元,因为它限制了特定更改对文档的影响范围。

规范作者在引入新属性或机制时需要考虑各种容器类型是否以及如何影响他们所引入的内容,并在规范中包括此处未描述的任何影响。

3.1. 尺寸容器

为一个元素赋予尺寸容器会使其主框成为一个尺寸容器框,并具有以下效果:

  1. 内在尺寸尺寸容器框决定,按照按空布局的逻辑处理,好像元素没有任何内容。

    注意:这会影响对最小内容最大内容关键字的显式调用,以及任何依赖于这些测量的计算,例如将大小包含的项目放入网格轨道中,或者在合适内容尺寸的父容器中。

  2. 布局尺寸容器框及其内容分两个阶段进行:

    按空布局

    使用的 宽度高度根据盒子布局时的正常方式进行确定,只不过被视为没有内容—甚至伪元素如::before::after::marker也不例外。

    替换元素必须被视为具有自然宽度和高度为0,且无自然长宽比

    注意:尺寸容器只抑制自然长宽比,所以像长宽比这样的属性直接影响优选长宽比,因此仍然有效。

    所有CSS属性都会像正常布局时一样应用于尺寸容器框。其他规范可能会做出具体豁免。

    注意:即使元素的尺寸属性指定了内在尺寸,这也不一定会使元素的尺寸变为零:元素本身设置的属性仍会被考虑在内,这可能会导致元素变大。

    按位置布局
    容器框的内容(包括任何伪元素)必须正常地布局到现有固定大小的尺寸容器框中。

    注意: 尺寸容器不会抑制基线对齐。参见布局容器

  3. 尺寸容器框整体的(参见CSS Fragmentation 3 § 4.1 可能的断点)。

给定以下标记和样式,图像会被调整为100px x 100px,因为长宽比属性生效。
img {
  width: 100px;
  aspect-ratio: 1/1;
  contain: size;
}
<img src="https://www.example.com/300x100.jpg">

如果未声明长宽比属性,图像将为100px x 0px,因为其自然长宽比被抑制,其自然高度被视为0。

然而,当满足以下任意条件时,为一个元素赋予尺寸容器将无效:

注意:内部表格框,不包括表格标题栏,被排除在外,因为表格布局算法不允许框比其流入内容更小。将表格单元格按空布局并在内部布局其内容而不改变尺寸,实际上是未定义的操作。手动将宽度高度属性设置为0不能使其比内容更小。这一问题不适用于表格标题栏,它们完全可以具有独立于其内容的固定大小。

3.1.1. 可能的尺寸容器优化

本节为非规范性内容。

尺寸容器本身并没有提供太多的优化机会。它自身的主要优势在于,想要基于容器框的大小来布局内容的工具(例如实现“容器查询”概念的JS库),可以这样做而不必担心“无限循环”,即子元素的尺寸响应于容器框的大小,导致容器框的大小也发生变化,从而可能触发对子元素尺寸的进一步更改,可能会再次引发对容器框大小的更改,如此无限循环。

但是,当与布局容器结合使用时,可能启用的优化包括(但不限于):

  1. 容器框的后代的样式或内容发生变化时,计算DOM树的哪些部分被“弄脏”并可能需要重新布局,可以在容器框处停止。

  2. 在布局页面时,如果容器框不在屏幕上或被遮挡,则其内容的布局(即“按位置布局”)可以延迟或以较低优先级完成。

3.2. 布局容器

为一个元素赋予布局容器会使其主框成为一个布局容器框,并具有以下效果:

  1. 布局容器框 建立一个独立的格式化上下文

  2. 如果一个分段容器分段上下文中至少有一个具有布局容器,或者该分段上下文的至少一个分段容器是一个布局容器框的后代,并且同一分段上下文的至少一个后续分段容器不是具有布局容器的同一元素的后代,那么第一个是布局容器框的元素或是分段容器的祖先元素必须“截留”剩余的分段流分段不得继续超出布局容器边界,且第一个布局容器边界内的最后一个分段容器被视为其分段上下文中的最后一个分段容器

    如果只有在分段流中还有更多内容时才生成分段上下文中的后续分段容器,那么它们不会生成。如果它们无论如何都存在,它们仍然是分段上下文的一部分,但不会接收任何来自分段流的内容。

    注意: 在撰写本文时,没有稳定的规范受此条影响。只有那些使分段上下文的一些(但不是全部)分段容器成为布局容器(或布局容器元素的后代)的规范才会受到影响。这种情况不适用于[CSS-PAGE-3][CSS-MULTICOL-1]。尽管如此,仍然包含了这一要求,因为已经考虑了几种可能导致这种情况的机制(例如:[CSS-REGIONS-1]::nth-fragment(),多列的假设选择器……),如果这些机制不遵守这一规则,布局容器旨在提供的保证将无法实现。[CSS-REGIONS-1]详细说明了布局容器如何影响区域。

    <article>Lorem ipsum…</article>
    <div id=a></div>
    <aside><div id=b></div>
    <div id=c></div>
    </aside>
    <aside><div id=d></div>
    <div id=e></div>
    </aside>
    <div id=f></div>
    
    article {flow-into: foo;}
    #a, #b, #c, #d, #e, #f {flow-from: foo;}
    aside {contain: layout}
    

    在此[CSS-REGIONS-1]示例中,内容可以从#a流向#b,从#b流向#c。然而,由于#c是第一个布局容器框中的最后一个片段容器,它截留了所有剩余的内容,并且没有任何内容流入#d#e#f

  3. 如果溢出属性的计算值为可见裁剪或其组合,则任何溢出必须视为墨水溢出

  4. 布局容器框建立一个绝对定位包含块和一个固定定位包含块

  5. 布局容器框创建一个堆叠上下文

  6. 强制换行允许在布局容器框中发生,但不会像CSS Fragmentation 3 § 3.1 框之间的换行:break-before和break-after属性中描述的那样传播到父级。

    注意:这引入了先前不存在的可能性,即强制换行可能发生在框和其容器之间(参见CSS Fragmentation 3 § 4.1 可能的断点)。

  7. 垂直对齐属性或其他需要将布局容器框的基线位置与其后代以外的某物相关联的属性而言,该容器框被视为没有基线。

然而,当满足以下任意条件时,为一个元素赋予布局容器将无效:

3.2.1. 可能的布局容器优化

本节为非规范性内容。

布局容器可能启用的优化包括(但不限于):

  1. 在布局页面时,单独的容器框的内容可以并行布局,因为它们保证不会相互影响。

  2. 在布局页面时,如果容器框不在屏幕上或被遮挡,并且屏幕上可见部分的布局不依赖于容器框的大小(例如,如果容器框接近块级容器的末尾,而你正在查看块级容器的开头),则容器框内容的布局可以延迟或以较低优先级完成。

    (当与尺寸容器配合使用时,此优化可以更广泛地应用。)

3.3. 样式容器

为一个元素赋予样式容器会产生以下效果:

  1. counter-incrementcounter-set属性必须限定在元素的子树内,并创建一个新的计数器。

  2. content属性的open-quoteclose-quoteno-open-quoteno-close-quote的效果必须限定在元素的子树内

    注意: 这意味着子树中的引用嵌套深度保持不变,并从其上下文通常暗示的值开始,但这些值在子树内对引用嵌套深度的更改不会影响子树外的引用嵌套深度。

注意: [CSS-REGIONS-1]样式容器如何影响区域有规范性要求。

限定属性的效果被限定在特定元素或子树内。

由于counter-increment被限定在元素的子树内,因此子树内的第一次使用表现得好像在限定元素处将命名计数器设置为0,无论该计数器是否在限定元素外使用过。子树内的任何增量对限定元素外的同名计数器没有影响。但是,counter()counters()content属性值本身并未限定,可以引用在子树外建立的计数器。因此,以下代码将显示为1 1.2
<div></div>
div {
  contain: style;
  counter-increment: n;
}
div::before, div::after {
  content: counters(n, '.') " ";
}
div::after {
  counter-increment: n 2;
}

3.3.1. 可能的样式容器优化

本节为非规范性内容。

样式容器可能启用的优化包括(但不限于):

  1. 当一个具有样式容器的元素的后代元素上的属性发生变化时,计算DOM树的哪些部分被“弄脏”并可能需要重新计算样式,可以在具有样式容器的元素处停止。

3.4. 绘制容器

为一个元素赋予绘制容器会使其主框成为一个绘制容器框,并具有以下效果:

  1. 元素的内容(包括任何墨水溢出可滚动溢出)必须剪裁到溢出剪裁边缘绘制容器框内,考虑[[css-backgrounds-3#corner clipping|角剪裁]]。这不包括创建任何机制来访问或指示被剪裁内容的存在;也不妨碍通过其他属性创建任何此类机制,例如溢出调整大小文本溢出

    注意: 此剪裁形状尊重overflow-clip-margin,允许具有绘制容器的元素仍然稍微超出其正常边界。

    注意: 本段描述的行为相当于在使用值时将overflow-x: visible更改为overflow-x: clip,并将overflow-y: visible更改为overflow-y: clip,而其他overflow-xoverflow-y的值保持不变。

  2. 绘制容器框建立一个绝对定位包含块固定定位包含块

  3. 绘制容器框创建一个堆叠上下文

  4. 绘制容器框 建立一个独立的格式化上下文

然而,当满足以下任意条件时,为一个元素赋予绘制容器将无效:

3.4.1. 可能的绘制容器优化

本节为非规范性内容。

绘制容器可能启用的优化包括(但不限于):

  1. 如果容器框不在屏幕上或被遮挡,UA通常可以跳过尝试绘制其内容,因为它们也保证处于屏幕外/被遮挡状态。

    注意: 某 些绘制效果(如blur()滤镜)具有非局部效果。用户代理需要跟踪这些效果,因为当其后代发生变化时,即使它们具有绘制容器且本可以跳过,也可能需要重新绘制带有此类滤镜的元素的部分内容。

  2. 除非通过其他机制(如溢出调整大小文本溢出属性)使剪裁内容可访问,UA可以为该框保留与框大小完全一致的“画布”空间。(在类似的可滚动情况下,如overflow: hidden,可以滚动到当前被剪裁的内容,所以UA通常会预见性地多绘制一些,以便在滚动发生时立即显示内容,而不是在稍后的一帧中显示。)

  3. 因为它们保证是堆叠上下文,滚动元素可以绘制到单个GPU图层中。

4. 完全抑制元素的内容:content-visibility属性

名称: content-visibility
值: visible | auto | hidden
初始值: visible
适用于: 可以应用布局容器的元素
继承:
百分比: 不适用
计算值: 按指定值
规范顺序: 按语法
动画类型: 不可动画

content-visibility属性控制元素是否完全渲染其内容,同时强制实施一系列容器,允许用户代理在需要之前省略大量布局和渲染工作。该属性具有以下值:

visible

无效。元素的内容按常规布局和渲染。

hidden

元素跳过其内容

跳过的内容必须对用户代理功能(例如页面查找、Tab顺序导航等)不可访问,也不可选中或聚焦。

注意: 这类似于将内容设置为display: none

auto

为元素开启布局容器样式容器绘制容器

如果该元素对用户不相关,它也会跳过其内容

hidden不同,跳过的内容必须仍然可以被用户代理功能正常访问,例如页面查找、Tab顺序导航等,并且必须能够正常聚焦和选择。

当一个元素跳过其内容时,用户代理必须更改使用值contain属性,以便为布局容器样式容器绘制容器尺寸容器启用。进一步的,其内容(该元素的扁平树后代,包括文本和元素,或替换元素的替换内容)不会被绘制(就像它们具有visibility: hidden)并且不会响应点击测试(就像它们具有pointer-events: none),并且在很大程度上不会更新其样式,除非通过脚本明确请求(有关详细信息,请参见§ 4.4 限制和说明)。

用户代理尽可能避免对跳过的内容进行布局/渲染工作;重度容器和使内容不可见且不可触摸的组合允许进行重度优化。如果某个时刻进行了渲染工作,用户代理应保留先前计算的布局状态,以便稍后可以快速显示跳过的内容

如果一个元素的值不是content-visibility: visible,则以下属性成立:
  • 布局容器确保用户代理能够在跳过的子树中省略布局工作,因为这种布局的结果不会影响容器元素外的元素。

  • 样式容器确保在跳过的子树中不需要处理计数器,因为它们不会影响容器元素外的计数器。

  • 绘制容器确保绘制内容的墨水溢出被剪裁;这反过来意味着用户代理可以可靠地确定元素的可见部分何时接近视口(并且,对于content-visibility: auto,开始绘制它)。

  • 尺寸容器确保用户代理能够在跳过的子树中省略布局,因为这种布局的结果不会影响容器元素的大小。

请注意,在content-visibility: auto的情况下,即使元素未被跳过布局容器样式容器绘制容器仍然存在。这是为了防止由于元素进入和退出跳过状态而导致的容器更改所引起的布局变化。

如果满足以下任意条件,则元素对用户相关:

4.1. 使用content-visibility: hidden

本节为非规范性内容。

content-visibility: hidden对元素施加了强大的限制,因此应谨慎使用。它还启用了一些非常有用的场景,通常改进了现有技术,以下是其中一些。

  1. 如果页面需要对不会被渲染的元素或文本进行一些测量,通常会将要测量的内容定位到屏幕外,使用类似于position: absolute; left: -100000px;,然后调用类似getBoundingClientRect()的API。

    不幸的是,即使页面从未打算显示这些内容,用户代理仍然必须为这些内容执行完整的样式、布局和渲染工作,以防它影响屏幕上的显示。作者也不能保证内容不会意外出现在屏幕上;即使是非常负的left值(如上所述)可能也不足以确保这一点,具体取决于内容。

    将这些内容包装在一个content-visibility: hidden容器中解决了所有这些问题。如果包装器没有边框、背景等,那么它和它的跳过的内容保证永远不会渲染到屏幕上,无论它们有多大。因为内容被跳过,用户代理也可以避免对其进行样式处理或布局,直到脚本最终需要时。

  2. 一个“单页应用程序”通常由几个独立的窗格或“视图”组成,其中只有一个同时显示。

    如果作者想要避免为非活动视图支付样式/布局/渲染等成本,他们可以将其完全从文档中移除,或者至少对其应用display:none。不幸的是,这意味着当视图确实需要显示时,所有样式/布局/渲染等工作都需要一次性完成,可能会导致视图实际显示之前的明显延迟。

    或者,可以将视图定位到屏幕外。这意味着当需要使用时,它将立即准备好,但它会一直消耗样式/布局/渲染的成本,这可能是显著的,特别是如果有许多非活动视图。非活动视图也可能仍然会出现在辅助工具中,混淆使用屏幕阅读器的用户、使用Ctrl-F进行页面查找的人等。

    content-visibility: hidden改进了这两种选项。因为内容被跳过,当它们不活动时,用户代理不会花费时间在它们上。它们也不会对屏幕阅读器、页面查找和其他工具可见。并且因为用户代理尽可能保留以前的样式/布局工作,如果视图以前已经显示过,重新渲染它可能会非常快。

  3. 如果作者想让一个元素“不可见”,但仍然在页面中显示以用于布局目的,一个选项是visibility: hidden。然而,visibility: hidden元素的后代可以设置visibility: visible并重新显示,这并不总是直观或预期的。

    content-visibility: hidden执行非常类似的功能,但后代无法“关闭”它并开始显示;它们保持“隐藏”,直到祖先关闭它。

    因为content-visibility: hidden还将许多容器值应用于容器,它并不总是像visibility: hidden那样可用,但当其限制可以接受时,它可以是一种更可靠、更一致的方式来隐藏元素的内容。

4.2. 使用content-visibility: auto

本节为非规范性内容。

content-visibility: autohidden更复杂;它不是类似于display: none,而是随着元素的内容变得与用户相关时,自适应地隐藏/显示元素的内容。它也不会将其跳过的内容从用户代理中隐藏,因此屏幕阅读器、页面查找和其他工具仍然可以与其交互。

最好将其视为容器的升级:如果作者有大量内容需要显示,并且这些内容通常会在屏幕外(例如一个可滚动的长列表),并且该内容可以接受重度容器,他们应该考虑使用content-visibility: auto一次性应用所有的容器。这也强烈暗示用户代理可以跳过内容的工作(可能会导致内容进入屏幕时出现小延迟),因为文档中有大量内容,其中大部分内容无论如何都不会被看到。

注意:因此,content-visibility: auto可以替代复杂的“虚拟列表”技术,至少在许多情况下可以如此。

由于content-visibility: auto只有在元素的内容对用户不相关时才会导致元素跳过其内容,因此最好在合理细粒度下使用。

例如,在Twitter上,将content-visibility: auto应用于整个时间线并不会产生多大效果——它总是在屏幕上,因此它永远不会跳过其内容

相反,content-visibility应该应用于单个推文,允许它们在离开屏幕时被跳过

由于content-visibility: auto在元素跳过其内容时会施加尺寸容器,如果元素依赖于其内容来确定其大小,页面布局(或至少,滚动条位置)可能会在元素离开屏幕并开始跳过时“跳动”。

这可以通过多种方式修复:

例如,在Twitter上,平均推文约为200px高,因此contain-intrinsic-size: auto 500px 200px将确保滚动条滑块大致处于正确的大小和位置,即使前面的或后面的推文被跳过,同时仍然允许推文在屏幕上时根据其内容进行调整。只要推文至少被查看过一次(并且在它们跳过时没有改变大小),它们的大小将准确无误地在跳过时被保留,因此滚动条滑块也将如此;只有新加载的推文(例如当你向下滚动时在时间线顶部加载的推文)将不得不依赖200px的高度估计。

4.3. 检测content-visibility: auto状态变化:contentvisibilityautostatechanged事件

当渲染状态发生变化并且元素开始或停止与用户相关时,具有content-visibility: auto样式的元素上会触发contentvisibilityautostatechanged事件。

此事件通过在状态变化发生时发布任务来调度。

[Exposed=Window]
interface ContentVisibilityAutoStateChangedEvent : Event {
  constructor(DOMString type, optional ContentVisibilityAutoStateChangedEventInit eventInitDict = {});
  readonly attribute boolean skipped;
};
dictionary ContentVisibilityAutoStateChangedEventInit : EventInit {
  boolean skipped = false;
};

ContentVisibilityAutoStateChangedEvent属性描述:

skipped 类型为boolean,只读

如果目标状态更改为跳过其内容,则设置为true,否则为false。

ContentVisibilityAutoStateChangedEventInit成员描述:

skipped 类型为boolean,默认值为false

请参阅skipped属性的描述。

请注意,即使在content-visibility: auto子树中的元素跳过其内容,它们仍然在语义上与元素相关。这意味着使用此信号无限期地跳过被跳过子树中的DOM更新是不合适的。相反,它应该用于降低更新的优先级,但确保内容在语义上保持相关并且合理地保持最新。这对于即使在祖先设置为跳过其内容时仍然使用这些内容的辅助技术尤为重要。

4.4. 限制和澄清

  1. IntersectionObserver的角度来看,元素的跳过的内容从不与交叉根相交。即使根和目标元素都在跳过的内容中,这一点也成立。

  2. ResizeObserver的角度来看,元素的跳过的内容的大小从不变化。如果这些元素后来变为非跳过状态,则会在新大小与最后一次通知的大小不同的情况下,传递大小调整观察结果。

  3. 如果元素开始或停止跳过其内容,此更改发生在渲染更改效果的帧的requestAnimationFrame回调运行之后。具体来说,这些更改将在处理模型的更新渲染步骤的步骤13和14之间生效(在“运行动画帧回调”和“运行更新交叉观察步骤”之间)。

    可以使用IntersectionObserver的内部版本来确定元素的视口交集。但是,由于这些观察结果是在更新渲染的第14步调度的,因此对跳过(从而绘制)状态的更改直到下一帧的处理才会对用户可见。因此,更新跳过状态(包括包含调整)也推迟到该帧。这确保了脚本访问,例如,在这两个事件之间(内部交叉观察和跳过状态更新)元素的包含值时,将检索与当前绘制状态一致的值,并且不会导致任何强制布局。
  4. 对于content-visibility: auto的初始可见性判断必须在确定新content-visibility: auto元素存在的同一帧中进行。

    当元素首次获得content-visibility: auto时,它可能会或可能不会被定位在屏幕上。此状态的确定以及是否跳过该元素的判断必须在同一帧中完成。如果未完成,则可能会在元素位置产生空白内容,因为可见性检查和跳过状态更新将推迟到下一帧。
  5. 就滚动操作而言,例如scrollIntoView(),具有content-visibility: auto跳过其内容的元素的大小和位置是在尺寸包含仍然活跃的情况下确定的。

    注意:一旦滚动到视图中,元素将不再跳过其内容,因此可能不会再具有尺寸包含;如果这改变了元素的大小,它可能不会像请求的那样准确对齐在视口中。

    如果一个元素对用户代理功能不可用(例如,由于跳过了一个content-visibility: hidden祖先),则滚动操作不应滚动到该元素,仿佛它没有布局框一样。

  6. 如果具有content-visibility: auto跳过其内容的元素被聚焦(或其内容被聚焦),它将在由于聚焦而滚动到视图之前变为与用户相关(因此停止跳过其内容)。

    注意:因此,与上一点不同,元素被正确地调整大小并在视口中对齐。这与focus()方法的步骤顺序是一致的。

  7. 如果一个iframe跳过其内容或是元素的跳过内容的一部分,用户代理应该在可能的情况下完全跳过iframe事件循环中的更新渲染步骤。

    注意:一旦iframe开始跳过其内容,它需要至少运行一次该步骤以移除已绘制的输出。

  8. 跳过的内容不计入innerText的结果。

  9. 当元素处于跳过状态时,CSS过渡和动画不会更新:

    • 即使新应用的样式会启动动画,也不会创建新的动画。

    • 现有的动画不会在时间线上前进。

    • 元素上的运行动画不会结束。

    如果脚本查询跳过元素的样式(引发样式更改事件),以致需要知道动画或过渡的状态才能返回正确信息,则动画和过渡将根据样式更改事件时的样式进行采样:

    CSS Animations 2 § 4 动画事件CSS Transitions 2 § 5 过渡事件定义了对象何时创建,何时触发事件,以及触发的事件数据。

    当元素停止跳过状态时,动画和过渡将被采样,然后从该点起正常推进时间线。

    注意:总体而言,这类似于当背景标签被带回前台时过渡/动画的行为,使用户代理能够尽可能跳过不必要的动画工作,而不会过度干扰动画在重新变得相关时的表现。

  10. 当元素处于跳过状态时,它不应启动任何过渡,即使样式更改事件影响了其计算样式。

    当元素停止跳过状态时,不应由于与其不再处于跳过状态相关联的样式更改事件而启动任何过渡。

    注意:这类似于元素从display:none切换到非none值——即使在这种情况下样式技术上在更改(从初始值到层叠的“适当”值),也不会启动任何过渡。

  11. 如果元素有一个content-visibility: hidden的祖先,并且它被放置在顶层中,则它不会生成任何框,就像它具有display: none一样。

    注意:由于其他原因而跳过的元素,例如具有content-visibility: auto祖先,仍将正常生成框,并可能因此变为非跳过状态。

4.5. 无障碍影响

如果用户代理暴露某种形式的“无障碍树”,类似于DOM树但专门用于无障碍用例,例如屏幕阅读器(从而提供与无障碍API相关的元素位置等),那么跳过的内容content-visibility: hidden元素中也必须类似地在无障碍树中“跳过”(省略)(类似于display: none元素在文档的所有视图中被省略)。

跳过的内容content-visibility: auto元素中不得暴露用户通过无障碍树与页面交互的事实,而不是通过视觉呈现在屏幕上。特别是,如果用户代理使用content-visibility: auto避免对屏幕上未显示的内容进行布局和绘制工作,那么它也必须避免对无障碍树中未显示的内容进行此类工作。如果这不可能(例如,如果用户代理在无障碍树中表示一个可聚焦元素需要知道其确切位置,因此需要对其及周围内容进行完整布局),那么用户代理必须完全省略无障碍树中的跳过的内容

注意:此要求旨在保护使用无障碍工具的用户免于通过时间通道的观察被识别和分析;如果用户代理在视觉呈现时可以跳过大量工作,但在呈现给无障碍树时必须完成所有工作,那么作者可以通过观察布局操作的时间来判断用户如何与页面交互。

4.6. 示例

<style>
.sv {
  content-visibility: auto;
  min-height: 50px;
}
</style>

<div class=sv>
  ... some content goes here ...
</div>

.sv 元素的 content-visibility: auto 值允许用户代理管理元素是否被跳过。特别是当此元素接近视口时,用户代理将开始绘制元素。当元素移离视口时,它将停止绘制。此外,当元素被跳过时,用户代理应尽可能跳过渲染工作。

<style>
.sv {
  content-visibility: hidden;
}
</style>

<div class=sv>
  ... some content goes here ...
</div>

在此示例中,无论视口交集如何,元素都被跳过。这意味着唯一能让内容绘制出来的方法是通过脚本更新值以删除content-visibility或更改其值。同样,用户代理应尽可能跳过内容中的渲染工作。

跳过渲染的附加效果是用户代理可以保留内容的布局状态,因此将来删除content-visibility属性时,内容的渲染速度会比使用display: none或类似方式隐藏时更快。

<style>
body {
  margin: 0;
}
.sv {
  content-visibility: hidden;
  position: relative;
  left: 10px;
  top: 20px;
}
#child {
  position: relative;
  left: 1px;
  top: 2px;
  width: 100px;
  height: 200px;
}
</style>

<div id=target class=sv>
  <div id=child></div>
  ... some other content goes here ...
</div>
<script>
  ...
  // This will force rendering work, including layout,
  // if the UA previously avoided it.
  target.firstElementChild.getBoundingClientRect();
  ...
</script>

与上一个示例类似,元素被跳过。用户代理应尽可能避免渲染工作。然而,在此示例中,在某个时刻脚本访问了元素内容中的布局值。在这种情况下,用户代理无法避免渲染工作,并且必须处理任何先前跳过的渲染工作,以便向调用者返回正确的值。在此示例中,getBoundingClientRect()的结果是一个位置为 (11, 22) 且大小为 100x200 的矩形。

请注意,对同一布局值的重复调用不应导致任何额外的渲染工作,因为用户代理应保留最后更新的渲染状态。

还请注意,需要渲染工作的这种情况并不是唯一的。在某些其他情况下,用户代理可能也无法避免渲染工作。

5. 隐私考虑

本规范中的功能没有已知的隐私影响。

6. 安全考虑

本规范中的功能没有已知的安全影响。

像其他任何 CSS 规范一样,它影响文档的渲染,但不会引入任何特殊能力,以之前未通过其他 CSS 模块提供的方式,或者通过格式化文档行为本身误导性地呈现内容。

附录 A. 变更

本附录是说明性的。

2020-12-16 工作草案以来的变更

2020-06-03 工作草案以来的变更

2019-11-11 工作草案以来的变更

CSS 包含级别 1以来的变更

一致性

文档约定

一致性要求通过描述性断言和 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 语法及本模块中定义的各个特性语法,则该样式表符合本规范。

如果渲染器不仅能够按照适当的规范解释样式表,还能够通过正确解析本规范定义的所有特性并相应地渲染文档,则该渲染器符合本规范。然而,如果用户代理由于设备限制无法正确渲染文档,并不意味着该用户代理不符合规范。(例如,用户代理不要求在单色显示器上渲染颜色。)

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

部分实现

为了使作者能够利用向前兼容的解析规则分配回退值,CSS 渲染器必须将其无法使用的所有 at-rules、属性、属性值、关键词和其他语法结构视为无效(并适当地忽略)。特别是,用户代理不得在单个多值属性声明中有选择性地忽略不受支持的组件值并使用受支持的值:如果任何值被认为无效(因为不受支持的值必须是无效的),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]
Bert Bos; Elika Etemad; Brad Kemper. CSS Backgrounds and Borders Module Level 3. 2021年7月26日. CR. URL: https://www.w3.org/TR/css-backgrounds-3/
[CSS-BOX-4]
Elika Etemad. CSS Box Model Module Level 4. 2020年4月21日. WD. URL: https://www.w3.org/TR/css-box-4/
[CSS-BREAK-3]
Rossen Atanassov; Elika Etemad. CSS Fragmentation Module Level 3. 2018年12月4日. CR. URL: https://www.w3.org/TR/css-break-3/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 2022年1月13日. CR. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-CONTAIN-1]
Tab Atkins Jr.; Florian Rivoal. CSS Containment Module Level 1. 2020年12月22日. REC. URL: https://www.w3.org/TR/css-contain-1/
[CSS-CONTENT-3]
Elika Etemad; Dave Cramer. CSS Generated Content Module Level 3. 2019年8月2日. WD. URL: https://www.w3.org/TR/css-content-3/
[CSS-DISPLAY-3]
Tab Atkins Jr.; Elika Etemad. CSS Display Module Level 3. 2021年9月3日. CR. URL: https://www.w3.org/TR/css-display-3/
[CSS-IMAGES-3]
Tab Atkins Jr.; Elika Etemad; Lea Verou. CSS Images Module Level 3. 2020年12月17日. CR. URL: https://www.w3.org/TR/css-images-3/
[CSS-INLINE-3]
Dave Cramer; Elika Etemad; Steve Zilles. CSS Inline Layout Module Level 3. 2020年8月27日. WD. URL: https://www.w3.org/TR/css-inline-3/
[CSS-LISTS-3]
Elika Etemad; Tab Atkins Jr.. CSS Lists and Counters Module Level 3. 2020年11月17日. WD. URL: https://www.w3.org/TR/css-lists-3/
[CSS-OVERFLOW-3]
David Baron; Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. 2021年12月23日. WD. URL: https://www.w3.org/TR/css-overflow-3/
[CSS-POSITION-3]
Elika Etemad; Tab Atkins Jr.. CSS Positioned Layout Module Level 3. 2022年9月1日. WD. URL: https://www.w3.org/TR/css-position-3/
[CSS-PSEUDO-4]
Daniel Glazman; Elika Etemad; Alan Stearns. CSS Pseudo-Elements Module Level 4. 2020年12月31日. WD. URL: https://www.w3.org/TR/css-pseudo-4/
[CSS-SCOPING-1]
Tab Atkins Jr.; Elika Etemad. CSS Scoping Module Level 1. 2014年4月3日. WD. URL: https://www.w3.org/TR/css-scoping-1/
[CSS-SIZING-3]
Tab Atkins Jr.; Elika Etemad. CSS Box Sizing Module Level 3. 2021年12月17日. WD. URL: https://www.w3.org/TR/css-sizing-3/
[CSS-TRANSITIONS-1]
David Baron; et al. CSS Transitions. 2018年10月11日. WD. URL: https://www.w3.org/TR/css-transitions-1/
[CSS-UI-3]
Tantek Çelik; Florian Rivoal. CSS Basic User Interface Module Level 3 (CSS3 UI). 2018年6月21日. REC. URL: https://www.w3.org/TR/css-ui-3/
[CSS-UI-4]
Florian Rivoal. CSS Basic User Interface Module Level 4. 2021年3月16日. WD. URL: https://www.w3.org/TR/css-ui-4/
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. 2019年6月6日. CR. URL: https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2021年12月16日. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-WRITING-MODES-3]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 3. 2019年12月10日. REC. URL: https://www.w3.org/TR/css-writing-modes-3/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. 2019年7月30日. CR. URL: https://www.w3.org/TR/css-writing-modes-4/
[CSS2]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 2011年6月7日. REC. URL: https://www.w3.org/TR/CSS21/
[CSSOM-VIEW-1]
Simon Pieters. CSSOM View Module. 2016年3月17日. WD. URL: https://www.w3.org/TR/cssom-view-1/
[DOM]
Anne van Kesteren. DOM Standard. 现行标准. URL: https://dom.spec.whatwg.org/
[FULLSCREEN]
Philip Jägenstedt. Fullscreen API Standard. 现行标准. URL: https://fullscreen.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. 现行标准. URL: https://html.spec.whatwg.org/multipage/
[INTERSECTION-OBSERVER]
Stefan Zager; Emilio Cobos Álvarez. Intersection Observer. 2022年7月6日. WD. URL: https://www.w3.org/TR/intersection-observer/
[RESIZE-OBSERVER-1]
Aleks Totic; Greg Whitworth. Resize Observer. 2020年2月11日. WD. URL: https://www.w3.org/TR/resize-observer-1/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997年3月. 最佳现行规范. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SVG2]
Amelia Bellamy-Royds; et al. Scalable Vector Graphics (SVG) 2. 2018年10月4日. CR. URL: https://www.w3.org/TR/SVG2/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. 现行标准. URL: https://webidl.spec.whatwg.org/

参考性引用

[CSS-GRID-2]
Tab Atkins Jr.; Elika Etemad; Rossen Atanassov. CSS Grid Layout Module Level 2. 2020年12月18日. CR. URL: https://www.w3.org/TR/css-grid-2/
[CSS-MULTICOL-1]
Florian Rivoal; Rachel Andrew. CSS Multi-column Layout Module Level 1. 2021年10月12日. CR. URL: https://www.w3.org/TR/css-multicol-1/
[CSS-OVERFLOW-4]
David Baron; Florian Rivoal. CSS Overflow Module Level 4. 2017年6月13日. WD. URL: https://www.w3.org/TR/css-overflow-4/
[CSS-PAGE-3]
Elika Etemad; Simon Sapin. CSS Paged Media Module Level 3. 2018年10月18日. WD. URL: https://www.w3.org/TR/css-page-3/
[CSS-REGIONS-1]
Rossen Atanassov; Alan Stearns. CSS Regions Module Level 1. 2014年10月9日. WD. URL: https://www.w3.org/TR/css-regions-1/
[CSS-SIZING-4]
Tab Atkins Jr.; Elika Etemad; Jen Simmons. CSS Box Sizing Module Level 4. 2021年5月20日. WD. URL: https://www.w3.org/TR/css-sizing-4/
[FILTER-EFFECTS-1]
Dirk Schulze; Dean Jackson. Filter Effects Module Level 1. 2018年12月18日. WD. URL: https://www.w3.org/TR/filter-effects-1/

属性索引

名称 初始值 应用于 继承 百分比 动画类型 标准顺序 计算值
contain none | strict | content | [ size || layout || style || paint ] none 见下文 不适用 不可动画 按照语法 关键字 none 或 size、layout、paint 中的一个或多个
content-visibility visible | auto | hidden visible 适用于可以应用布局封闭的元素 不适用 不可动画 按照语法 按指定值

IDL 索引

[Exposed=Window]
interface ContentVisibilityAutoStateChangedEvent : Event {
  constructor(DOMString type, optional ContentVisibilityAutoStateChangedEventInit eventInitDict = {});
  readonly attribute boolean skipped;
};
dictionary ContentVisibilityAutoStateChangedEventInit : EventInit {
  boolean skipped = false;
};