【CSS】疑似要素をhoverで表示したい時の正解

技術

「アイコンや背景をCSSの疑似要素で作ったけれど、マウスを乗せた時に色や画像を変えたい。でも、::before:hover と書いても動かない……。」

実は、疑似要素に直接ホバーイベントを当てることはできません。 なぜなら、疑似要素はHTML要素として存在しているわけではないからです。

今回は、疑似要素をホバーで変化させるための「正しい書き方」と、実務で役立つ注意点を解説します。

1. 【結論】「親要素がホバーされたら疑似要素を変える」

疑似要素をホバーさせたい時は、「親要素(実体のある要素)にマウスが乗った時、その中の疑似要素のプロパティを変更する」という指定順序にするのが正解です。

❌ 間違った書き方

疑似要素自体にホバーをつけようとしても反応しません。

.item::before:hover {
  background-image: url(images/item2.png); /* 動きません */
}

✅ 正しい書き方

.item にホバーしたら、その ::before を変える」と記述します。

/* SCSS形式 */
.item {
  position: relative;
}

.item::before {
  content: "";
  background-image: url(images/item.png);
}
 
/* 親要素(item)にホバーした時の指定 */
.item:hover::before {
   background-image: url(images/item2.png);
}

2. 実務で役立つ3つのテクニック

① アニメーションで「ふわっ」とさせる

画像をパッと切り替えるだけでなく、transition を使うとユーザビリティが向上します。この時、transition はhover側ではなく、元の疑似要素側(初期状態)に記述するのがコツです。

.item::before {
  content: "";
  transition: opacity 0.3s ease, background-image 0.3s ease;
  opacity: 0.8;
}

.item:hover::before {
  opacity: 1;
  background-image: url(images/item2.png);
}

② 疑似要素の場所だけで反応させたい場合

「親要素全体ではなく、疑似要素(アイコンなど)がある場所を触った時だけ反応させたい」という場合は、親要素側のポインターイベントを制御します。
※ただし、親要素内の他のテキストなども反応しなくなるため、レイアウトに応じて使い分けが必要です。

.item:hover::before {
  pointer-events: none;
}

.item::before {
  pointer-events: auto;
}

③ z-indexの重なりに注意

疑似要素を absolute で配置する場合、親要素内のテキストが隠れてしまうことがあります。z-index: -1; などで背面に回すと、今度はホバーが反応しなくなるケースがあるため、重なり順の設計は慎重に行いましょう。

まとめ

  • ・ターゲットは親要素(.item)にする
  • ・変化させるのは疑似要素(::before)にする
  • ・親子関係を崩さない

これさえ守れば、CSSだけで表現力豊かなインタラクションが実装できます。ぜひ活用してみてください!