はじめに
CSSを使っていて、案外つまづきやすいポイントなのでまとめてみた。
ここで例に取り上げるのはhoverのみだが、:checkedや:active、:visitedなどでも同様に作用するぞ。
用例
こんな感じのチェックボックス、作ろうとした、あるいは作った人もそれなりにいることだろう。
が、コレ、細かいポイントを見落として作ったのでは動かない場合がある。
See the Pen BaozbYa by Yomogenium (@yomogenium) on CodePen.
ざっくり言ってしまえば、そのポイントは1つ。疑似クラスと要素連結の組み合わせだ。
扱えるようになるとめちゃくちゃ便利なのだが、こいつにはクセが存在するのである。
疑似クラスを普通に利用する
<style>
/* patern0 */
.hovered{
display: inline-block;
background: white;
border-radius: 10px;
padding: 1em 2em;
}
.hovered:hover{
background: red;
}
</style>
<div class="hovered"></div>
アクションの作動時にほかの要素を動かしたい場合(疑似クラス+要素連結)
動かしたい要素が直下(すぐ下)の子要素にある
<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>
動かしたい要素が子要素にある(直下でない場合でも可)
<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>
動かしたい要素が同じ階層で、ひとつ後ろにある
<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にカーソルを載せた場合は発動するが、二つ目にかざしても何も起こらない。
<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にカーソルをかざしても反応しない(「~」なら反応する)。
また、下に挙げる例では反応すらしない。
<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>
ある要素が条件を満たしたとき、その要素についている疑似要素を変化させたい
疑似要素は、基本的にセレクタで分けたり繋げたりはせず、疑似クラスの後ろにつなげて使う、と覚えておこう。
<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に同時に変化を加えてやることも可能だ。
<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>