60
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CSSAdvent Calendar 2023

Day 9

SCSSからCSSネスティングに切り替えたい人に贈る3つの罠

Last updated at Posted at 2023-12-08

今年も残すところあと1月を切り、CSSもこの1年でさらに進化を遂げましたね。

CSSは普段、SCSSを使ってコーディングしている方も多いますが、
CSSの進化により、SCSS不要論も今年チラチラ見られるようになりました。

本当にSCSSがなくても問題ないのか、新しいCSSネストについて調べてみました。

CSSネストの基本

まずはCSSネストがなんなのかというおさらいをしておきましょう。

2つのクラスparentとchildがあり、parentより子の階層にchildクラスが含まれているときだけスタイルづけしたい時、普通のCSSだとこのように書きます。

.parent {
  min-height: 100dvh;
  width: 100%;
}
.parent .child {
  background: white;
}

二度、parentクラスの記述があり、面倒ですね。
それを、このように書いて、parentとchildの関係性をわかりやすくし、記述量を減らせるのがCSSネストになります。

.parent {
  min-height: 100dvh;
  width: 100%;

  .child {
    background: white;
  }
}

CSSネストの罠

そんな便利なCSSネストですが、今までSCSSでのネスト構造に慣れていた人が
少し混乱してしまうかもしれない罠ポイントがあります。

詳細度の罠

CSSでのネストは傍目にはSCSSでのネストと同じように見えるのですが、
複数個の親要素を同時に記載した場合、動作が異なります。

例えば、あるクラスparent1やID codeの子要素になった時のtextクラスにスタイルを指定したい時、このようにネストで記述します。

.parent1, #code {
  font-size: 1.0rem;

  .text {
   color: green;
  }
}
<div class="parent1">
  <p class="text"></p>
</div>

SCSSの場合だと、 .parent1 .text#code .textとそれぞれのセレクタをCSSに生成しますが、CSSの場合は:is(.parent1, #code) .textと同じように解釈します。

:is()は最近出てきた新しい擬似クラスです。
これは複数のセレクタをまとめて定義するときに便利なのですが、:is()の詳細度は、()でまとめたセレクタの中で一番高い詳細度となります。

つまり、上の例CSSネストの時のセレクタ:is(.parent1, #code) .textでは、詳細度は「1,1,0」となります。
SCSSの場合は、「0,2,0」となるので、SCSSと同じつもりでコーディングしたときにうまくクラスが当たらなくなる場合があります。

&の役割が少し違う罠

CSSのクラスをBEMでつけたりすると、クラス名は結構長くなりがちです。

.contact {
  &__wrapper {}
  &__button {
    &--type1 {}
  }
}

SCSSのネストの場合、このように&を使ってクラス名の重複を避けて記述することができますが、CSSのネストでは&にテキストの参照する機能はないため、このような記述はできません。

ですので、CSSでは真面目にクラス名を記述することになります。

.contact {
 .contact__wrapper {}
 .contact__button {}
 .contact__button--type1 {}
}

記号始まりでないとダメな罠

CSSのネストと認識されるには下記の記号がセレクタの前にある必要があります。

& . # : + > ~ [ @

このため、h1やspanなどの要素型セレクタをネストする際はこのように &: ネストセレクタを使って記述する必要があります。

.button {
  & span {}
}

ただし、ごく最近のブラウザでは、要素型セレクタに&がなくてもネストとして認識されるようになるとのことです!

chrome 120以降, safari 17.2以降, Firefox 117以降

また、このように擬似クラスは、&なしでCSSネストとして認識されます。

.button {
  :hover {
    opacity: 0.8;
  }
}

しかし、この場合、 .button *:hoverと解釈され、buttonクラスの子孫要素の全てがhoverされた時のスタイルを定義することになってしまいます。
もし、buttonクラスの、hover擬似クラスを定義したい場合は、 &: ネストセレクタを使ってこのように記載します。SCSSと同じですね。

.button {
  &:hover {
    opacity: 0.8;
  }
}

終わりに

SCSSネストからCSSネストに切り替える場合、そのまま記述を移し替えた場合
引っかかりそうな罠を3つ紹介しました。

2023年12月初旬現在、罠となってはしまいますが、どんどん仕様も変わっているのでいつの日かそのまま移行できる日も来るかもしれませんね。


参考

60
38
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
60
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?