HOME / BLOG
BLOG

CSS @scopeの使い方【コンポーネント単位でスタイルを閉じる】

デフォルト画像

CSSでコンポーネントを作っていると、最後にしんどくなるのは「どのセレクタが勝っているのか分からない」問題です。最初は.card h2くらいで済んでいたのに、ページが増えると.page .section .card h2みたいな指定が増えていきます。

そこで今見ておきたいのが@scopeです。ざっくり言うと、CSSの効く範囲を特定のDOMツリーに閉じるためのルールです。CSS ModulesやShadow DOMほど大きな仕組みにしなくても、普通のCSSのまま「この部品の中だけ」を指定しやすくなります。

CSS @scopeとは

@scopeは、指定したルート要素の中だけにスタイルを適用するCSSのat-ruleです。MDNではBaseline 2025の機能として扱われていて、今後の素のCSS設計ではかなり重要になると思っています。

@scope (.article-card) {
  h2 {
    font-size: 1.4rem;
  }

  p {
    line-height: 1.8;
  }
}

この場合、.article-cardの中にあるh2pだけが対象になります。ページ全体のh2へ広がらないので、後から読み返した時に意図が追いやすいです。

まずはこの形で使う

実務で最初に使うなら、カード、CTA、プロフィール、記事内の補足ボックスのような「小さく完結したUI」からが安全です。

HTML

<section class="profile-card">
  <h2>Enough Basketball Idiot</h2>
  <p>記事、ツール、バスケの記録をまとめていく場所です。</p>
  <a href="#">記事を見る</a>
</section>

<section class="note-card">
  <h2>別のカード</h2>
  <p>こちらは同じh2でも別ルールで見せたい。</p>
</section>

CSS

@scope (.profile-card) {
  :scope {
    max-width: 520px;
    padding: 24px;
    border: 1px solid #d9e2f2;
    border-radius: 8px;
    background: #ffffff;
    color: #111827;
  }

  h2 {
    margin: 0 0 12px;
    font-size: 28px;
    line-height: 1.25;
  }

  p {
    line-height: 1.8;
    color: #4b5563;
  }

  a {
    display: inline-flex;
    margin-top: 12px;
    color: #0b4dff;
    font-weight: 700;
  }
}

@supports not selector(:scope) {
  .profile-card h2 {
    font-size: 28px;
  }
}

:scopeの使いどころ

@scopeの中で:scopeを書くと、スコープのルート要素そのものを指定できます。上の例だと.profile-card自体の余白や背景を:scopeで書いています。

@scope (.profile-card) {
  :scope {
    padding: 24px;
    border: 1px solid #d9e2f2;
  }

  h2 {
    margin-block-start: 0;
  }
}

@scopeが向いている場面

  • WordPressテーマ内の共通パーツを整理したい
  • 記事本文用のスタイルとカード用のスタイルを混ぜたくない
  • LPの一部だけ違う見た目にしたい
  • CSS Modulesまでは入れたくないが、セレクタの影響範囲は狭めたい
  • 詳細度を上げ続ける運用から抜けたい

@layerとの違い

機能役割向いていること
@layerカスケードの優先順位を層で管理するreset、base、components、utilitiesの整理
@scopeスタイルの適用範囲をDOMツリーで絞る部品単位のスタイル漏れ防止
CSS Modulesビルド時にクラス名を分離するReactやAstroなどのコンポーネント開発
Shadow DOMDOMとCSSを強くカプセル化するWeb Components

自分なら、サイト全体の大枠は@layer、部品単位の漏れ防止に@scope、アプリ寄りのUIではCSS Modules、という感覚で使い分けます。全部を置き換えるというより、今あるCSS設計に足す道具です。

注意点

  • 古いブラウザまで強く見る案件では、通常のクラス指定をfallbackとして残す
  • スコープを深くしすぎると、結局読みづらいCSSになる
  • ページ全体のレイアウト指定には向かない
  • ブラウザ実装差が残る部分は、実機で確認する

あわせて読みたい

参考資料

まとめ

@scopeは、CSSを「ページ全体へ広げるもの」から「部品の中に閉じるもの」へ寄せてくれます。WordPressテーマでも、Astroでも、静的なHTMLでも使い道があります。

いきなり全CSSを置き換える必要はありません。まずはカードやCTAのような小さなUIに使って、セレクタの見通しが良くなるか試すのがちょうどいいです。