包含
contain
CSS 属性指示一个元素及其内容在尽可能大的程度上独立于文档树的其余部分。包含功能可以隔离 DOM 的一部分,通过将布局、样式、绘制、大小或任何组合的计算限制到 DOM 子树而不是整个页面来提供性能优势。包含还可以用于限定 CSS 计数器和引号。
试试看
有四种类型的 CSS 包含:大小、布局、样式和绘制,它们都设置在容器上。该属性是一个空格分隔的列表,包含五个标准值的一个子集或两个简写值之一。容器内包含属性的更改不会传播到页面其余部分的包含元素外部。包含的主要好处是浏览器不必经常重新渲染 DOM 或页面布局,从而在渲染静态页面时带来少量性能优势,并在更动态的应用程序中带来更大的性能优势。
在具有应该独立的元素组的页面上使用 contain
属性非常有用,因为它可以防止元素内部在边界框之外产生副作用。
语法
/* Keyword values */
contain: none;
contain: strict;
contain: content;
contain: size;
contain: inline-size;
contain: layout;
contain: style;
contain: paint;
/* Multiple keywords */
contain: size paint;
contain: size layout paint;
contain: inline-size layout;
/* Global values */
contain: inherit;
contain: initial;
contain: revert;
contain: revert-layer;
contain: unset;
值
contain
属性可以具有以下任何值
- 关键字
none
**或** - 一个或多个空格分隔的关键字
size
(或inline-size
)、layout
、style
和paint
,以任何顺序**或** - 简写值之一
strict
或content
这些关键字具有以下含义
none
-
元素按正常方式渲染,不应用任何包含。
strict
-
所有包含规则都应用于元素。这等效于
contain: size layout paint style
。 content
-
除
size
之外的所有包含规则都应用于元素。这等效于contain: layout paint style
。 size
-
大小包含应用于元素的内联和块方向。可以单独计算元素的大小,忽略子元素。此值不能与
inline-size
组合。 inline-size
-
内联大小包含应用于元素。可以单独计算元素的内联大小,忽略子元素。此值不能与
size
组合。 layout
-
元素的内部布局与页面其余部分隔离。这意味着元素外部的任何内容都不会影响其内部布局,反之亦然。
样式
-
对于可能影响不仅仅是元素及其后代的属性,其效果不会超出包含元素。计数器和引号的作用域限定为元素及其内容。
绘制
-
元素的后代不会显示在其边界之外。如果包含框位于屏幕外,则浏览器无需绘制其包含的元素——这些元素也必须位于屏幕外,因为它们完全包含在该框中。如果后代溢出包含元素的边界,则该后代将被裁剪到包含元素的边框盒。
正式定义
正式语法
示例
绘制限制
以下示例演示了如何使用contain: paint
来防止元素的后代在其边界之外绘制。
div {
width: 100px;
height: 100px;
background: red;
margin: 10px;
font-size: 20px;
}
<div style="contain: paint">
<p>This text will be clipped to the bounds of the box.</p>
</div>
<div>
<p>This text will not be clipped to the bounds of the box.</p>
</div>
布局限制
考虑以下示例,其中显示了应用和未应用布局限制的元素的行为
<div class="card" style="contain: layout;">
<h2>Card 1</h2>
<div class="fixed"><p>Fixed box 1</p></div>
<div class="float"><p>Float box 1</p></div>
</div>
<div class="card">
<h2>Card 2</h2>
<div class="fixed"><p>Fixed box 2</p></div>
<div class="float"><p>Float box 2</p></div>
</div>
<div class="card">
<h2>Card 3</h2>
<!-- ... -->
</div>
.card {
width: 70%;
height: 90px;
}
.fixed {
position: fixed;
right: 10px;
top: 10px;
background: coral;
}
.float {
float: left;
margin: 10px;
background: aquamarine;
}
第一张卡片应用了布局限制,其布局与页面其余部分隔离。我们可以将此卡片重复使用在页面上的其他位置,而无需担心其他元素的布局重新计算。如果浮动元素与卡片边界重叠,则页面其余部分的元素不受影响。当浏览器重新计算包含元素的子树时,只会重新计算该元素。包含元素外部的任何内容都不需要重新计算。此外,固定框使用卡片作为布局容器来定位自身。
第二张和第三张卡片没有限制。第二张卡片中固定框的布局上下文是根元素,因此固定框位于页面右上角。浮动元素与第二张卡片的边界重叠,导致第三张卡片出现意外的布局偏移,这在<h2>
元素的位置上可见。当重新计算发生时,它不限于容器。这会影响性能并干扰页面其余部分的布局。
样式限制
样式限制将计数器和引号的作用域限定到包含元素。对于 CSS 计数器,counter-increment
和counter-set
属性的作用域限定为元素,就像元素位于文档的根部一样。
限制和计数器
下面的示例介绍了应用样式限制时计数器的工作原理
<ul>
<li>Item A</li>
<li>Item B</li>
<li class="container">Item C</li>
<li>Item D</li>
<li>Item E</li>
</ul>
body {
counter-reset: list-items;
}
li::before {
counter-increment: list-items;
content: counter(list-items) ": ";
}
.container {
contain: style;
}
如果没有限制,则每个列表项的计数器将从 1 增加到 5。样式限制会导致counter-increment
属性的作用域限定为元素的子树,并且计数器将从 1 重新开始。
限制和引号
CSS 引号也受到类似的影响,即与引号相关的content
值的作用域限定为元素。
<!-- With style containment -->
<span class="open-quote">
outer
<span style="contain: style;">
<span class="open-quote"> inner </span>
</span>
</span>
<span class="close-quote"> close </span>
<br />
<!-- Without containment -->
<span class="open-quote">
outer
<span>
<span class="open-quote"> inner </span>
</span>
</span>
<span class="close-quote"> close </span>
body {
quotes: "[" "]" "‹" "›";
}
.open-quote:before {
content: open-quote;
}
.close-quote:after {
content: close-quote;
}
由于限制,第一个结束引号会忽略内部 span 并改为使用外部 span 的结束引号。
规范
规范 |
---|
CSS Containment 模块级别 2 # contain 属性 |
浏览器兼容性
BCD 表格仅在启用 JavaScript 的浏览器中加载。
另请参阅
- CSS 包含
- CSS 容器查询
- CSS
content-visibility
属性 - CSS
position
属性