contain

Baseline 已廣泛支援

此特性已經十分成熟,可在許多裝置和瀏覽器版本上使用。自 2022 年 3 月起,它已在各瀏覽器中可用。

contain CSS 屬性表示一個元素及其內容儘可能獨立於文件樹的其餘部分。包含功能可以將 DOM 的一個子部分隔離出來,透過將佈局、樣式、繪製、尺寸或它們的任意組合的計算限制在一個 DOM 子樹內而不是整個頁面,從而提供效能優勢。包含功能還可以用於限定 CSS 計數器和引用。

試一試

contain: none;
contain: size;
contain: layout;
contain: paint;
contain: strict;
<section class="default-example" id="default-example">
  <div class="card" id="example-element">
    <h2>Element with '<code>contain</code>'</h2>
    <p>
      The Goldfish is a species of domestic fish best known for its bright
      colors and patterns.
    </p>
    <div class="fixed"><p>Fixed right 4px</p></div>
  </div>
</section>
h2 {
  margin-top: 0;
}

#default-example {
  text-align: left;
  padding: 4px;
  font-size: 16px;
}

.card {
  text-align: left;
  border: 3px dotted;
  padding: 20px;
  margin: 10px;
  width: 85%;
  min-height: 150px;
}

.fixed {
  position: fixed;
  border: 3px dotted;
  right: 4px;
  padding: 4px;
  margin: 4px;
}

CSS 包含有四種類型:尺寸、佈局、樣式和繪製,它們設定在容器上。該屬性是五個標準值子集或兩個簡寫值之一的空格分隔列表。容器內包含屬性的更改不會傳播到包含元素之外,影響頁面的其餘部分。包含的主要好處是瀏覽器不必經常重新渲染 DOM 或頁面佈局,從而在渲染靜態頁面時帶來微小的效能提升,在更動態的應用程式中帶來更大的效能提升。

在頁面上,如果元素組應該相互獨立,使用 contain 屬性會很有用,因為它可以防止元素內部產生超出其邊框的副作用。

注意: 對此屬性使用 layoutpaintstrictcontent 值會建立

  1. 一個新的包含塊(對於 position 屬性為 absolutefixed 的後代元素)。
  2. 一個新的堆疊上下文
  3. 一個新的塊格式化上下文

語法

css
/* 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)、layoutstylepaint,任意順序
  • 簡寫值 strictcontent 之一

關鍵字具有以下含義

none

元素正常渲染,不應用任何包含。

strict

所有包含規則都應用於元素。這等同於 contain: size layout paint style

content

除了 size 之外的所有包含規則都應用於元素。這等同於 contain: layout paint style

size

尺寸包含應用於元素的行內和塊方向。元素的尺寸可以獨立計算,忽略子元素。此值不能與 inline-size 組合使用。

inline-size

行內尺寸包含應用於元素。元素的行內尺寸可以獨立計算,忽略子元素。此值不能與 size 組合使用。

layout

元素的內部佈局與頁面的其餘部分隔離。這意味著元素外部的任何內容都不會影響其內部佈局,反之亦然。

style

對於可以影響不僅僅是元素及其後代的屬性,其效果不會超出包含元素。計數器和引用被限定在元素及其內容之內。

paint

元素的後代不會顯示在其邊界之外。如果包含框在螢幕外,瀏覽器無需繪製其包含的元素——這些元素也必須在螢幕外,因為它們完全被該框包含。如果後代溢位包含元素的邊界,那麼該後代將被剪裁到包含元素的邊框。

正式定義

初始值none
應用於所有元素
繼承性
計算值同指定值
動畫型別不可動畫化

正式語法

contain = 
none |
strict |
content |
[ [ size | inline-size ] || layout || style || paint ] |
view-transition

示例

繪製包含

以下示例展示瞭如何使用 contain: paint 來防止元素的後代在其邊界之外繪製。

css
div {
  width: 100px;
  height: 100px;
  background: red;
  margin: 10px;
  font-size: 20px;
}

.contain-paint {
  contain: paint;
}
html
<div class="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>

佈局包含

請看下面的示例,它展示了應用和未應用佈局包含時元素的行為

html
<div class="card 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>
css
.card {
  width: 70%;
  height: 90px;
}

.fixed {
  position: fixed;
  right: 10px;
  top: 10px;
  background: coral;
}

.float {
  float: left;
  margin: 10px;
  background: aquamarine;
}

.contain-layout {
  contain: layout;
}

第一張卡片應用了佈局包含,其佈局與頁面的其餘部分隔離。我們可以在頁面上的其他位置重用這張卡片,而無需擔心其他元素的佈局重新計算。如果浮動元素與卡片邊界重疊,頁面其餘部分的元素不受影響。當瀏覽器重新計算包含元素的子樹時,只重新計算該元素。包含元素外部的任何內容都不需要重新計算。此外,固定框使用卡片作為佈局容器來定位自身。

第二張和第三張卡片沒有包含。第二張卡片中固定框的佈局上下文是根元素,因此固定框位於頁面的右上角。一個浮動元素與第二張卡片的邊界重疊,導致第三張卡片出現意外的佈局偏移,這在 <h2> 元素的定位中可見。當重新計算發生時,它不限於一個容器。這會影響效能並干擾頁面的其餘佈局。

樣式包含

樣式包含將計數器引用限定在包含元素內。對於 CSS 計數器,counter-incrementcounter-set 屬性被限定在該元素上,就像該元素位於文件的根部一樣。

包含和計數器

下面的示例展示了應用樣式包含時計數器的工作方式

html
<ul>
  <li>Item A</li>
  <li>Item B</li>
  <li class="container">Item C</li>
  <li>Item D</li>
  <li>Item E</li>
</ul>
css
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 值被限定在元素內

html
<!-- With style containment -->
<span class="open-quote">
  outer
  <span class="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>
css
body {
  quotes: "[" "]" "‹" "›";
}
.open-quote::before {
  content: open-quote;
}

.close-quote::after {
  content: close-quote;
}

.contain-style {
  contain: style;
}

由於包含,第一個結束引用忽略了內部 span,而是使用了外部 span 的結束引用

規範

規範
CSS 包含模組第 2 級
# contain-property

瀏覽器相容性

另見