【CSS】CSSネストの基本|記法・書き方・対応ブラウザ・Safari/iOSの注意点まで

【CSS】CSSネストの基本|記法・書き方・対応ブラウザ・Safari/iOSの注意点まで

今回はCSSのネストについて解説します。

従来はSass(SCSS記法)などのCSSプリプロセッサを利用してネスト構造を利用していましたが、2023年にChromiumベースのブラウザが初めて対応し、2025年現在ではほとんどの主要ブラウザで利用できるようになっています。

基本の書き方

Sass (SCSS記法)などのように入れ子で書くことができ、ブラウザが直接解釈します。

HTML
<div class="message">
    メッセージの全体は1.2rem
    <p class="em">ここだけ2remに</p>
</div>

上記のHTMLにCSSを適用するには、ネストを利用しない場合は以下のように記述します。

CSS(従来の書き方)
.message { 
  font-size: 1.2rem; 
}
.message .em { 
  font-size: 2rem; 
}

ネストを利用した方法だと以下のようにスッキリ書けます。

CSS(ネストの書き方)
.message {
    font-size: 1.2rem; 
    .em { font-size: 2rem;  }
}

どちらも出力結果は同じですが、ネストの方が「どの要素の内側の指定か」が直感的に伝わります。

サンプル

メッセージの全体は1.2rem

ここだけ2remに

ネストの中にもネストを書くことができます。

.card {
    .contents {
      .mark-main {
          font-size: .6rem;
      }
    }
}

メディアクエリなどの条件付きグループ(@media / @supports / @container など)も内側に書けます。

.card {
    display: grid;
    grid-template-columns: 1fr;
    @media (width >= 768px) {
        grid-template-columns: 1fr 2fr;
    }
}

擬似クラスなど“親と結合”するケースでは & を使います。

.card {
    &:hover { box-shadow: 0 0 8px; }    /* => .card:hover  */
    &::before { content: ""; }          /* 擬似要素は & を付ける */
}

コンビネータ・結合子(要素どうしの関係を指定する記号)も内側に書けます。

.card {
    .title { font-weight: 700; }    /* => .card .title  */    
    > a { text-decoration: none; }  /* => .card > a */
    + .card { margin-top: 1rem; }   /* => .card + .card */
    ~ .card { opacity: .8; }        /* => .card ~ .card */
}

古いブラウザ/Safari・iOSへの対応

ネストしたCSSが効かない理由として、古いブラウザや、Safari/iOS/iPadOSのバージョンが古い可能性があります。

古いブラウザにも対応する必要がある場合は、従来通りビルド変換(変換ツール)を使います。

ビルド変換(変換ツール)を使う

CSSのネストは最新の主要ブラウザには対応していますが、古いブラウザ にも対応する必要がある場合には、従来通りSassや、PostCSS、Lightning CSS などのCSSプリプロセッサで通常のCSSに変換して配信ください。

ここでは詳しく解説しませんが、以下のツールを利用します。

  • Sass(Dart Sass)
    そのまま SCSS記法 のネストで書けて、ビルド時にフラットCSSへ展開されます。
    CLI:npm i -D sass → sass src/main.scss dist/main.css --style=expande
    webpack:sass-loader + css-loader
    gulp:gulp-sass(Dart Sass)
  • PostCSS
    postcss-nesting を使うと、ネイティブのCSSネストの書式に近い形で記述でき、出力をフラット化できます。
    webpack/postcss-loader や gulp-postcss に組み込み可。
  • Lightning CSS
    対象ブラウザに合わせてネストを自動ダウングレード(単体/webpack でも利用可)。

なお、主要ブラウザがCSSネスト対応を開始した各バージョンとリリース日は以下となっています。

Can I Use ?

ブラウザ対応開始
バージョン
リリース日備考
Chrome (デスクトップ)1122023-04-04112–119 は部分対応(先頭に記号が必要)、120+ で完全対応
Chrome(Android)1202023-12-05モバイルもデスクトップと同様
Edge (デスクトップ)1122023-04-04Chrome (デスクトップ)と同様
Edge (Android)1202023-12-19モバイルもデスクトップと同様
Safari (macOS)
iOS/iPadOSの各ブラウザ
16.52023-05-1816.5–17.1 部分対応/17.2+ で完全対応
Firefox (デスクトップ)
Android版も同様
1172023-08-29117+ で完全対応
Samsung Internet252024-04-24

また、現状のブラウザのバージョン別の利用数は以下のサイトなどから確認できます。

[Edit Chart Data] から各データや表を変更できます。

https://gs.statcounter.com/browser-version-market-share/all/japan

Safari(16.5〜17.1)への対応

Safari(WebKit:iOS/ iPadOS 16.5〜17.1にインストールした各ブラウザも含みます)は、16.5からCSSのネストに対応しましたが、Safari(16.5〜17.1)は「タグ名で始まるネスト」は解釈しない(& なしでは解釈されない)という制限がありました。

例:h2 { … })を & h2 にしないと解釈されない

17.2以降は問題ありません。

iOS Safari も同様です。iOS/ iPadOS の Chrome/Firefox/Edge も WebKit のため同じ仕様に従います。

16.5〜17.1の古いバージョンのSafariも対応する必要がある場合は、& h2 など & を明示すればより安全です。

なお、クラス/ID/結合子(>, +, ~)で始まる場合は & 不要です。

対応する必要がある場合は以下のように前に&をいれます。

.article {
    & h2 { margin: .2rem; }       /* => .article h2 */
    &::before { content: ""; }    /* => .article::before */
    .title { padding: .2rem; }    /* => .article .title */
    #contents { margin: .2rem; } /* .article #contents */
    > h2 { margin: .5rem; }     /* => .article > h2 */
    + .article { margin-top: 1rem; }
}

iOSとiPadOSのバージョン別利用率は以下などから確認できます。

https://developer.apple.com/jp/support/app-store/

豊富なオリジナルブロックでLPをかんたんに作成できるLP Creator

LPをかんたんに作成できるLP Creator

デザイン・機能・SEO・収益化にこだわったメディア運営者向け「STREETIST」

デザイン・機能・速度・SEO・収益化にこだわった、ブロガー・メディア運営者向けのデザインテーマ STREETIST

CSSネストのデメリット

古いブラウザの対応が必要

最新の主要ブラウザのみ対応するのなら問題なく利用できますが、古いブラウザまで対応する必要がある場合は、前述の通りに対応しましょう。

深いネスト構造は読みづらくなる

あまり深いネスト構造にしてしまうと、保守や可読性が低減します。

ネストは適度な深さにとどめ、読みやすさを優先しましょう。

まとめ

いかがでしょうか?

現状ではまだCSSでネストをやるには少し不安があるかもしれませんね。

多くのプロジェクトでは何らかの CSS プリプロセッサ/ビルド変換を使っていることがほとんだと思いますが、当面はSassや PostCSS(postcss-nesting)や Lightning CSS で変換するのが安全策です。

ネスト以外にも、Sass には mixin・変数・関数(@use / @forward 含む)などの成熟した機能があり、PostCSS でも Autoprefixer や postcss-preset-env / postcss-custom-media などで未来仕様の前倒しや最適化が行えます。

ただし、今後は旧環境の自然減に伴い、ビルドに頼らずネストをそのままCSS配信する運用も現実的になります。

ビルドに頼る必要もない、ちょっとしたCSSを書く際に、本記事で紹介したポイントを思い出していただけると幸いです。


他にもこんな記事があります。