content-visibility

Baseline 2024 *
新推出

自 2024 年 9 月起,此功能已可在最新设备和浏览器版本上使用。此功能可能无法在旧设备或浏览器上使用。

* 此特性的某些部分可能存在不同级别的支持。

content-visibility CSS 属性控制元素是否渲染其内容,并强制执行一组严格的包含策略,允许用户代理在内容需要时才执行大量的布局和渲染工作。它允许用户代理跳过元素的渲染工作(包括布局和绘制),直到需要时才执行——这使得初始页面加载速度更快。

注意:当设置了 content-visibility: auto 的元素的渲染工作开始或停止跳过时,contentvisibilityautostatechange 事件会在该元素上触发。这为应用程序代码在不需要时开始或停止渲染过程(例如,在 <canvas> 上绘图)提供了一种便捷的方式,从而节省处理能力。

试一试

content-visibility: visible;
content-visibility: hidden;
<section class="default-example" id="default-example">
  <div class="container" id="example-element">
    <div class="child">
      <span>This is an inner div</span>
    </div>
  </div>
</section>
.container {
  width: 140px;
  height: 140px;
  border: 3px solid rgb(64 28 163);
  background-color: rgb(135 136 184);
  display: flex;
  align-items: center;
  justify-content: center;
}

.child {
  border: 3px solid rgb(64 28 163);
  background-color: wheat;
  color: black;
  width: 80%;
  height: 80%;
  display: flex;
  align-items: center;
  justify-content: center;
}

语法

css
/* Keyword values */
content-visibility: visible;
content-visibility: hidden;
content-visibility: auto;

/* Global values */
content-visibility: inherit;
content-visibility: initial;
content-visibility: revert;
content-visibility: revert-layer;
content-visibility: unset;

visible

无效果。元素的內容按正常方式布局和渲染。这是默认值。

hidden

元素跳过其内容。跳过的内容不得被用户代理功能(例如页面查找、Tab 键顺序导航等)访问,也不得被选中或聚焦。这类似于为内容设置 display: none

auto

元素启用布局包含、样式包含和绘制包含。如果元素与用户无关,它还会跳过其内容。与 hidden 不同,跳过的内容必须仍可正常用于用户代理功能,例如页面查找、Tab 键顺序导航等,并且必须可正常聚焦和选择。

描述

content-visibility 的动画和过渡

支持的浏览器使用 离散动画类型 的变体来动画/过渡 content-visibility

离散动画通常意味着属性将在动画进行到 50% 时在两个值之间翻转。然而,对于 content-visibility,浏览器将在两个值之间翻转,以在整个动画持续时间内显示动画内容。例如:

  • 当从 hiddenvisible 动画 content-visibility 时,该值将在动画持续时间的 0% 翻转为 visible,使其在整个过程中可见。
  • 当从 visiblehidden 动画 content-visibility 时,该值将在动画持续时间的 100% 翻转为 hidden,使其在整个过程中可见。

此行为对于创建进入/退出动画很有用,例如,您希望使用 content-visibility: hidden 从 DOM 中删除某些内容,但您希望实现平滑过渡(例如淡出)而不是立即消失。

当使用 CSS 过渡content-visibility 进行动画处理时,需要在 content-visibility 上设置 transition-behavior: allow-discrete。这有效地启用了 content-visibility 过渡。

注意:在过渡元素的 content-visibility 值时,您不需要像 过渡 display 那样,使用 @starting-style 块为过渡属性提供一组起始值。这是因为 content-visibility 不像 display 那样将元素从 DOM 中隐藏:它只是跳过渲染元素的内容。

正式定义

初始值visible
应用于可应用尺寸限制的元素
继承性
计算值同指定值
动画类型离散行为,除非动画到或从 hidden,否则在整个持续时间内都可见

正式语法

content-visibility = 
visible |
auto |
hidden

无障碍

具有 content-visibility: auto 属性的屏幕外内容仍保留在文档对象模型和可访问性树中。这允许在不负面影响可访问性的情况下通过 content-visibility: auto 提高页面性能。

由于不渲染屏幕外内容的样式,使用 display: nonevisibility: hidden 故意隐藏的元素仍将出现在可访问性树中。如果您不希望元素出现在可访问性树中,请使用 aria-hidden="true"

示例

使用 auto 降低长页面的渲染成本

以下示例展示了使用 content-visibility: auto 跳过屏幕外部分的绘制和渲染。当 section 位于视口之外时,内容的绘制将被跳过,直到该部分接近视口,这有助于页面加载和交互。

HTML

html
<section>
  <!-- Content for each section… -->
</section>
<section>
  <!-- Content for each section… -->
</section>
<section>
  <!-- Content for each section… -->
</section>
<!-- … -->

CSS

contain-intrinsic-size 属性为每个 section 元素的高度和宽度添加了一个 500px 的默认大小。渲染后,即使滚动到视口之外,它也将保留其渲染的固有大小。

css
section {
  content-visibility: auto;
  contain-intrinsic-size: auto 500px;
}

使用 hidden 管理可见性

以下示例展示了如何使用 JavaScript 管理内容可见性。使用 content-visibility: hidden; 而不是 display: none; 可以保留内容隐藏时的渲染状态,并且渲染速度更快。

HTML

html
<div class="hidden">
  <button class="toggle">Show</button>
  <p>
    This content is initially hidden and can be shown by clicking the button.
  </p>
</div>
<div class="visible">
  <button class="toggle">Hide</button>
  <p>
    This content is initially visible and can be hidden by clicking the button.
  </p>
</div>

CSS

content-visibility 属性设置在具有 visiblehidden 类元素的直接子段落上。在我们的示例中,我们可以根据父 div 元素的 CSS 类来显示和隐藏段落中的内容。

包含 contain-intrinsic-size 属性以表示内容大小。这有助于在内容隐藏时减少布局偏移。

css
p {
  contain-intrinsic-size: 0 1.1em;
  border: dotted 2px;
}

.hidden > p {
  content-visibility: hidden;
}

.visible > p {
  content-visibility: visible;
}

JavaScript

js
const handleClick = (event) => {
  const button = event.target;
  const div = button.parentElement;
  button.textContent = div.classList.contains("visible") ? "Show" : "Hide";
  div.classList.toggle("hidden");
  div.classList.toggle("visible");
};

document.querySelectorAll("button.toggle").forEach((button) => {
  button.addEventListener("click", handleClick);
});

结果

内容可见性动画

在此示例中,我们有一个 <div> 元素,其内容可以通过点击或按下任意键在显示和隐藏之间切换。

HTML

html
<p>
  Click anywhere on the screen or press any key to toggle the
  <code>&lt;div&gt;</code> content between hidden and showing.
</p>

<div>
  This is a <code>&lt;div&gt;</code> element that animates between
  <code>content-visibility: hidden;</code>and
  <code>content-visibility: visible;</code>. We've also animated the text color
  to create a smooth animation effect.
</div>

CSS

在 CSS 中,我们最初在 <div> 上设置 content-visibility: hidden; 以隐藏其内容。然后,我们设置 @keyframes 动画并将其附加到类,以显示和隐藏 <div>,动画 content-visibilitycolor,以便在内容显示/隐藏时获得平滑的动画效果。

css
div {
  font-size: 1.6rem;
  padding: 20px;
  border: 3px solid red;
  border-radius: 20px;
  width: 480px;

  content-visibility: hidden;
}

/* Animation classes */

.show {
  animation: show 0.7s ease-in forwards;
}

.hide {
  animation: hide 0.7s ease-out forwards;
}

/* Animation keyframes */

@keyframes show {
  0% {
    content-visibility: hidden;
    color: transparent;
  }

  100% {
    content-visibility: visible;
    color: black;
  }
}

@keyframes hide {
  0% {
    content-visibility: visible;
    color: black;
  }

  100% {
    content-visibility: hidden;
    color: transparent;
  }
}

JavaScript

最后,我们使用 JavaScript 将 .show.hide 类适当地应用于 <div>,以便在它在显示和隐藏状态之间切换时应用动画。

js
const divElem = document.querySelector("div");
const htmlElem = document.querySelector(":root");

htmlElem.addEventListener("click", showHide);
document.addEventListener("keydown", showHide);

function showHide() {
  if (divElem.classList.contains("show")) {
    divElem.classList.remove("show");
    divElem.classList.add("hide");
  } else {
    divElem.classList.remove("hide");
    divElem.classList.add("show");
  }
}

结果

渲染结果如下所示:

规范

规范
CSS 包含模块第 2 级
# content-visibility

浏览器兼容性

另见