【CSS】擬似クラスを用途毎に整理

CSSについて改めてドキュメントを読んでみて、今更「疑似クラス」なるもの存在を知る。
スクリプトを書かなくても似たような実装がCSSだけで出来る模様なので、用途毎に整理。
目次を見て、探してる用途に合った内容があれば、コピペして使えばいいのかなぁと。

ブラウザは、Chrome・FireFox・InternetExplorer・Edge・safariに対応している内容のみを書きました。
調べてみると「InternetExplorer」「FireFox」未対応の「疑似クラス」が多い。。
ブラウザ依存が無ければ、もっと色々できるみたいなんだけど・・。


#参考
[疑似クラス](https://developer.mozilla.org/ja/docs/Web/CSS/Pseudo-classes)

##オプションボタン・ラジオボタン・チェックボックス・チェックON時に発火

チェック用ボックスとかを非表示(display:none)にして、ボタンとか要素クリック的な使い方もできそう？
※色の切り替えや要素の表示・非表示程度だろうけども・・。

```html:sample.html
<div>
    <input type="radio" name="my-input" id="yes">
    <label for="yes">Yes</label>

    <input type="radio" name="my-input" id="no">
    <label for="no">No</label>
  </div>

  <div>
    <input type="checkbox" name="my-checkbox" id="opt-in">
    <label for="opt-in">Check me!</label>
  </div>

  <select name="my-select" id="fruit">
    <option value="opt1">Apples</option>
    <option value="opt2">Grapes</option>
    <option value="opt3">Pears</option>
  </select>


  <br />

  <label for="toggle" style="cursor: pointer;background:#00188f; color:#fff; padding:5px;
    border-radius:5px;">ボタン風ラベル</label>
  <input type="checkbox" id="toggle" style="display: none;">
  <div class="clicksample">テキスト
  </div>
```

```css:sample.css
    div,
    select {
      margin: 8px;
    }


    /* チェックが入った入力のラベル */
    input:checked+label {
      color: red;
    }

    /* チェックが入ったラジオボタン */
    input[type="radio"]:checked {
      box-shadow: 0 0 0 3px orange;
    }

    /* チェックが入ったチェックボックス */
    input[type="checkbox"]:checked {
      box-shadow: 0 0 0 3px hotpink;
    }

    /* 選択されたオプション */
    option:checked {
      box-shadow: 0 0 0 3px lime;
      color: red;
    }

    /* 「テキスト」 */
    .clicksample {
      background: lightgray;
    }

    /* ボタン風ラベルクリック時 */
    #toggle:checked+.clicksample {
      background: lightgreen;
    }
```

**結果**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/9f5d0c7f-166a-bd63-0958-c2e641042c82.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/d20ebe44-f979-ff42-b5ad-ba7111ac753c.png)


##disabled状態の場合

たまに「disabled」の色を変えたいって、お客様いますよね。

```html:sample.html
<form action="#">
  <fieldset id="shipping">
    <legend>送り先</legend>
    <input type="text" placeholder="名前">
    <input type="text" placeholder="住所">
    <input type="text" placeholder="郵便番号">
  </fieldset>
  <br>
  <fieldset id="billing">
    <legend>請求先</legend>
    <label for="billing_is_shipping">送り先と同じ:</label>
    <input type="checkbox" id="billing-checkbox" checked>
    <br>
    <input type="text" placeholder="名前" disabled>
    <input type="text" placeholder="住所" disabled>
    <input type="text" placeholder="郵便番号" disabled>
  </fieldset>
</form>
```

```css:sample.css
input[type="text"]:disabled {
  background: #ccc;
}
```

```javascript:sample.js
// ページの読み込みの終了を待つ
document.addEventListener('DOMContentLoaded', function () {
  // チェックボックスに 'change' イベントリスナーを追加
  document.getElementById('billing-checkbox').onchange = toggleBilling;
}, false);

function toggleBilling() {
  // 請求先のテキストフィールドを選択
  var billingItems = document.querySelectorAll('#billing input[type="text"]');

  // 請求先テキストフィールドを切り替え
  for (var i = 0; i < billingItems.length; i++) {
    billingItems[i].disabled = !billingItems[i].disabled;
  }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/eb4e3553-81a8-47df-2afd-15503c4fec77.png)


##enabled状態の場合
「disabled」もあるので、「enabled」ものせておきます。

```html:sample.html
<form action="url_of_form">
  <label for="FirstField">First field (enabled):</label>
  <input type="text" id="FirstField" value="Lorem"><br>

  <label for="SecondField">Second field (disabled):</label>
  <input type="text" id="SecondField" value="Ipsum" disabled="disabled"><br>

  <input type="button" value="Submit">
</form>
```

```css:sample.css
input:enabled {
  color: #2b2;
}

input:disabled {
  color: #aaa;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/f7f80dc4-11d4-c7d5-8a90-418a0135effe.png)

##フォーカス時

こちらは、業務アプリ系だとよくやっていますね。

```html:sample.html
<input class="red-input" value="I'll be red when focused."><br>
<input class="blue-input" value="I'll be blue when focused.">
```

```css:sample.css
.red-input:focus {
  background: yellow;
  color: red;
}

.blue-input:focus {
  background: yellow;
  color: blue;
}
```

**結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/73e84413-c9a3-907c-7db0-310e2900360d.png)


##ホーバー(hover)時
これは、要望あるかな・・？ありそうで無さそうな。

```html:sample.html
<a href="#">Try hovering over this link.</a>
```

```css:sample.css
a {
  background-color: powderblue;
  transition: background-color .5s;
}

a:hover {
  background-color: gold;
}
```

**結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/d68d53ef-3523-96e9-bf88-ee896a19dcdf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/6aff8ff6-cfc1-dd8b-8a2f-097c75dc13b8.png)

##リンク(aタグ)の状態に応じて、スタイルを変える。
こちらは、あまり要望ないかも・・？

```html:sample.html
<p>この段落にはリンクが含まれています。
  <a href="#">このリンクはクリックすると赤色になります。</a>
  この段落は段落やリンクをクリックすると灰色になります。
</p>
```

```css:sample.css
a:link { color: blue; }          /* 未訪問リンク */
a:visited { color: purple; }     /* 訪問済みリンク */
a:hover { background: yellow; }  /* ホバー時 */
a:active { color: red; }         /* アクティブなリンク */
p:active { background: #eee; }   /* アクティブな段落 */
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/be991f31-9ef2-724a-8388-856513573e02.png)

##否定(not)文？

たまにスクリプトのセレクタでも使います。
一つ一つ、classとかの適用がめんどいときに使える？

```html:sample.html
<p>I am a paragraph.</p>
<p class="fancy">I am so very fancy!</p>
<div>I am NOT a paragraph.</div>
```

```css:sample.css
.fancy {
  text-shadow: 2px 2px 3px gold;
}

/* <p> elements that are not in the class `.fancy` */
p:not(.fancy) {
  color: green;
}

/* Elements that are not <p> elements */ 
body :not(p) {
  text-decoration: underline;
}

/* Elements that are not <div> and not <span> elements */
body :not(div):not(span) {
  font-weight: bold;
}

/* Elements that are not `.crazy` or `.fancy` */
/* Note that this syntax is not well supported yet. */
body :not(.crazy, .fancy) {
  font-family: sans-serif;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/84b5d567-7664-6e09-8343-0fcdf7f00231.png)

##要素の位置を指定する場合

縞模様とかで一覧系だとよく使いそう。

```html:sample.html
<h3><code>span:nth-child(2n+1)</code>, WITHOUT an
   <code>&lt;em&gt;</code> among the child elements.</h3>
<p>Children 1, 3, 5, and 7 are selected.</p>
<div class="first">
  <span>Span 1!</span>
  <span>Span 2</span>
  <span>Span 3!</span>
  <span>Span 4</span>
  <span>Span 5!</span>
  <span>Span 6</span>
  <span>Span 7!</span>
</div>

<br>

<h3><code>span:nth-child(2n+1)</code>, WITH an
   <code>&lt;em&gt;</code> among the child elements.</h3>
<p>Children 1, 5, and 7 are selected.<br>
   3 is used in the counting because it is a child, but it isn't
   selected because it isn't a <code>&lt;span&gt;</code>.</p>
<div class="second">
  <span>Span!</span>
  <span>Span</span>
  <em>This is an `em`.</em>
  <span>Span</span>
  <span>Span!</span>
  <span>Span</span>
  <span>Span!</span>
  <span>Span</span>
</div>

<br>

<h3><code>span:nth-of-type(2n+1)</code>, WITH an
   <code>&lt;em&gt;</code> among the child elements.</h3>
<p>Children 1, 4, 6, and 8 are selected.<br>
   3 isn't used in the counting or selected because it is an <code>&lt;em&gt;</code>, 
   not a <code>&lt;span&gt;</code>, and <code>nth-of-type</code> only selects
   children of that type. The <code>&lt;em&gt;</code> is completely skipped
   over and ignored.</p>
<div class="third">
  <span>Span!</span>
  <span>Span</span>
  <em>This is an `em`.</em>
  <span>Span!</span>
  <span>Span</span>
  <span>Span!</span>
  <span>Span</span>
  <span>Span!</span>
</div>
```

```css:sample.css
html {
  font-family: sans-serif;
}

span,
div em {
  padding: 5px;
  border: 1px solid green;
  display: inline-block;
  margin-bottom: 3px;
}

.first span:nth-child(2n+1),
.second span:nth-child(2n+1),
.third span:nth-of-type(2n+1) {
  background-color: lime;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/e0823361-ffba-3caf-64ec-9121646f99ae.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/3ee552ff-7bbd-6a8c-6faf-c20f3ec0feba.png)

##プレースホルダー表示中の間だけスタイルを適用

たまに要望があるかも・・？

```html:sample.html
<input placeholder="何か入力してください！">
```

```css:sample.css
input {
  border: 2px solid black;
  padding: 3px;
}

input:placeholder-shown {
  border-color: red;
}
```

**結果**

*未入力*
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/69ed6ec6-fcb1-bf71-f7bf-e5820e85824c.png)

*入力済*
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/d3b7e5e5-7dd3-6881-c3f3-7456ba3c7be2.png)

---
**とまぁ書いておきながら、結局全部スクリプトで書いちゃえ！って、思ってしまいそうではある。。**