CSSの:not()および:where()を活用しよう。

こんにちは、アンドレです。
以前の記事で、:has()についてご紹介しましたが、今回は:not()および:where()の活用例をご紹介したいと思います。

:not()の活用例

(そもそも:not()って何?という方は下記を参照ください)
https://developer.mozilla.org/ja/docs/Web/CSS/Reference/Selectors/:not

個人的に一番よく使うのが、:first-childと合わせて:not(:first-child)とし、:first-childではない=前に何らかの要素があればmargin-topを適用し、前の要素との余白を確保するやり方です。

section:not(:first-child) {
  margin-top: 64px;
}

のような書き方ですね。見出しやヘッダーの場合は下方向に一定の余白を確保したいことが多いので、その際は:not(:last-child)とします。

また、:has()と合わせることで、何かしらの要素がない場合にスタイルを変化させることもできます。
例えば、

.list:not(:has(.item)) {
  display: none;
}

とすると、.itemを持たない.listを非表示にすることができます。

:where()の活用例

(そもそも:where()って何?という方は下記を参照ください)
https://developer.mozilla.org/ja/docs/Web/CSS/Reference/Selectors/:where

:where()はMDNの例を見ると、セレクターの詳細度を高めずに特定のコンテキスト(「olの子孫である」など)におけるスタイリングをするのが用途に思えますが、引数に複雑セレクターを指定できるので、子孫結合子および全称セレクターと合わせることで、子要素からより直接的にコンテキストを参照させることができます。例えば、

.module {
  &:where(ul *) {
    color: red;
  }
  &:where(ol *) {
    color: blue;
  }
}

のようにすると、ul内の.moduleは赤文字、ol内の.moduleは青文字になります。
モジュールのスタイルは基本的に集約されているほうがよいはずなので、コンテキストによってスタイルが変化する場合はこのような記述のほうが好ましいかと思います。

まとめ

:has()、:not()、:where()を使うことで、「なぜそのスタイルになるのか」をよりロジカルに指定することができ、結果として変更等に強いCSSになると考えています。
皆さんもぜひ活用してみてください!