【CSS】擬似クラス :not( )・:is( )・:has( )・:where( )

## 概要
W3Cの[CSS Values and Units Module Level 4](https://www.w3.org/TR/css-values-4/#viewport-relative-lengths)で、擬似クラスについていくつか仕様が変更されました。

この変更では、擬似クラスに `論理的な組み合せ`、`属性セレクタ`、`自然言語に関する擬似クラス`など、多くの擬似クラスが追加されました。

そのため、この記事では追加された、論理的な組み合せの擬似クラスの`:not()`・`:is()`・`:has()`・`:where()`について解説していきます。

## 否定疑似クラス `:not( )`
否定疑似クラス `:not( )` は、列挙されたセレクターに一致しない要素を表す、関数形の擬似クラスになります。

### 基本構文
*クラス名がstyleの中で、pタグでないモノのスタイルを指定します。*
```css
.style:not(p) {

}
```

`:not()` を使用する際、以下の場合は気をつけてください。

+ 否定疑似クラスを入れ子にすることはできません。
    + 例 ） ❌ `:not(:not(...))`
+ 否定疑似クラスを使用する際、無意味な書き方ができます。
    + 例 ） `:not(*)` → スタイルは変化しない
+ 否定疑似クラスは、詳細度が高くなります。
    + 例 ）`#foo:not(#bar)`では、`#foo`より詳細度が高くなります。
+ `:not(.foo)` は `.foo` ではないすべての要素が選択されます。
    + 例 ）`html` や `body`も選択されることになります。


### サンプル
<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="ExELYag" data-editable="true" data-user="sp_degu" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/ExELYag">
  擬似クラス</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


### ブラウザーの互換性
<p class="ciu_embed" data-feature="css-not-sel-list" data-periods="future_1,current,past_1,past_2" data-accessible-colours="false">
<picture>
<source type="image/webp" srcset="https://caniuse.bitsofco.de/image/css-not-sel-list.webp">
<source type="image/png" srcset="https://caniuse.bitsofco.de/image/css-not-sel-list.png">
<img src="https://caniuse.bitsofco.de/image/css-not-sel-list.jpg" alt="Data on support for the css-not-sel-list feature across the major browsers from caniuse.com">
</picture>
</p>
<script src="https://cdn.jsdelivr.net/gh/ireade/caniuse-embed/public/caniuse-embed.min.js"></script>


## 論理和擬似クラス `:is( )`
論理和擬似クラス `:is( )` は、列挙されたセレクターのどれか1つにあてはまる要素を示す、関数形の擬似クラスになります。
`:where( )`との違いは、`:is( )`の詳細度にカウントされるのに対し、`:where( )`の詳細度が0であることです。

### 基本構文
*`header` `main` `footer`の中のどれかのpタグにホバーした時のスタイル*
```css
:is(header, main, footer) p:hover {

}
```

### サンプル
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="JjLvdGW" data-user="sp_degu" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/JjLvdGW">
  Untitled</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### ブラウザーの互換性
<p class="ciu_embed" data-feature="css-matches-pseudo" data-periods="future_1,current,past_1,past_2" data-accessible-colours="false">
<picture>
<source type="image/webp" srcset="https://caniuse.bitsofco.de/image/css-matches-pseudo.webp">
<source type="image/png" srcset="https://caniuse.bitsofco.de/image/css-matches-pseudo.png">
<img src="https://caniuse.bitsofco.de/image/css-matches-pseudo.jpg" alt="Data on support for the css-matches-pseudo feature across the major browsers from caniuse.com">
</picture>
</p>




## 詳細度調整擬似クラス `:where( )`
詳細度調整擬似クラス `:where( )` は、列挙されたセレクターのどれか1つにあてはまる要素を示す、関数形の擬似クラスになります。
`:is( )`との違いは、`:is( )`の詳細度にカウントされるのに対し、`:where( )`の詳細度が0であることです。

### 基本構文
*`header` `main` `footer`の中のどれかのpタグにホバーした時のスタイル*
```css
:where(header, main, footer) p:hover {

}
```
### サンプル
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="xxWjGqd" data-user="sp_degu" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/xxWjGqd">
  is</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### ブラウザーの互換性
![スクリーンショット 2022-08-05 16.05.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/0e270375-010d-7f9d-7d6a-e01c9d5d0dea.png)



## 関係上の疑似クラス `:has( )`
関係上の疑似クラス `:has( )` は、列挙されたセレクターにあてはまる要素が１つ以上あることを示す、関数形の擬似クラスになります。

### 基本構文
*クラス名がstyleの中で、pタグが含まれているモノのスタイルを指定します。*
```css
.style:has(p) {

}
```

### サンプル
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="JjLvdLO" data-user="sp_degu" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/JjLvdLO">
  where</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### ブラウザーの互換性

![スクリーンショット 2022-12-22 11.02.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/afe3d714-c780-aa45-5e0d-a68a6f8e26fc.png)

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510