困った時に使える擬似要素と擬似クラス

擬似クラスや擬似要素は増えていて、５年くらい前に覚えた知識と現状はかなり変わっています。
以前はJavaScriptで行なっていたような実装もCSSのみで行えるようになってきました。
そこでもう少し手軽にいろいろできないかなと思い、自分のメモがてらまとめました。

## 擬似要素
名前の通り擬似的な要素です。英語では「pseudo elements」で検索すると引っかかります。CSS3になってからはコロン２つで表現します。

### ::before
beforeは要素内の要素の先頭に対して、擬似的な要素を作成します。

```html
<p class='paragraph'>textextextextext</p
```

```scss
.paragraph {
  color: #333;

  &::before {
    content: 'BEFORE';
    color: #f00;
  }
}
```

<p data-height="265" data-theme-id="0" data-slug-hash="VEGjVp" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似要素::before" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/VEGjVp/">擬似要素::before</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### ::after
afterは要素内の要素の最後に対して、擬似的な要素を作成します。

```html
<p class='paragraph'>textextextextext</p
```

```scss
.paragraph {
  color: #333;

  &::after {
    content: 'AFTER';
    color: #f00;
  }
}
```
<p data-height="265" data-theme-id="0" data-slug-hash="BqOLpv" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似要素::after" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/BqOLpv/">擬似要素::after</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### ::selection
selectionは要素内のテキストを選択した際にスタイルを変化させます。

```html
<p class='paragraph'>
  textextextextexttextextextext<br>
  texttextextextextexttextextextextext<br>
  textextextextexttextextextextexttextextextextext<br>
  textextextextexttextextextextext
</p
```
```scss
.paragraph {
  color: #333;

  &::selection {
    color: #fff;
    background-color: #333;
  }
}
```
<p data-height="265" data-theme-id="0" data-slug-hash="VEGKdx" data-default-tab="html,result" data-user="yutasuzuki" data-pen-title="擬似要素::selection" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/VEGKdx/">擬似要素::selection</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### ::first-letter
first-letterは要素の先頭の文字に対してスタイルを変化させます。

```html
<p class='paragraph'>
  textextextextexttextextextext<br>
  texttextextextextexttextextextextext
</p
```
```scss
.paragraph {
  color: #333;

  &::first-letter {
    font-size: 2rem;
  }
}
```

<p data-height="265" data-theme-id="0" data-slug-hash="xyaEep" data-default-tab="html,result" data-user="yutasuzuki" data-pen-title="擬似要素::first-letter" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/xyaEep/">擬似要素::first-letter</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### ::first-line
first-lineはblock要素の１行目に対してスタイルを変化させます。inline要素に対してはスタイルは変更されません。

```html
<p class='paragraph'>
  textextextextexttextextextext<br>
  texttextextextextexttextextextextext
</p>  
<span class='paragraph'>
  textextextextexttextextextext<br>
  texttextextextextexttextextextextext
</span>
```
```scss
.paragraph {
  color: #333;

  &::first-line {
    font-size: 2rem;
  }
}
```
<p data-height="265" data-theme-id="0" data-slug-hash="Jmabjv" data-default-tab="html,result" data-user="yutasuzuki" data-pen-title="擬似要素::first-line" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/Jmabjv/">擬似要素::first-line</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 擬似クラス

### :active
activeはボタンなどを押した時にスタイルを変化させます。

```html
<a class='anchor'>click!!</a>
```

```scss
.anchor {
  color: #007bff;
  font-size: 4rem;
  font-weight: bold;
  
  &:active {
    color: #0062cc;
  }
}
```
<p data-height="265" data-theme-id="0" data-slug-hash="XxxeyZ" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似クラス:active" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/XxxeyZ/">擬似クラス:active</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


### :checked
checkedはチェックボックスにチェックがついた状態にスタイルを変化させます。

```html
<input type='checkbox' id='foo'><label for='foo'>hoge</label>
```
```scss
input:checked + label {
  color: red;
}
```
<p data-height="265" data-theme-id="0" data-slug-hash="zmMwGo" data-default-tab="html,result" data-user="yutasuzuki" data-pen-title="擬似クラス:checked" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/zmMwGo/">擬似クラス:checked</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :default
defaultはチェックボックスなどでデフォルトでチェックが入っているもののスタイルを変更します。

```html
<input type='radio' name='foo' id='baz'><label for='baz'>baz</label>
<input type='radio' name='foo' id='bar' checked><label for='bar'>bar</label>
```
```scss
input:default + label {
  color: red;
  font-weight: bold;
  font-size: 4rem;
}
```

<p data-height="265" data-theme-id="0" data-slug-hash="gBQWRq" data-default-tab="html,result" data-user="yutasuzuki" data-pen-title="擬似クラス:default" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/gBQWRq/">擬似クラス:default</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :disabled
disabledはinput要素などが無効の時にスタイルを変更します。

```html
<input type='text' placeholder='名前' disabled>
```
```scss
input:disabled {
  background: #ccc;
}
```

<p data-height="265" data-theme-id="0" data-slug-hash="XxyRYa" data-default-tab="html,result" data-user="yutasuzuki" data-pen-title="擬似クラス:disabled" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/XxyRYa/">擬似クラス:disabled</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :empty
emptyは子要素を持たない要素のスタイルを変更します。

```html
<p></p>
<p>foo</p>
```

```scss
p {
  padding: 15px;
  
  &:empty {
    background-color: #e77;
  }
}
```

<p data-height="265" data-theme-id="0" data-slug-hash="MPzmRm" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似クラス:empty" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/MPzmRm/">擬似クラス:empty</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :enabled
enabledはdisabledとは逆で、入力可能なもののスタイルを変更します。

```html
<input type='text' placeholder='enabled'>
<input type='text' placeholder='disabled' disabled>
```
```scss
input {
  padding: 5px 10px;
 
  &:enabled {
    background-color: #cff;
  }
  
  &:disabled {
    background-color: #fcc;
  }
}
```

<p data-height="265" data-theme-id="0" data-slug-hash="pxQwmK" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似クラス:enabled" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/pxQwmK/">擬似クラス:enabled</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :first-child
first-childは兄弟要素の一番はじめの要素のスタイルを変化させます。

```html
<p>foofoofoofoofoofoo</p>
<p>barbarbarbarbarbarbarbar</p>

<div>
  <p>bazbazbazbazbazbazbazbazbazbaz</p>
</div>
```

```scss
p {
  &:first-child {
    color: #e33;
    background-color: #333;
    padding: 5px 10px;
  }
}
```
<p data-height="265" data-theme-id="0" data-slug-hash="JmeyKd" data-default-tab="html,result" data-user="yutasuzuki" data-pen-title="擬似クラス:first-child" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/JmeyKd/">擬似クラス:first-child</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :first-of-type
first-of-typeは兄弟要素のグループの中でその種類の最初の要素のスタイルを変化させます。

```html
<p>foofoofoofoofoofoo</p>
<p>barbarbarbarbarbarbarbar</p>

<div>
  <p>bazbazbazbazbazbazbazbazbazbaz</p>
  <p>foofoofoofoofoofoo</p>
  <p>barbarbarbarbarbarbarbar</p>
</div>
```
```scss
p:first-of-type {
  color: #009;
  font-weight: bold;
}
```

<p data-height="265" data-theme-id="0" data-slug-hash="EdOvva" data-default-tab="html,result" data-user="yutasuzuki" data-pen-title="擬似クラス:first-of-type" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/EdOvva/">擬似クラス:first-of-type</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :focus
focusはinputやtextareaなど入力要素があるものにフォーカスが当たった際にスタイルを変化させます。

```html
<input type='text' placeholder='focus'>
```
```scss
input {
  padding: 5px 10px;

  &:focus {
    background-color: #9f9;
  }
}

```
<p data-height="265" data-theme-id="0" data-slug-hash="PyxKaR" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似クラス:focus" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/PyxKaR/">擬似クラス:focus</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :focus-within
focus-withinは子や孫要素がフォーカスされた際にスタイルを変化させます。

```html
<section>
  <input type='text' placeholder='focus-within'>
</section>
```
```scss
section {
  padding: 15px;

  &:focus-within {
    background-color: #fcc;
    border: 1px #f99 solid;
  }
}
```
<p data-height="265" data-theme-id="0" data-slug-hash="vVQJqd" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似クラス:focus-within" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/vVQJqd/">擬似クラス:focus-within</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :hover
hoverはマウスが乗った時にスタイルが変化します。

```html
<a href="#">hover</a>
```
```scss
a:hover {
  color: red;
}
```

<p data-height="265" data-theme-id="0" data-slug-hash="qJQPdj" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似クラス:hover" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/qJQPdj/">擬似クラス:hover</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :in-range
in-rangeは指定された許容範囲内に入っている時にスタイルを変化させます。

```html
<input type='number' placeholder='1から10を入力してください' min='1' max='10' value='11'>
```
```scss
input {
  width: 160px;
  padding: 10px 15px;
  font-size: 2rem;

  &:in-range {
    background-color: #0e5;
  }
  
  &:out-of-range {
    background-color: #e66;
  }
}
```

<p data-height="265" data-theme-id="0" data-slug-hash="ReqLge" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似クラス:in-range" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/ReqLge/">擬似クラス:in-range</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


### :valid

```html
<input type='number' placeholder='必ず半角数字を入れて下さい' required>
```

```scss
input {
  width: 240px;
  padding: 5px 10px;

  &:valid {
    background-color: #dfd;
  }
}
```
<p data-height="265" data-theme-id="0" data-slug-hash="vVQWvL" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似クラス:valid" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/vVQWvL/">擬似クラス:valid</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


### :invalid

```html
<input type='number' placeholder='必ず半角数字を入れて下さい' required>
```

```scss
input {
  width: 240px;
  padding: 5px 10px;
  
  &:invalid {
    background-color: #fcc;
  }
}
```

<p data-height="265" data-theme-id="0" data-slug-hash="EdOwov" data-default-tab="result" data-user="yutasuzuki" data-pen-title="擬似クラス:invalid" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/EdOwov/">擬似クラス:invalid</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :any()
複数のclassや要素を指定することができます。

```html
<article>
  <p>ArticleArticleArticleArticleArticle</p>
</article>
<div class='foo'>
  <p>FooFooFooFooFooFoo</p>
</div>
<section>
  <p>SectionSectionSectionSectionSection</p>
</section>
```

```scss
:-webkit-any(article, .foo) p:hover {
  color: red;
  cursor: pointer;
}
```

<p data-height="265" data-theme-id="0" data-slug-hash="zmMEXp" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似クラス:any()" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/zmMEXp/">擬似クラス:any()</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :not()
指定された要素やクラス以外のもののスタイルを変化させます。

```html
<section>
  <p>ParagraphParagraphParagraph</p>
  <div>DivDivDivDivDivDivDivDiv</div>
  <span>SpanSpanSpanSpanSpanSpan</span>
</section>

<ul>
  <li>11111111</li>
  <li>22222222</li>
  <li>33333333</li>
</ul>
```

```scss
section > *:not(p) {
  color: #070;
}

ul > li:not(:last-child) {
  color: #700;
}
```
<p data-height="265" data-theme-id="0" data-slug-hash="rqQYVp" data-default-tab="html,result" data-user="yutasuzuki" data-pen-title="擬似クラス:not()" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/rqQYVp/">擬似クラス:not()</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :optional
optionalは任意入力項目のスタイルを変化させます。

```html
<input type='text' placeholder='optional'>
<input type='text' placeholder='required' required>
```
```scss
input {
  padding: 5px 10px;
 
  &:optional {
    border: 1px solid #0cc;
  }
  
  &:required {
    border: 1px solid #c00;
  }
}
```


<p data-height="265" data-theme-id="0" data-slug-hash="OBawvR" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似クラス:required" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/OBawvR/">擬似クラス:required</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### :required
requiredは必須項目のスタイルを変化させます。

```html
<input type='text' placeholder='optional'>
<input type='text' placeholder='required' required>
```
```scss
input {
  padding: 5px 10px;
 
  &:optional {
    border: 1px solid #0cc;
  }
  
  &:required {
    border: 1px solid #c00;
  }
}
```

<p data-height="265" data-theme-id="0" data-slug-hash="OBawvR" data-default-tab="css,result" data-user="yutasuzuki" data-pen-title="擬似クラス:required" class="codepen">See the Pen <a href="https://codepen.io/yutasuzuki/pen/OBawvR/">擬似クラス:required</a> by yutasuzuki (<a href="https://codepen.io/yutasuzuki">@yutasuzuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

















































































## まとめ
まとめてみると前から知っていれば、もっと効果的に使えそうだなーっていうのも結構あります。
今回これをやりなおそうと思ったきっかけは、後輩が`:not()`をうまく使っており自分の擬似クラスへの理解がまだまだ足りないと感じたからです。どうしても好きな分野でないと過去の遺産や知識で片付けてしまうので、世代が違う子は本当に刺激になります。