CSSContainプロパティを使用してブラウザを最適化するのを支援する

公開: 2022-03-10
簡単な要約↬CSScontainプロパティcontain使用すると、ブラウザにレイアウトを説明できるため、パフォーマンスを最適化できます。 ただし、レイアウトに関してはいくつかの副作用があります。

この記事では、W3C勧告になったばかりのCSS仕様を紹介します。 CSS Containment Specification contain 、単一のプロパティ、containsを定義し、レイアウトのどの部分が独立していて、レイアウトの他の部分が変更された場合に再計算する必要がないかをブラウザーに説明するのに役立ちます。

このプロパティはパフォーマンスの最適化のために存在しますが、ページのレイアウトにも影響を与える可能性があります。 したがって、この記事では、恩恵を受けることができるさまざまなタイプのcontainだけでなく、サイトの要素に包含を適用する場合に注意する必要があることについても説明します。

レイアウト再計算の問題

JavaScriptを使用して要素を読み込んだ後、要素を動的に追加または変更しない単純なWebページを構築している場合は、CSSContainmentが解決する問題について心配する必要はありません。 ページが読み込まれるため、ブラウザはレイアウトを1回だけ計算する必要があります。

封じ込めが役立つのは、ユーザーがページをリロードせずにページに要素を追加したい場合です。 私の例では、イベントの大きなリストを作成しました。 ボタンをクリックすると、最初のイベントが変更され、浮動要素が追加され、テキストが変更されます。

最初のアイテムのコンテンツの一部を変更するためのボタンが付いたアイテムのリスト
(CodePenの最初の例を参照してください)

ボックスの内容が変更された場合、ブラウザは要素のいずれかが変更された可能性があることを考慮する必要があります。 よくあることなので、ブラウザは一般的にこれをうまく処理できます。 とは言うものの、開発者として、各コンポーネントが独立しているかどうか、そして1つのコンポーネントへの変更が他のコンポーネントに影響を与えないかどうかを知っているので、CSSを介してブラウザーにこれを知らせることができれば便利です。 これがcontainationとcontainプロパティが提供するものです。

ジャンプした後もっと! 以下を読み続けてください↓

封じ込めはどのように役立ちますか?

HTMLドキュメントは、DevToolsを使用して要素を検査するときに表示されるツリー構造です。 上記の例では、JavaScriptを使用して変更したい項目を1つ特定し、内部にいくつかの変更を加えています。 (これは、そのリストアイテムのサブツリー内のものだけを変更していることを意味します。)

注目アイテムのリストアイテムが展開されたDevToolsは、内部の要素を表示します
DevToolsでリストアイテムを検査する

containsプロパティを要素contain適用すると、変更はその要素のサブツリーにスコープされることをブラウザーに通知します。これにより、ブラウザーは可能な最適化を実行できます。その要素以外は変更されないため、安全です。 正確には、特定のブラウザが実行する可能性があるのはエンジンです。 CSSプロパティは、このレイアウトの開発者および専門家として、単にそれを知らせる機会を提供します。

多くの場合、先に進んでcontainプロパティの使用を開始しても安全ですが、異なる値には、サイトの要素にプロパティを追加する前に理解する価値のある潜在的な副作用がいくつかあります。

封じ込めの使用

containsプロパティcontain 、3つの異なるタイプの包含を設定できます。

  • layout
  • paint
  • size

レベル2仕様にはstyle値があります。 レベル1から削除されたため、推奨事項には表示されず、Firefoxには実装されていません。

レイアウト

レイアウトの封じ込めは最大のメリットをもたらします。 レイアウトの包含をオンにするには、次のスニペットを使用します。

 .item { contain: layout; }

レイアウトの包含を有効にすると、ブラウザは、要素の外側では内部レイアウトに影響を与えることができず、要素の内側からは要素の外側のレイアウトについて何も変更できないことを認識します。 これは、このシナリオで可能な最適化を行うことができることを意味します。

レイアウトの包含が有効になっている場合、さらにいくつかのことが起こります。 これらはすべて、このボックスとコンテンツがツリーの他の部分から独立していることを保証するものです。

ボックスは、独立したフォーマットコンテキストを確立します。 これにより、ボックスの内容がボックス内にとどまることが保証されます。特に、フロートが含まれ、マージンがボックス全体で崩壊することはありません。 これは、私の記事「CSSレイアウトとブロックフォーマットコンテキストについて」で説明したように、 display: flow-rootを使用するときにオンにする動作と同じです。 フロートが箱から突き出て、次のテキストがフロートの周りを流れる可能性がある場合、それは要素フロートの外側にあるもののレイアウトを変更している状況であり、封じ込めの候補としては不十分です。

収容ボックスは、絶対位置または固定位置の子孫の収容ブロックとして機能します。 これは、適用したボックスのposition: relative contain: layoutを使用したかのように機能することを意味します。

ボックスは、スタッキングコンテキストも作成します。 したがって、 z-indexはこの要素で機能し、その子はこの新しいコンテキストに基づいてスタックされます。

今回はcontain: layoutを使用した例を見ると、float要素が導入されたときに、ボックスの下部を突き出していないことがわかります。 これは、floatを含む、動作中の新しいブロックフォーマットコンテキストです。

アイテムのリスト、浮動要素は親ボックスの境界内に含まれています
containsの使用:floatが含まれるレイアウト(CodePenのレイアウト包含の例を参照)

ペイント

ペイントの封じ込めをオンにするには、次を使用します。

 .item { contain: paint; }

ペイントの包含を有効にすると、レイアウトの包含で見られるのと同じ副作用が発生します。包含ボックスが独立したフォーマットコンテキストになり、配置された要素の包含ブロックになり、スタッキングコンテキストが確立されます。

ペイントの封じ込めが行うことは、包含ブロック内の要素がそのボックスの境界の外側に表示されないことをブラウザーに示すことです。 コンテンツは基本的にボックスにクリップされます。

これは簡単な例でわかります。 カードに高さを付けても、フロートが流れ出ているため、フロートしたアイテムは箱の底から突き出ています。

収納ボックスの底を突き出す浮き箱
フロートはリストアイテムに含まれていません

ペイントの封じ込めをオンにすると、フロートされたアイテムがボックスのサイズにクリップされます。 contain: paintが適用されます。

箱から逃げるところが切り取られた、浮いた箱が入った箱
ボックスの内容はボックスの高さにクリップされます(CodePenのペイント例を参照)

サイズ

サイズの封じ込めは、それがどのように機能するかを完全に認識していない場合に問題を引き起こす可能性が最も高い値です。 サイズの封じ込めを適用するには、次を使用します。

 .item { contain: size; }

サイズの封じ込めを使用する場合は、ボックスのサイズがわかっていて、変更されないことをブラウザに通知します。 これは、ブロックディメンションで自動サイズ設定されたボックスがある場合、コンテンツにサイズがないかのように扱われるため、ボックスはコンテンツがないかのように折りたたまれることを意味します。

以下の例では、 liに高さを指定していません。 それらはまたcontain: size 。 すべてのアイテムがコンテンツがまったくないかのように折りたたまれており、非常に独特な外観のリストになっていることがわかります。

最初のアイテムのコンテンツの一部を変更するためのボタンが付いたアイテムのリスト
(CodePenのサイズの例を参照してください)

ボックスに高さを指定すると、 contain: sizeが使用されるときに高さが尊重されます。 サイズの封じ込めだけでは、新しいフォーマットコンテキストは作成されないため、レイアウトやペイントの封じ込めのようにフロートやマージンは含まれません。 単独で使用する可能性は低くなります。 代わりに、可能な限り多くの封じ込めを取得できるように、 containの他の値と一緒に適用する可能性があります。

省略形の値

ほとんどの場合、2つの省略値のいずれかを使用して、封じ込めを最大限に活用できます。 レイアウトとペイントの封じ込めをオンにするには、 contain: content;を使用します。 、およびすべての可能な包含をオンにするには(サイズがないアイテムは折りたたまれることに注意してください)、 contain: strictを使用します。

仕様によると:

contain: contentは広く適用するのに合理的に「安全」です。 その影響は実際にはかなり軽微であり、ほとんどのコンテンツはその制限に違反することはありません。 ただし、サイズの包含を適用しないため、要素はそのコンテンツのサイズに応答できます。これにより、レイアウトの無効化がツリーのさらに上に浸透する可能性があります。 可能な限り多くの封じ込めを取得するために、 contain: strictに使用します。」

したがって、事前にアイテムのサイズがわからず、フロートとマージンが含まれることを理解している場合は、 contain: contentを使用してください。 封じ込めの他の副作用に満足していることに加えて、アイテムのサイズを知っている場合は、 contain: strictを使用してください。 残りはブラウザに任されています、あなたはあなたのレイアウトがどのように機能するかを説明することによってあなたのビットをしました。

今すぐ封じ込めを使用できますか?

CSS Containment仕様は、W3C勧告になりました。これは、 Web標準と呼ばれることもあります。 仕様をこの段階に到達させるには、FirefoxとChromeの両方で確認できる機能の2つの実装が必要でした。

Can IUseの封じ込めに関するブラウザサポート情報のスクリーンショット
封じ込めのためのブラウザのサポート(出典:使用できますか)

このプロパティはユーザーに対して透過的であるため、このプロパティをサポートしていないブラウザに多数の訪問者がいる場合でも、どのサイトにも完全に安全に追加できます。 ブラウザが封じ込めをサポートしていない場合、訪問者は通常得られるエクスペリエンスを得ることができ、ブラウザをサポートしている訪問者はパフォーマンスが向上します。

これは、コンポーネントまたはパターンライブラリで作成するコンポーネントに追加するのに最適なことです。この方法で作業している場合、各コンポーネントは、他の要素に影響を与えない独立したものになるように設計されている可能性があります。ページ、 contain: contentを便利な追加にします。

したがって、ロード後にDOMにコンテンツを追加しているページがある場合は、試してみることをお勧めします。興味深い結果が得られた場合は、コメントでお知らせください。

関連リソース

次のリソースでは、封じ込めの実装と潜在的なパフォーマンス上の利点について詳しく説明します。

  • 「CSSプロパティをcontainMDNWebドキュメント
  • 「Chrome52でのCSS封じ込め」、 Google Developers
  • 「CSS封じ込めモジュールレベル1」、 W3C勧告
  • 「CSS封じ込めの概要」、 Manuel Rego Casasnovas