content-visibility

Avatar of Idorenyin Udoh
Idorenyin Udoh

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费信用额度!

CSS 中的 content-visibility 属性指示浏览器在初始加载时是否应渲染元素的内容。 因此,当浏览器开始加载内容并将其在屏幕上播放时,此属性允许我们介入并告诉浏览器*不要*加载元素的内容,直到需要它。 可以把它理解为*类似于*延迟加载,因为屏幕外元素的子元素不会在进入视窗之前渲染。

.element {
  content-visibility: hidden;
}

使用 content-visibility 的主要目的是性能。 它有助于加快页面加载速度,因为浏览器能够延迟渲染不在用户视窗中的元素,直到用户滚动到它们。 结果可能很显著。 这里是一项性能测试的结果,Una Kravets 和 Vladimir Levin 共同进行了测试,展示了 content-visibility 在典型网页上可以带来的差异。

来源:web.dev

语法

content-visibility: [visible | auto | hidden];
  • 初始值: visible
  • 应用于:布局包含可以应用的元素
  • 继承:
  • 计算值:如指定
  • 动画类型:不可动画

content-visibility 属性接受三个值之一

  • hidden:元素绕过其内容(有点类似于将 display: none; 应用于内容)。
  • visible:没有效果,元素按正常方式渲染。
  • auto:元素具有布局、样式和绘制包含。 浏览器可以确定此内容是否与用户相关,如果不是,则浏览器将跳过它。 同时,元素仍然可聚焦、可选择并可访问,例如制表键和页面内搜索。

content-visibility: hidden;

我在上面提到它有点类似于 display: none;,因为元素根本没有绘制到页面上。

当规则被删除时,浏览器必须渲染元素及其内容。 但是,使用 content-visibility: hidden; 时,元素是隐藏的,但其**渲染状态被缓存**。 因此,当规则被删除时,浏览器不必从头开始渲染元素。 因此,您可以在默认情况下隐藏的内容上使用它,但您很有可能在页面的生命周期中显示它(例如,常用的模态)。 这样,当它在后续访问中渲染时,元素加载速度会快得多。

规范中的注释明确说明了 hidden 值的可访问性

跳过内容必须不可访问用户代理功能,例如页面内查找、制表符导航等,也不可选择或可聚焦。

content-visibility: auto;

您可以将其视为整个 DOM 部分的延迟加载

如果元素位于折叠下方,并且具有 content-visibility: auto; 规则,则浏览器不会考虑其任何内容。 因此,该元素的渲染被跳过。 当用户滚动到元素时,浏览器会绘制其内容,并且渲染足够快,以便用户看到。 浏览器决定何时渲染的启发式方法尚不清楚,可能取决于浏览器的决定。

可访问性问题

在使用 content-visibility: hidden 时要小心。 这不仅告诉浏览器在初始页面加载时跳过渲染元素,而且还会阻止辅助技术(如屏幕阅读器)读取该元素。

相反,auto 关键字告诉浏览器,只要元素在屏幕外,元素的内容在初始页面加载时就不需要。 换句话说,该元素被跳过,就像我们使用 hidden 关键字时一样。

然而,auto 也表明该元素**应该仍然对用户可用**,而不是完全忽略 DOM 中的元素。这意味着该元素及其内容应该是可聚焦的、可选择的、可制表符访问的,并且可以通过浏览器的页面内查找功能搜索。再次强调,规范对此非常明确。

hidden 不同,跳过的内容仍应作为正常内容提供给用户代理功能(例如页面内查找、制表符顺序导航等),并且必须像往常一样可聚焦和可选择。

此外,使用 CSS 隐藏的屏幕外元素(例如 display: none;)应该应用 aria-hidden="true",因为浏览器没有渲染它们。这样,它们仍然存在于可访问性树中。

UX 问题

您可以想象,如果网页的大块内容没有渲染,滚动条的长度可能表明页面上的内容比实际内容少得多。Alex Russell 在他的“content-visiblity Without Jittery Scrollbars”文章中谈论了(并已经有了)针对这个问题的解决方案。

性能

再次强调,此属性完全是为了提升性能。结果可能很显著。观看 Jake Archibald 和 Surma 的这段视频,他们演示了此属性的应用,并看到了巨大的变化。

contain-intrinsic-size 属性

自然地,当浏览器最初渲染网页的所有内容时,它会知道显示所有内容所需的高度(基于所有页面部分的单个高度的总和),并且滚动将是无缝的。但是,content-visibility: auto; 应用于元素时,会将该元素视为高度为 0(假设未显式设置 height 属性)。当用户滚动且元素进入视图(浏览器开始绘制它)时,会计算实际高度,这会导致页面布局发生变化。滚动可能会使网页变得有点卡顿——这就是所谓的累积布局偏移 (CLS),它被认为是搜索引擎优化的重要指标,因为 Google 现在将其包含在其衡量网站性能的核心 Web 指标指标中。

解决大型布局变化的方案是将 content-visibility: auto;contain-intrinsic-size 配合使用,为浏览器提供一个可预测的高度,以便在绘制元素时用作占位符。

.off-screen-parent {
  content-visibility: auto;
  contain-intrinsic-size: 4800px; /* A guess at the height of it */
}

contain-intrinsic-size 充当未渲染内容的占位符。从而抑制了滚动和布局变化问题。因此,如果您知道确切的高度,就可以将其用作该值。如果不知道,请进行估计。当渲染该部分时,如果设置的高度不是实际高度,那么将会发生一点布局变化,但它不会像没有 contain-intrinsic-size 属性时那样明显。

演示

我创建了一个带有虚拟文本和总共 185 张图片的基本网站

A screenshot of the site

我使用GitHub Pages 进行托管。一个分支具有 content-visibilitycontain-intrinsic-size 属性,另一个则没有。所以我将两者进行比较。

未将 content-visibility 应用于元素时的结果。
使用 content-visibility 渲染的页面速度大约是前者的四分之一。

浏览器支持

这些浏览器支持数据来自Caniuse,其中提供了更多详细信息。数字表示浏览器从该版本开始支持该功能。

桌面

ChromeFirefoxIEEdgeSafari
85125不支持8518.0

移动设备/平板电脑

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712718.0

更多信息