2023 年に正式に仕様として加わり、それまでは Sass などのプリプロセッサを使用しなければ実現できなかったネストが、ネイティブ CSS で可能になりました。

この記事では、CSS ネストの基本から、従来の CSS の書き方がネストを使った場合どのような記述になるのか、CSS ネストのメリット・デメリットについて解説していきます。

LINE着せかえ「回るお寿司」販売中!

CSS ネストとは?

従来の CSS では、ある要素が他の要素の子孫であることを示すためには、セレクターを半角スペース区切り(子孫結合子)で記述する必要がありました。

.container {
  background-color: #F0F0F0;
}

.container .item {
  color: #333;
}

これが、CSS ネストを使用すると、直感的に親子関係がわかりやすい形で記述できます。

.container {
  background-color: #F0F0F0;

  .item {
    color: #333;
  }
}

もちろん、ネストが可能なのは子孫結合子だけではありません。ここからは、CSS の様々なセレクターについて、従来の書き方がネストを使用するとどのように書けるのかを解説していきます。

CSS ネストの記述例

結合子

冒頭で紹介した子孫結合子を含む、子結合子>や、次兄弟結合子+、後続兄弟結合子~などの結合子を使用したネストの書き方です。

従来の CSS の書き方

.container .item {
  color: #333;
}

.list > li {
  list-style: disc;
}

h2 + p {
  color: #FF0000;
}

ネストを使った CSS の書き方

.container {
  .item {
    color: #333;
  }
}

.list {
  > li {
    list-style: disc;
  }
}

h2 {
  + p {
    color: #FF0000;
  }
}

疑似クラス・疑似要素

:hover::afterなどの疑似クラス・疑似要素をネストする場合は、入れ子セレクター&を使用します。この入れ子セレクター&は、ネスト内で親セレクターをそのまま参照する役割を持ち、結合子では省略可能でしたが、疑似クラス・疑似要素では省略できません。

従来の CSS の書き方

button:hover {
  background-color: blue;
}

button::after {
  content: " →";
}

.card:has(.image) {
  border: 1px solid black;
}

ネストを使った CSS の書き方

button {
  &:hover {
    background-color: blue;
  }
  
  &::after {
    content: "→";
  }
}

.card {
  &:has(.image) {
    border: 1px solid black;
  }
}

属性セレクター

属性セレクター[ ]のネストの書き方です。こちらも、入れ子セレクター&を使用し、親セレクターを参照する必要があります。

従来の CSS の書き方

input[type="text"] {
  border: 1px solid #ccc;
}

ネストを使った CSS の書き方

input {
  &[type="text"] {
    border: 1px solid #ccc;
  }
}

複合セレクター

複数のクラスを持つ要素を示す、複合セレクターのネストの書き方です。こちらも、入れ子セレクター&を使用し、親セレクターを参照する必要があります。

従来の CSS の書き方

.note.caution {
  background: #FFDDDD;
}

ネストを使った CSS の書き方

.note {
  &.caution {
    background: #FFDDDD;
  }
}

親要素に異なるクラスがある場合

入れ子セレクター&は、頭以外でも使用できます。例えば、親要素に付くクラスが変わる場合では、以下のように記述することができます。

従来の CSS の書き方

.card {
  color: #000000;
  background: #FFFFFF;
}

html.dark-mode .card {
  color: #FFFFFF;
  background: #000000;
}

ネストを使った CSS の書き方

.card {
  color: #000000;
  background: #FFFFFF;

  html.dark-mode & {
    color: #FFFFFF;
    background: #000000;
  }
}

アットルール

@media@layerなどのアットルールもネストして記述することができます。アットルール自体を入れ子にすることも可能で、その場合は入れ子にしたアットルールに応じて適切な形で結合されます。

従来の CSS の書き方

/* @media 単体 */
.card {
  width: 640px;
}

@media (max-width: 800px) {
  .card {
    width: 320px;
  }
}

/* @media 複数 */
.container {
  color: blue;
}

@media (max-width: 800px) {
  .container {
    color: red;
  }
}

@media (max-width: 800px) and (min-width: 400px) {
  .container {
    color: green;
  }
}

/* @layer */
@layer base {
  .foo {
    block-size: 100%;
  }
}
@layer base.support {
  .foo .bar {
    min-block-size: 100%;
  }
}

ネストを使った CSS の書き方

/* @media 単体 */
.card {
  width: 640px;

  @media (max-width: 800px) {
    width: 320px;
  }
}

/* @media 複数 */
.container {
  color: blue;
  background: grey;

  @media (max-width: 800px) {
    color: red;

    @media (min-width: 400px) {
      color: green;
    }
  }
}

/* @layer */
.foo {
  @layer base {
    block-size: 100%;

    @layer support {
      & .bar {
        min-block-size: 100%;
      }
    }
  }
}

CSS ネストのメリットとデメリット

とても便利な CSS なネストですが、メリットもあればデメリットもあります。

メリット

  • コードの可読性保守性向上 :
    ネストを使用すると、親子関係が明確に表現されるため、スタイルがどの要素に適用されているのかが分かりやすくなります。特に、多くのコンポーネントがある場合などでは、要素の関係を直感的に理解しやすくなります。
  • 冗長なコードの削減 :
    同じ親要素に対して繰り返しセレクターを記述する手間を省けます。長いクラス名がある場合も記述が一度で済むので、容量の削減にもなります。

デメリット

  • 過剰なネストによる可読性の低下 :
    ネストが深くなりすぎると、コードが複雑になり、可読性が低下します。特に過度なネストは、後からコードを見たときに意図が分かりにくくなり、修正が困難になることがあります。
  • パフォーマンスの影響 :
    深いネストや多くのセレクターを使用すると、ブラウザがスタイルを計算する際に処理が増え、パフォーマンスに悪影響を及ぼすことがあります。

終わりに

CSS のネストを活用することで、スタイルの可読性やメンテナンス性が向上し、コードの整理もしやすくなります。ただし、過剰なネストは可読性を損なう可能性があるため、適切なレベルで使用することが重要です。ぜひ実際に試して、CSS ネストの利便性を体感してみてください!

参考