Featured image of post CSSスコープ付きスタイル:@scopeとカプセル化戦略 Featured image of post CSSスコープ付きスタイル:@scopeとカプセル化戦略

CSSスコープ付きスタイル:@scopeとカプセル化戦略

@scopeアットルール、Shadow DOM、CSS Modules、BEMを比較し、モダンウェブアプリケーションにおけるCSSスコーピングとカプセル化戦略を解説。

CSSのスタイルはデフォルトでグローバルにカスケードするため、あるコンポーネントのセレクタが意図せず別のコンポーネントに影響を与えることがあります。開発者は長年にわたり、命名規則、ビルド時ツール、DOM分離などでこの問題に対処してきました。そして今、CSS @scopeアットルールが登場し、近接性ベースのカスケード制御という新しい選択肢を提供しています。

@scopeアットルール

CSS Scoping Module Level 1で導入された@scopeは、スタイルを指定したルート要素とその子孫に制限します。命名規則とは異なり、ブラウザによって強制される点が決定的に異なります。

@scope (.card) {
  .title { font-size: 1.25rem; font-weight: 600; }
  .body { padding: 1rem; }
}

最大の革新は**スコープ近接性(scope proximity)**です。要素に近いスコープで定義されたスタイルは、詳細度に関係なく優先されます。スコープリミットを使用すると、スタイルが適用されるサブツリーをさらに制限できます。

@scope (.card) to (.card__footer) {
  .link { color: blue; }
}

これにより、カードの中に別のカードがある場合でも、内側のカードは外側のスコープスタイルの影響を受けません。@scopeはChrome 118+、Safari 17.4+、Firefox 128+でサポートされています。


Shadow DOMとCSS Modules

Shadow DOMは最も強力なカプセル化を提供します。スタイル、マークアップ、動作がシャドウルート内で完全に分離されます。

class MyCard extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: "open" });
    shadow.innerHTML = `
      <style>.title { font-size: 1.25rem; }</style>
      <div class="title">Hello</div>
    `;
  }
}
customElements.define("my-card", MyCard);

CSS Modulesはビルド時にローカルスコープのクラス名を生成し、ランタイムコストゼロで衝突を防止します。

/* card.module.css */
.title { font-size: 1.25rem; }
.body { padding: 1rem; }
import styles from "./card.module.css";
function Card() {
  return <div className={styles.card}>
    <h2 className={styles.title}>Title</h2>
  </div>;
}

ビルドツールが.title.card_title_3kl4sのような一意な名前に変換します。TypeScript統合やcomposesによるクラス合成も可能ですが、要素セレクタはスコープされないという制限があります。


BEMと実践的戦略

BEM(Block Element Modifier)は.block__element--modifierという命名規則で衝突を防止します。ツールは不要ですが、真のカプセル化はなく、大規模コードベースではカスケード漏洩が発生します。

戦略カプセル化ランタイムコストビルド手順最適な用途
@scopeカスケードレベルなし不要モダンCSSのコンポーネント
CSS Modulesクラスレベルなし必要フレームワークベースのSPA
Shadow DOM完全なDOM分離インスタンスごと不要分散ウィジェット、デザインシステム
BEM慣習のみなし不要ビルド手順のないプロジェクト

最も実践的なのはハイブリッドアプローチです。コンポーネントファイルにはCSS Modulesを使用し、その中で@scopeでカスケードを管理します。分散ウィジェットライブラリにはShadow DOM、グローバルユーティリティにはBEMを採用します。@scopeはCSSにブラウザ強制のスコープをもたらすパラダイムシフトであり、日常的なコンポーネントスタイリングのカスケード管理を劇的にシンプルにします。