疑似クラス+要素連結をマスターする。疑似要素もあるよ。

#はじめに

CSSを使っていて、案外つまづきやすいポイントなのでまとめてみた。
ここで例に取り上げるのはhoverのみだが、:checkedや:active、:visitedなどでも同様に作用するぞ。



#用例
こんな感じのチェックボックス、作ろうとした、あるいは作った人もそれなりにいることだろう。
が、コレ、細かいポイントを見落として作ったのでは動かない場合がある。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="css,result" data-user="yomogenium" data-slug-hash="BaozbYa" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="BaozbYa">
  <span>See the Pen <a href="https://codepen.io/yomogenium/pen/BaozbYa">
  BaozbYa</a> by Yomogenium (<a href="https://codepen.io/yomogenium">@yomogenium</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


ざっくり言ってしまえば、そのポイントは１つ。**疑似クラスと要素連結の組み合わせ**だ。
扱えるようになるとめちゃくちゃ便利なのだが、こいつにはクセが存在するのである。


#疑似クラスを普通に利用する

```html:html
<style>
/* patern0 */

.hovered{
  display: inline-block;
  background: white;
  border-radius: 10px;
  padding: 1em 2em;
}

.hovered:hover{
background: red;
}
</style>

<div class="hovered"></div>
```




#アクションの作動時にほかの要素を動かしたい場合（疑似クラス+要素連結）

###動かしたい要素が直下（すぐ下）の子要素にある

```html:html

<style>
/* patern1 */
.hovered{
  display: inline-block;
  background: white;
  border-radius: 10px;
  padding: 1em 2em;
}

.acttarget{
    color: white;
    background: #444040;
    display: inline-block;
    padding: 0.5em 1em;
}

.hovered:hover > .acttarget{
  color: red;
}

</style>

<div class="hovered">
<p class="acttarget">action!</p>
</div>

```

###動かしたい要素が子要素にある（直下でない場合でも可）

```html:html
<style>
/* patern2 */

.hovered{
  display: inline-block;
  background: white;
  border-radius: 10px;
  padding: 1em 2em;
}

.acttarget{
    color: white;
    background: #444040;
    display: inline-block;
    padding: 0.5em 1em;
}
.hovered:hover .acttarget{
  color: red;
}
</style>

<div class="hovered">
  <div>
    <p class="acttarget">action!</p>
    </div>
</div>

```

###動かしたい要素が同じ階層で、ひとつ後ろにある

```html:html
<style>
/* patern3 */

.hovered{
  display: inline-block;
  background: white;
  border-radius: 10px;
  padding: 1em 2em;
}
.acttarget{
    color: white;
    background: #444040;
    display: inline-block;
    padding: 0.5em 1em;
}
.hovered:hover ~ .acttarget{
  color: red;
}
</style>

<div class="hovered"></div>
<p class="acttarget">action!</p>
<div class="hovered">関係ない要素</div>
```

※ここに出てきている「~」は「間接セレクタ」。
隣接セレクタは、
「変化させたい要素が、:hoverなどの**疑似クラスをつけた要素よりも後ろ**にある」
という条件を満たさないと適用されないので注意しよう。
例として、一つ目のhoveredにカーソルを載せた場合は発動するが、二つ目にかざしても何も起こらない。


```html:html
<style>
/* patern4 */

.hovered{
  display: inline-block;
  background: white;
  border-radius: 10px;
  padding: 1em 2em;
}
.acttarget{
    color: white;
    background: #444040;
    display: inline-block;
    padding: 0.5em 1em;
}
.hovered:hover + .acttarget{
  color: red;
}
</style>

<div class="hovered"></div>
<div class="hovered"></div>
<p class="acttarget">action!</p>
<div class="hovered">関係ない要素</div>
```

※ここに出てきている「+」は「隣接セレクタ」と呼ぶ。
隣接セレクタは、
「変化させたい要素が、:hoverなどの疑似クラスをつけた要素の**すぐ後**にある」
という条件を満たさないと適用されない。
上の例でいえば、一つ目のhoveredにカーソルをかざしても反応しない（「~」なら反応する）。

また、下に挙げる例では反応すらしない。

```html:html
<style>
/* patern5--failed */

.hovered{
  display: inline-block;
  background: white;
  border-radius: 10px;
  padding: 1em 2em;
}

.acttarget{
    color: white;
    background: #444040;
    display: inline-block;
    padding: 0.5em 1em;
}
.hovered:hover + .acttarget{
  color: red;
}
</style>

<!-- 失敗例。どちらのhoveredにマウスカーソルをかざしても反応しません。 -->
<div class="hovered">
</div>

<p>関係ないターゲット</p>
<p class="acttarget">action!</p>

<div class="hovered">
関係ない要素
</div>

```


###ある要素が条件を満たしたとき、その要素についている疑似要素を変化させたい
疑似要素は、基本的にセレクタで分けたり繋げたりはせず、疑似クラスの後ろにつなげて使う、と覚えておこう。

```html:html
<style>
/* patern6 */

.hovered{
  display: inline-block;
  background: white;
  border-radius: 10px;
  padding: 1em 2em;
}
.hovered:before{
  display: block;
  content: '';
  background-color: black;
  width: 8px;
  height:8px;
  transform: rotate(30deg);
}
.hovered:hover:before{
  background: red;
}
</style>

<div class="hovered"></div>
```


もちろん、以下のようにbefore、afterに同時に変化を加えてやることも可能だ。

```html:html

<style>
/* patern7 */

.hovered{
  display: inline-block;
  background: white;
  border-radius: 10px;
  padding: 1em 2em;
  position: relative;
}
.hovered:before{
  display: block;
  content: '';
  background-color: black;
  width: 8px;
  height:8px;
  transform: rotate(30deg);
  position: absolute;
  top:8px;
  left: 6px;
}
.hovered:after{
  display: block;
  content: '';
  background-color: black;
  width: 6px;
  height:6px;
  border-radius: 50%;
  position: absolute;
  top: 10px;
  right: 8px;  
  
}

.hovered:hover{
  background: black;
}
.hovered:hover:before{
  background: red;
}
.hovered:hover:after{
  background: #55c500;
}
</style>

<div class="hovered"></div>

```