CSS 封じ込め
CSS 封じ込め (CSS Containment) 仕様の目的は、ウェブページの表示性能を向上させるために、開発者がページの任意のサブツリーをページのそれ以外の部分から独立させることができるようにすることです。もしページの一部が独立していることをブラウザーが知っていれば、レンダリングを最適化し、表示性能を向上させることができます。この仕様では、単一の CSS プロパティ
contain
を定義しています。この文書では、その仕様の基本的な目的を説明しています。
基本的な例
多くのウェブページは、互いに独立したいくつかのセクションで構成されています。例えば、記事の見出しと内容の一覧が、以下のようなマークアップで存在していたとします。
html
<h1>私のブログ</h1>
<article>
<h2>良い記事の見出し</h2>
<p>内容はこちら。</p>
</article>
<article>
<h2>他の記事の他の見出し</h2>
<p>さらなる内容はこちら。</p>
</article>
それぞれの記事には CSS で contain
プロパティに content
という値が設定されています。
css
article {
contain: content;
}
それぞれの記事は、ページ上の他の記事と独立していますので、 contain: content
がこのことをブラウザーに伝えるために指定されています。それでブラウザーはこの情報を使用して、どのようにして内容を描画するかを決定します。例えば、表示される領域の外側にある記事は描画しない場合があります。
それぞれの <article>
の contain
プロパティを content
の値に設定すると、新しい要素が挿入されたとき、ブラウザーはそれを含む要素のサブツリー以外の領域を再レイアウトまたは再描画する必要がないことを判断します。ただし、もし <article>
が(height: auto
の場合のように)そのコンテンツによってサイズが変わるようスタイル付けされている場合は、ブラウザーがサイズの変化に対応する必要があるかもしれません。
各記事が独立していることを contain
プロパティで伝えています。
content
の値は contain: layout paint
の短縮形です。これはブラウザーに、要素の内部レイアウトがページの他の部分と完全に分離しており、要素に関するすべてがその境界の内側で描画されることを伝えます。視覚的にはみ出るようなものはありません。
この情報は、ページを作成するウェブ開発者にとっては、通常知っていることであり、実際、非常に明白なことです。しかし、ブラウザーはその意図を推測することができず、記事が完全に自己完結していると仮定することはできません。したがって、このプロパティは、この事実をブラウザーに説明し、その知識に基づいて表示性能を最適化することを可能にする良い方法を提供します。
主要概念と用語
この仕様では contain
というプロパティのみを定義しています。このプロパティの値には、封じ込めの種類を指定します。
レイアウトの封じ込め
css
article {
contain: layout;
}
レイアウトは通常、文書全体がスコープになっています。つまり、文書全体の中から 1 つの要素を動かしただけで、すべてが動かされたかのように扱われます。 contain: layout
を使うことで、ブラウザーに対して必要な要素のみを伝えることができます。このプロパティを指定した要素の中の全てがその要素によって封じ込められ、その他の要素には影響せず、そしてその包含ブロックは独立した整形コンテキストになります。
加えて、以下の点に注意する必要があります。
float
レイアウトはこのプロパティとは独立して作用します。- レイアウトの封じ込めの境界でマージンが相殺されることはありません。
- レイアウトのコンテナーは
absolute
/fixed
による位置指定の子要素の包含ブロックになります。 - この包含ボックスは重ね合わせコンテキストを作ります。従って
z-index
を使用することができます。
ペイントの封じ込め
css
article {
contain: paint;
}
ペイントの封じ込めは、基本的に、ボックスを主要ボックスのパディングエッジでクリッピングします。視覚的なはみ出しは許されません。 paint
封じ込めにも layout
封じ込めと同じことが当てはまります(上記を参照)。
もうひとつの利点は、包含ボックスが画面外にある場合、ブラウザーはその内包する要素を描く必要がないことです — これらはそのボックスによって完全に内包されているので、画面外にあるに違いないからです。
サイズの封じ込め
css
article {
contain: size;
}
サイズの封じ込めを単独で使用した場合、表示性能の最適化はあまり期待できません。しかし、要素の子のサイズが要素自体のサイズに影響しないことを意味し、そのサイズは子がないものとして計算されます。
もし、contain: size
をオンにした場合は、これを適用した要素のサイズも指定する必要があります。もし、手動でサイズを指定しない場合は、ほとんどの場合、サイズがゼロになってしまいます。
スタイルの封じ込め
css
article {
contain: style;
}
名前に反して、スタイルの封じ込めは、 Shadow DOM で得られるようにスタイルを封じ込めるわけではありません。主な使用例は、 CSS カウンター がある要素で変更され、それがツリーの残りの部分に影響する可能性がある状況を防ぐことです。
contain: style
を使用すると、counter-increment
と counter-set
プロパティがそのサブツリーにのみ限定された新しいカウンターを作成することを保証します。
メモ: style
の封じ込め仕様上「リスクがあり」、どこでも対応しているとは限りません (現在 Firefox は対応していません)。
特殊な値
封じ込めの特殊な値が 2 つあります。
content
strict
1 つ目は上記の例で既に見ました。 contain: content
を使用すると、 layout
と paint
の封じ込めが有効になります。仕様書では、この値を「広く適用してもそれなりに安全である」と説明しています。この値は size
の封じ込めを適用しないので、子要素のサイズに依存して、ボックスのサイズがゼロになる危険性はありません。
できるだけ多くの封じ込めを得るには、 contain: strict
を使用します。これは contain: size layout paint
と同じ動作をしますが、おそらく以下のようにすると、 style
に対応しているブラウザーでは封じ込めを追加することができます。
css
contain: strict;
contain: strict style;
リファレンス
CSS プロパティ
仕様書
Specification |
---|
CSS Containment Module Level 2 # contain-property |
CSS Containment Module Level 2 # content-visibility |
ブラウザーの互換性
css.properties.contain
BCD tables only load in the browser
css.properties.content-visibility
BCD tables only load in the browser
css.properties.contain
BCD tables only load in the browser
css.properties.content-visibility
BCD tables only load in the browser