フロントエンド - CSS・スタイリング

CSS Containment しーえすえす こんてんめんと

contain プロパティレンダリング最適化レイアウト境界content-visibilityパフォーマンスペイント最適化
CSS Containmentについて教えて

簡単に言うとこんな感じ!

「この部品の変化は、外には影響しないよ!」とブラウザに教える仕組みだよ。Webページって、一箇所変わると全体を再計算しちゃうんだけど、CSS Containmentを使うと「ここだけ」で計算を止められるから、ページがサクサク動くようになるんだ!


CSS Containmentとは

CSS Containment(CSSコンテインメント)とは、ある要素のレンダリング(描画処理)の影響範囲を、その要素の内側に閉じ込めるための仕組みです。CSSの contain プロパティで指定し、「この要素の内側で何が変わっても、外側の要素には影響しない」とブラウザに明示的に伝えることができます。

ブラウザは、HTML上のある要素が変化すると、場合によってはページ全体のレイアウト計算や描画処理をやり直します。これを**リフロー(レイアウトの再計算)リペイント(再描画)**と呼びます。大規模なWebアプリでは、このコストが積み重なり表示が遅くなる原因になります。CSS Containmentを使うと、ブラウザが「この要素の外まで計算しなくていい」と判断できるため、パフォーマンスを大幅に改善できます。

2019年にW3Cの勧告候補となり、現在はChrome・Firefox・Safariなど主要ブラウザで広くサポートされています。大量のカードUI・無限スクロール・ダッシュボードのような「繰り返し登場するコンポーネント」を持つページで特に効果を発揮します。


CSS Containmentの仕組みと種類

contain プロパティには複数の値があり、どの範囲の処理を「封じ込める」かを選べます。

英語の意味効果
sizeサイズ子要素のサイズが親のサイズに影響しない
layoutレイアウト内部のレイアウト変化が外部に伝わらない
paint描画要素の外に描画内容がはみ出さない
styleスタイルカウンターなど一部スタイルの影響を封じ込める
contentコンテンツlayout + paint + style の組み合わせ
strict厳格size + layout + paint + style すべて

実務でよく使うのは contain: contentcontain: layout です。

/* カードコンポーネントの例 */
.card {
  contain: content; /* layout + paint + style をまとめて指定 */
}

/* サイドバーなど独立したブロックの例 */
.sidebar {
  contain: layout paint;
}

覚え方:「封印(contain)すると、外には漏れない」

contain は「封じ込める・格納する」という英語の意味。「魔法陣の中の出来事は外に影響しない」とイメージすると覚えやすいです。layout を指定すれば内部のDOMが大きく変わっても外側は再計算されず、paint を指定すれば内部の再描画が外に波及しません。

content-visibility との組み合わせ

CSS Containmentを発展させた content-visibility プロパティ(CSS Containment Level 2 で追加)と組み合わせると、さらに強力な最適化が可能です。

/* 画面外の要素のレンダリングをスキップする */
.article-section {
  content-visibility: auto;
  contain-intrinsic-size: 0 500px; /* スキップ時の仮サイズ */
}

content-visibility: auto は、画面に見えていない要素のレンダリングを丸ごとスキップします。長いページを一気に高速化できる、現時点で最も効果的な手法の一つです。


歴史と背景

  • 2014年頃 — Webアプリの複雑化・SPA(シングルページアプリ)の普及により、DOMの動的変更によるパフォーマンス劣化が深刻な課題に
  • 2016年 — GoogleのエンジニアがW3Cに CSS Containment の仕様草案を提出。「ブラウザに範囲を教えることで最適化できるはず」という発想が起点
  • 2017年 — Chrome 52+ で contain プロパティの試験的サポートが始まる
  • 2019年CSS Containment Level 1 がW3C勧告候補(CR)に。主要ブラウザが対応を進める
  • 2020年content-visibility が Chrome 85 で実装。Googleのブログで「ページロードを最大7倍高速化」と報告され注目が集まる
  • 2022年 — CSS Containment Level 2(content-visibility を含む)がW3C勧告候補に。Firefox・Safariも対応完了し、実用的なフェーズへ
  • 現在React・Vue・Webコンポーネントなどコンポーネント指向開発との親和性の高さから、パフォーマンスチューニングの定番手法として定着

ブラウザのレンダリングパイプラインとの関係

CSS Containmentがなぜ効くのかを理解するには、ブラウザがページを表示するまでの流れ(クリティカルレンダリングパス)を把握すると役立ちます。

HTML解析 → DOMツリー構築
CSS解析  → CSSOMツリー構築

       レンダーツリー構築

    [Layout] サイズ・位置の計算   ← contain: layout / size が効く

    [Paint]  ピクセル描画          ← contain: paint が効く

    [Composite] レイヤー合成

通常、DOMの一部が変わると Layout → Paint → Composite の処理が上流から再実行されます。CSS Containmentを指定すると、その要素の境界でパイプラインを打ち切り、外側の要素に処理が伝播しなくなります。

containmentなし ページ全体のLayout計算 ページ全体のPaint処理 カード内の変化 ↓ 全体に波及 ページ全体を再計算 ⚠ コストが高い contain: content あり ページ外部は再計算しない 封じ込め領域(card要素) 内部の変化はここで完結 🔒 境界の外には波及しない 必要な部分だけ再計算 ✅ コストを最小化

実務での使いどころ

シーン推奨設定理由
カードUIの一覧contain: content各カードが独立してレンダリングされる
無限スクロールリストcontent-visibility: auto画面外のレンダリングをスキップ
モーダル・ドロップダウンcontain: layout paint開閉時の再計算を封じ込める
ウィジェット・サイドバーcontain: layoutメインコンテンツへの影響を防ぐ
アニメーション要素contain: layoutアニメ中の再計算コストを局所化

関連する規格・RFC

規格内容
CSS Containment Level 1contain プロパティの基本仕様(W3C勧告)
CSS Containment Level 2content-visibility などを追加した拡張仕様(W3C勧告候補)
CSS Containment Level 3CSS コンテナークエリーとの統合を含む最新仕様(W3C作業草案)

関連用語