包含

Avatar of Travis Almand
Travis Almand

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

CSS 中的 contain 属性指示浏览器尽可能将元素及其后代视为独立于文档树。这有可能在布局、样式、绘制、大小或 DOM 限制区域的任何组合计算中提供性能优势,而不是整个页面。

该属性有五个标准值和两个简写值,它们组合了标准值的变体。每个值根据应用它们的元素的上下文具有一些独特的和共享的优势。

该属性的典型用法是包含某种类型内容的元素。考虑一个渲染传入数据的部件,该数据会更改元素后代的布局和视觉效果。另一个要考虑的元素是包含第三方数据的元素,例如横幅广告,其中包含的好处让我们可以降低某些内容的绘制优先级,如何处理接收到的内容的大小,或者确定内容是否应该可见。另一方面,一个主要静态的网站将除了在页面加载时第一次布局和绘制到屏幕外几乎不会有任何其他好处。

语法

div {
  contain: none | strict | content | [ size || layout || style || paint ];
}
div {
  contain: none; /* no containment on element */
  contain: layout; /* influences how element relates to other elements in the document */
  contain: paint; /* influences how element is painted to screen */
  contain: size; /* influences how element affects size calculations for the page */
  contain: style; /* is considered at-risk for removal from spec */


  contain: content; /* combines layout and paint */
  contain: strict; /* combines layout, paint, and size */
}

属性值

布局

layout 包含值通知浏览器,元素的任何后代都不会影响页面上的其他元素,反之亦然,其他元素也不会对包含元素的后代有任何影响。这使浏览器有可能减少创建页面布局时所需的计算次数。

另一个好处是,如果包含的元素在屏幕外或以某种方式被遮挡,则浏览器可能会延迟或将相关计算降低优先级。一个例子是包含的元素不在一个块元素的末尾可见,而该块元素的开头是可见的。

具有 layout 包含的元素将成为定位后代的包含框 - 例如具有绝对定位的元素。元素相对于页面获得新的堆叠上下文,并且可以使用 z-index 属性。不过,方向属性(如 topleft)不适用。

即使包含元素的后代可能不会影响页面上的其他元素,它们仍然可以影响其包含的祖先元素。例如,后代会导致包含元素在响应更改时调整大小。在这种情况下,包含的元素仍然可能影响页面上的其他元素,但后代将不再参与这些计算。

以下演示简单说明了应用 layout 包含时会发生什么。点击每个顶部的框,包含就会被应用,红色的箭头会改变外观。红色箭头的外观表明框的后代在布局计算期间是否影响页面上的其他框。

绘制

paint 包含值通知浏览器,元素的任何后代都不会在元素的边框框之外绘制。如果后代元素的位置使其边界框的一部分被包含元素的 border-box 剪切,则该部分将不会被绘制。如果后代元素的位置完全在包含元素的 border-box 外部,则它根本不会被绘制。这类似于将 overflow: hidden; 应用于元素,但没有跳过或减少所需计算的好处。

另一个好处是,如果包含的元素在视窗内以某种方式不可见,则它可能会在执行绘制计算时跳过元素的后代。一个例子是放置在视窗左侧页面外的元素。如果包含的元素不可见,则保证其内容将不可见。因此,它们不需要参与绘制计算。

具有 paint 包含的元素也会成为定位后代的包含框 - 例如具有绝对定位的元素。该元素还相对于页面获得新的堆叠上下文,并且可以使用 z-index 属性。不过,方向属性(如 topleft)不适用。

滚动元素可以通过将其后代放置在一个可以帮助滚动性能的新绘制层中获得额外的好处。通常,滚动元素会导致持续重绘,因为后代在滚动时出现和消失。具有绘制包含的滚动元素可以潜在地跳过滚动后代的这种持续重绘。

以下演示简单说明了应用 paint 包含时会发生什么。点击任意位置切换紫色框的包含。当包含被应用时,一些绿色的框会改变外观。绿色框的外观显示了它们是如何绘制或未绘制的。

尺寸

size 包含值通知浏览器,在执行页面布局计算时,不需要考虑任何后代。包含的元素必须应用 heightwidth 属性,否则它将折叠到零像素正方形。只有元素本身需要考虑用于页面布局计算,因为后代不能影响元素的大小。包含的元素的后代在这些计算中完全被跳过;就好像它根本没有后代一样。

为了充分利用优化优势,size 包含通常与其他包含类型一起应用。

具有 size 包含的元素相对于页面获得新的堆叠上下文,并且可以使用 z-index 属性。不过,方向属性(如 topleft)不适用。

以下演示简单说明了应用 size 包含时会发生什么。点击任意位置切换紫色框的包含。当包含被应用时,紫色框会改变大小。默认情况下,紫色框的高度由其子元素定义,但在包含的情况下,必须定义高度。一旦包含被应用,后代将不再参与与大小相关的布局计算。

样式

style 包含值通知浏览器,一些 CSS 属性(如计数器和引号)将被限定到包含的元素。

counter-incrementcounter-set 属性必须限定到包含元素的子树。如果扩展到包含元素之外,则会创建一个新的计数器。

content 属性的 open-quoteclose-quoteno-open-quoteno-close-quote 值必须限定到包含元素的子树。

该包含值被认为有从规范中删除的风险。

内容

content 包含值是布局和绘制包含值的组合。这相当于以这种方式应用包含。

div {
  contain: layout paint;
}

上面描述的每个值的潜在优势都将适用于包含的元素。这种包含被认为在页面上广泛应用于多个元素是相对安全的。

严格

strict 包含值是 layoutpaintsize 包含值的组合。这相当于以这种方式应用包含。

div {
  contain: layout paint size;
}

上面描述的每个值的潜在优势都将适用于包含的元素。

作为“最严格”的包含值,此值应谨慎使用。这是因为它对包含元素施加了尺寸要求。有了这些要求,此包含值确实提供了包含中最有可能的性能优势。

浏览器支持

此浏览器支持数据来自 Caniuse,它包含更多详细信息。数字表示浏览器从该版本开始支持该功能。

桌面

ChromeFirefoxIEEdgeSafari
52697915.4

移动/平板电脑

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712715.4

其他资源