1. ホーム
  2. Web制作
  3. CSS

[CSSチュートリアル】CSSの新機能には、ページの再描画や並び替えの問題をコントロールする機能が含まれています。

2022-01-01 04:18:33

新しいCSSプロパティcontainを紹介する前に、読者の皆さんにページの再描画と並べ替えがどういうものかをすでに知っておいてもらう必要があります。

これまでにも何度も説明されていることですが、CSSアニメーションのパフォーマンスを向上させるための正しい姿勢[1]を確認してください。

よし、この記事の本題に入ろう。

コンテナ なぜ?

contain 属性は、特定の DOM 要素とその子要素を指定して、DOM ツリー構造全体から独立できるようにするためのものです。その目的は、ページ全体を毎回対象とするのではなく、一部の要素だけを再描画したり並べ替えたりする機能をブラウザに与えることです。

contain プロパティは、ある要素とそのコンテンツが、ドキュメントツリーの残りの部分から可能な限り独立していることを示すためのものです。これにより、ブラウザは、ページ全体ではなく、DOM の限定された領域に対して、レイアウト、スタイル、ペイント、サイズ、またはそれらの組み合わせを再計算することができます。

その構文を見てみましょう。

{ 
  /* No layout containment. */ 
  contain: none; 
  /* Turn on containment for layout, style, paint, and size. */ 
  contain: strict; 
  /* Turn on containment for layout, style, and paint. */ contain: content; /* Turn on containment for layout, style, paint, and size. 
  contain: content; 
  /* Turn on size containment for an element. */ contain: size; /* Turn on containment for layout, style, paint, and size. 
  contain: size; 
  /* Turn on layout containment for an element. */ contain: layout; /* Turn on size containment for an element. 
  contain: layout; 
  /* Turn on style containment for an element. */ contain: style; /* Turn on style containment for an element. 
  contain: style; 
  /* Turn on paint containment for an element. */ contain: paint; /* Turn on paint containment for an element. 
  contain: paint; 
} 

noneの他に6つの値がありますので、一つずつ見ていきましょう。

内容:サイズ

contain: size: contain: size が設定された要素のレンダリングは、その子要素の内容に影響されません。

この値は、その要素のサイズの抑制をオンにします。これにより、その子孫を調べる必要がなく、包含するボックスを確実にレイアウトすることができます。

最初はこの定義に戸惑いましたし、読んだだけでは意味を正確に理解するのは難しいです。少し練習が必要でしょう。

次のような単純な構造があるとします。

<div class="container"> 
    
</div> 

.container { 
    width: 300px; 
    padding: 10px; 
    border: 1px solid red; 
} 
 
p { 
    border: 1px solid #333; 
    margin: 5px; 
    font-size: 14px; 
} 

そして、jQueryの力を借りて、コンテナをクリックするごとに、<p>Coco</p>の構造を追加しています。

$('.container').on('click', e => { 
    $('.container').append('<p>Coco</p>') 
}) 

そうすると、次のような結果になる。

見ての通り、要素が大きくなるにつれてコンテナ.containerの高さが増していますが、これは正常なことです。

この時点で、contain: size を container .container に追加すると、上で述べたように、contain: size を持つ要素のレンダリングは、その子のコンテンツに影響されないということがわかります。

.container { 
    width: 300px; 
    padding: 10px; 
    border: 1px solid red; 
+ contain: size 
} 

そして、どうなるか見てみましょう。

通常、親要素の高さは子要素の増加によって支えられていますが、子要素の変更が親要素のスタイルレイアウトに影響を与えなくなったことで、contain: sizeがその役割を果たすようになりました。

コンテナ:スタイル

次に、contain: style、contain: layout、contain: paintについて、contain: styleから説明します。

この記事を書いている時点では、contain: styleは今のところ削除されています。

CSS Containment Module Level 1[2]。この仕様から、危険な "style containment" 機能を削除し、レベル 2 に移動しました。

まあ、公式には「何らかのリスクがあるため一時的に削除された」ということで、おそらく第2版の仕様で再定義されるでしょうから、このプロパティはひとまず置いておくことになりますね。

contain: ペイント

contain: paint: つまり、この要素の子要素はこの要素の境界の外には表示されないことをユーザエージェントに伝えます。そのため、この要素が画面上にない場合、または不可視に設定されている場合、その子孫も不可視で表示されないことが保証されます。

この値は、要素のペイントコンテインメントをオンにします。これにより、包含ボックスの子孫はその枠外に表示されないことが保証されます。包含ボックスの子孫はその枠外に表示されないことが保証されるので、要素が画面外やその他の方法で見えない場合、その子孫は見えないことが保証されます。

これは少し理解しやすいので、最初の特徴を見てみましょう。

contain: paint を持つ要素の子要素は、この要素の境界の外には表示されません contain: paint を持つ要素の子要素は、この要素の境界の外には表示されません。

この機能は overflow: hidden と多少似ていますが、子要素のコンテンツが要素の境界を超えないのでレンダリングする必要がないことをユーザーエージェントに明示的に通知する点で、overflow: hidden と同じです。

簡単な例として、次のような要素構成があるとする。

<div class="container"> 
    <p>Coco</p> 
</div>

.container { 
    contain: paint; 
    border: 1px solid red; 
} 
 
p{ 
    left: -100px; 
} 

contain: paint が設定されている場合とされていない場合で、どうなるか見てみましょう。

CodePenデモ -- contain: paint デモ[3]。

画面外にcontain: paintが設定されている要素は、レンダリングもペイントもされない

contain: paint を使用すると、ユーザーエージェントは、要素が画面外にある場合はレンダリングを無視し、他のコンテンツをより迅速にレンダリングできるようになります。

コンテナ:レイアウト

contain: レイアウト。contain: layout が設定された要素はレイアウト制限を設定し、ユーザーエージェントに、要素の内部でスタイルを変更しても要素の外部でスタイルが変更されないこと、またその逆も然りであることを知らせます。

この値は、要素のレイアウト封じ込めをオンにします。これは、含むボックスがレイアウトの目的のために完全に不透明であることを保証します; 外部の何もその内部レイアウトに影響を与えることができません、そして逆も同様です。

contain: layout を有効にすると、ドキュメント全体を再レンダリングするのではなく、フレームごとにレンダリングする必要のある要素の数をほんの少しに減らすことができる可能性があります。これにより、ブラウザの不要な作業を大幅に減らし、パフォーマンスを大幅に改善することができます。

contain: layout を使用すると、開発者は、要素の子孫へのいかなる変更も、外部要素のレイアウトに影響を与えないように指定することができ、その逆も同様です。

その結果、ブラウザは内部要素の位置のみを計算し(それが変更された場合)、DOMの残りの部分は変更されません。その結果、フレームレンダリングパイプラインでのレイアウト処理が高速化されることを意味します。

問題点

記述はいいのですが、実際のデモテスト(2021/04/27時点のChrome 90.0.4430.85)では、contain:layoutだけでは上記のようにきれいに検証されないのです。

指定した要素にcontain: layoutを設定すると、変更した要素の子孫を変更しても外部要素のレイアウトに影響し、赤枠をクリックすると、コンテナに挿入された<p>Coco<p>要素が追加されます。

簡単なコードは次のようになります。

<div class="container"> 
    <p>Coco</p> 
    ... 
</div> 
<div class="g-test"></div> 

html, 
body { 
    width: 100%; 
    height: 100%; 
    display: flex; 
    justify-content: center; 
    align-items: center; 
    flex-direction: column; 
    gap: 10px; 
} 
 
.container { 
    width: 150px; 
    padding: 10px; 
    contain: layout; 
    border: 1px solid red; 
} 
 
.g-test { 
    width: 150px; 
    height: 150px; 
    border: 1px solid green; 
} 

CodePenデモ -- contain: レイアウトデモ[4]。

使用可能 -- CSS Contain

2021-04-27現在、Can i UseでのCSS Containの互換性が使用可能です。

参考文献

CSS Containment Module Level 1 [5]。

CSSコンテナメント[6]。

Chrome 52のCSSコンテインメント[7]。

参考文献

[1] CSSアニメーションのパフォーマンスを向上させるための正しい姿勢。

https://github.com/chokcoco/iCSS/issues/11

[2] CSS Containment Module Level 1。

https://www.w3.org/TR/css-contain-1/

[3] CodePenデモ -- contain: paint デモ。

https://codepen.io/Chokcoco/pen/KKwmgmN

[4] CodePenデモ -- contain: レイアウトデモ:

https://codepen.io/Chokcoco/pen/rNjRELL

[5] CSS Containment Module Level 1。

https://www.w3.org/TR/css-contain-1/

[6】CSSの封じ込め

https://justmarkup.com/articles/2016-04-05-css-containment/

[7】Chrome 52のCSSコンテインメント。

https://developers.google.com/web/updates/2016/06/css-containment

[8】Github -- iCSS:

https://github.com/chokcoco/iCSS

新しいCSS機能に関するこの記事は、ページの再描画と並べ替えの制御を含むこのに導入され、より関連するページ内容の再描画と並べ替え上のCSS制御は、スクリプトハウスの過去の記事を検索するか、次の関連記事を閲覧を続ける、私はあなたが将来よりスクリプトハウスをサポートしてくれることを願っています!。