コンポーネントにスコープを限定したCSSを使うと、ルールが適用される要素を制御できます。ページ間でルールを再利用するには、共有スタイルシートを使います。Mac上の小規模なHTMLプロジェクトでは、両方を組み合わせることもできます。移動やメンテナンスの対象に応じてファイル構成を選びましょう。

このガイドでは、角丸の正方形カードと、その外側に置いたメモを含むローカルページのスタイル設定を説明します。カードの外観を予測しやすく保ったうえで、そのCSSをページ内に置くか、再利用可能なファイルに置くかを判断します。ラベルと図形は説明用の例であり、フレームワークやダウンロードした素材は必要ありません。

実際に何を選ぶのでしょうか?

決めることは2つあります。CSSをどこに置くか、そしてどの要素を選択するかです。埋め込みスタイルシートは、HTML文書の style 要素内に置かれます。外部スタイルシートは別個のリソースであり、link を使い、rel="stylesheet" と href のパスを指定して読み込みます。これらはCSSを提供するためのHTMLの仕組みです。どちらの配置方法でも、通常のセレクターにコンポーネントの境界が自動的に与えられるわけではありません。HTML Standard: The style element、MDN: External resource link element。

ネイティブCSSの @scope は、選択範囲の境界を追加します。ルート要素を指定し、そのサブツリー内に適用するルールを記述します。文書内に似た要素がある場合でも、短いセレクターを使いやすくできます。Chromeのドキュメントでは、ネイティブのスコープと、生成されたクラスや属性を使ってセレクターを書き換えるツールも区別されています。コンポーネントの例がそのようなツールに依存する場合、それは別途必要な前提条件です。Limit the reach of your selectors with the CSS @scope at-rule。

この作業では、以下の判断表を参考にしてください。これはドキュメントに記載された仕組みに基づく編集上の推奨であり、ブラウザーの要件ではありません。

目の前の作業 推奨する構成 一緒に移動する必要があるもの
小さなページを1つのファイルにまとめる style 要素にCSSを埋め込む HTMLと、別途参照されているアセット
複数のページで同じカードをメンテナンスする コンポーネント専用クラスを使った外部スタイルシートを使う 各HTMLページと共有CSS
定義したサブツリー内で短いセレクターを使う 明示的なルートを指定した @scope ルールを、埋め込みまたは外部のCSSに追加する CSSと、一致するルートを含むマークアップ
スコープ対応が不確かなブラウザーをサポートする 重要なスタイルを通常のクラスルールに置く HTMLと、それらのルールを含むスタイルシート

「持ち運びやすい」という言葉には、具体的な意味が必要です。HTMLファイル1つだけを移動できると便利です。パスが引き続き正しく解決されるなら、HTMLとCSSを含むフォルダーも持ち運べます。再利用可能なコンポーネントには、さらに別の持ち運びやすさも必要です。移動先で、セレクターが想定するマークアップ上のフックが維持されていなければなりません。

Macで動作する2ファイルの例を作る

form-study という名前のフォルダーを作成し、その中に index.html と shared.css という名前のプレーンテキストファイルを2つ保存します。TextEditを使う場合は、コードを貼り付ける前に ファイル > 新規、続いて フォーマット > 標準テキストにする を選びます。HTMLファイルは .html 拡張子で保存し、確認を求められたら Use .html を選ぶようAppleが案内しています。スタイルシートの実際のファイル名が shared.css であり、末尾に .txt が追加されていないことを確認してください。Work with HTML documents in TextEdit on Mac。

次のHTML文書全体を index.html として保存します。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Form Study</title>
  <link rel="stylesheet" href="shared.css">
</head>
<body>
  <main class="study-page">
    <h1>Form Study</h1>
    <section class="shape-card">
      <h2 class="shape-card__title">Tile A</h2>
      <div class="shape-card__shape" aria-hidden="true"></div>
      <p>A rounded square.</p>
    </section>
    <section class="plain-note">
      <h2>Note B</h2>
      <p>This section is outside the card.</p>
    </section>
  </main>
</body>
</html>

次のスタイルシート全体を shared.css として保存します。

body {
  margin: 0;
  background: #f4f3ef;
  color: #252525;
  font-family: system-ui, sans-serif;
  line-height: 1.5;
}

.study-page {
  max-width: 40rem;
  margin: 2rem auto;
  padding: 0 1rem;
}

.shape-card {
  padding: 1.5rem;
  border: 2px solid #526676;
  border-radius: 1rem;
  background: #ffffff;
}

.shape-card__title {
  margin: 0 0 1rem;
  color: #36576b;
}

.shape-card__shape {
  width: 6rem;
  height: 6rem;
  border-radius: 1.25rem;
  background: #597b91;
}

.plain-note {
  margin-top: 2rem;
}

index.html をSafariまたは別のデスクトップブラウザーで開きます。表示されるのは、青い角丸の正方形を含む、枠線付きの白いカードと、その後に続く枠線なしのメモです。スタイルシートの読み込み方は、スタイルシートへのリンクの href にCSSリソースを指定するという、MDNのドキュメントに沿ったものです。MDN: Including a stylesheet。

この例では意図的に、カードのタイトルに専用クラスを付けています。ネイティブのスコープを使わなくても、想定するスタイルの適用関係がわかるためです。ページの背景とフォントは文書全体のデフォルトで、カードの枠線、タイトルの色、図形はカードに属します。再利用可能なルールを切り出すときも、この違いを保ってください。移動先のページでは、このページの背景や幅を引き継がずにカードだけを使いたい場合があります。

デザインを共有するには、同じフォルダーに2つ目のHTMLページを作り、同じスタイルシートへのリンクを使います。すると、両方のページが1つのCSSファイルを参照します。そのファイルの変更は、リンクしているすべてのページに影響するものとして扱い、共有ルールを変更したら各ページを確認してください。

ネイティブのスコープ付きCSSが役立つのはどんなときですか?

コンポーネントに複数の要素があり、シンプルなローカルセレクターが役立つ場合、特に入れ子になったコンテンツの周囲に明示的な下限を設ける必要がある場合は、@scope を使います。CSS Cascading and Inheritance仕様では、ルート要素と任意の制限要素によってスコープを定義しています。ルートは対象に含まれます。制限要素とその子孫は、スコープ付きルールの一致対象から除外されます。この仕様はワーキングドラフトです。CSS Cascading and Inheritance Level 6: Scoping Styles。

小さな実験として、次の任意のコードを shared.css に追加します。既存のサンプルマークアップを使い、カード内の段落の外観を変更します。

/* Optional addition to shared.css */
@scope (.shape-card) {
  p {
    padding: 0.5rem;
    background: #edf2f5;
  }
}

対応ブラウザーでは、カード内の段落に淡い背景色とパディングが適用されます。メモの段落にはこのルールのスコープ外なので適用されません。CSSは引き続き共有ファイル内にあります。スコープと共有は併用できます。

後からクラス nested-sample の入れ子領域を追加する場合は、この任意のコードを次のものに置き換えられます。これは境界の例です。元のページにはまだそのような入れ子領域はありません。

/* Alternative optional fragment */
@scope (.shape-card) to (.nested-sample) {
  p {
    padding: 0.5rem;
    background: #edf2f5;
  }
}

この制限により、入れ子領域はこれらのセレクターに一致しなくなります。ただし、スタイルが完全に分離されるわけではありません。color や font-family などの継承プロパティは、スコープの制限を越えて伝わることがあります。親要素に似た見た目が入れ子要素に残っている原因を調べるときは、この違いを念頭に置いてください。MDN: @scope description。

.shape-card のような明示的なルートを使うと、CSSを別のファイルへ移動したときに依存関係も明確になります。移動先の文書には、そのクラスを持つ要素が必要です。スタイルシートだけを移動しても、必要なマークアップは用意されません。

ブラウザーの対応にはどのような制限がありますか?

MDNは現在、@scope を Baseline 2026 としており、2026年3月以降、最新のブラウザーバージョンで利用できるようになりました。古いブラウザーでは対応していない場合があります。Macが手元にあるからといって、インストール済みブラウザーがどのCSS機能に対応しているかはわかりません。使用する予定のバージョンについて互換性情報を確認してください。MDN: @scope browser compatibility。

古いブラウザーも対象にする場合は、重要なカードのスタイルを上記の通常のクラスルールに残してください。任意のスコープ付き段落スタイルは、追加の機能として扱えます。CSSのエラー処理では、ブラウザーは未対応の内容を破棄しながら、有効なCSSの処理を続けることができます。そのため、スタイルシートを読み込んだだけでは、その中のすべてのルールが適用されたとは限りません。MDN: CSS error handling。

@scope を使わずに同じ段落スタイルを適用するには、カード内の段落に shape-card__caption などの専用クラスを付け、そのクラスを通常のルールで指定します。これによりマークアップ上のフックは増えますが、ネイティブのスコープに依存せずに表示できます。

同じ動作を期待して、style 要素に scoped 属性を追加しないでください。現行のHTML Standardに記載されたその要素の属性一覧には、この属性は含まれていません。ネイティブCSSのスコープには @scope ルールを使います。HTML Standard: The style element、MDN: @scope syntax。

ページの持ち運びやすさを保つには?

この例では、form-study フォルダー全体を移動すれば、index.html と shared.css の関係が保たれます。HTMLだけを移動すると、スタイルシートは元の場所に残ります。作成したページを引き渡すときや、配置を整理するときは、次の簡単な依存関係のチェックを行ってください。

  1. マークアップ: コンポーネントのクラスと、そのセレクターに必要な構造を維持します。
  2. スタイルシート: CSSファイルを含め、HTMLのリンク先が正しい場所を指すようにします。
  3. リソース: CSSから参照されるファイルを含め、パスを維持するか更新します。
  4. ブラウザー: ページを開くブラウザーバージョンで、スタイルが適用される方法を確保します。

コンポーネントにフォントや装飾ファイルを追加する場合は、3つ目の確認が重要になります。MDNの説明によると、CSS内の相対URLはスタイルシートのURLを基準に解決されます。そのため、宣言を別のフォルダーにあるスタイルシートへ移すと、参照先のリソースが変わることがあります。MDN: url() CSS function。

たとえば、外部スタイルシートをプロジェクトフォルダーから styles サブフォルダーへ移すと、url("assets/tile.png") を参照する宣言は styles/assets 内を指すようになります。パスを更新するか、対応するディレクトリ構成を維持してください。この例では図形をCSSだけで描いているため、そのような依存関係はありません。

HTMLファイル1つだけで引き渡すことを優先する場合は、指定したCSSを文書の head 内にある style 要素へ埋め込み、スタイルシートへのリンクを削除します。これで、この例に必要なのはHTMLファイルだけになります。任意の明示的なルートを持つ @scope ブロックも含め、同じセレクターを使ってください。HTMLでは style 要素を使ってスタイルシートを埋め込めます。HTML Standard: The style element。

ファイルを移動して再読み込みし、選択を確認する

プロジェクトフォルダー全体を別の場所にコピーし、コピーしたHTMLをブラウザーで開きます。そのコピー内で shared.css の図形の背景色を変更して保存し、ページを再読み込みします。画面に変化があれば、コピーしたページが使っているスタイルシートを編集したことを確認できます。

次に、カードとメモの両方を確認します。期待どおりなら、カードのスタイルは維持され、メモは任意のスコープ付き段落ルールの対象外のままです。ページ全体のスタイルがなくなった場合は、まずCSSのファイル名とリンクのパスを確認してください。任意のスタイルだけが適用されない場合は、ブラウザーの対応状況とスコープのルートを確認してください。無関係な要素まで変化した場合は、意図したコンポーネントの範囲を越えて適用されるセレクターを調べてください。

TextEditでHTMLを開き直すときにソースを表示するには、ファイル > 開く を選択し、必要に応じて オプションを表示、リッチテキストコマンドを無視 の順に選びます。Appleは、次回以降の読み込みに使う設定 Display HTML files as HTML code instead of formatted text についても説明しています。Work with HTML documents in TextEdit on Mac。

この小さなページをまとめておくことが主な目的なら、埋め込みCSSを選びます。複数のページで同じルールをメンテナンスするなら、共有スタイルシートを選びます。境界によってルールが簡潔になり、ブラウザーも対応している場合は、ネイティブのスコープを追加します。最後に実際のファイルを移動して開き直し、選んだ構成が依存するマークアップ、スタイルシート、リソース間の関係を確認してください。

参考資料