Menu

CSS ホバー: :hover、:active、リンクの色の状態

:hover 疑似クラスは、ポインターが要素の上にある間だけ要素をスタイルします。ボタンやカードのホバー効果、なめらかなトランジション、:link、:visited、:hover、:active を正しい順番で書くリンクの色、タッチスクリーンでのホバーを解説します。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

:hover の仕組み

:hover は、マウスポインターが要素の上にある間、その要素に一致する疑似クラスです。任意のセレクタに付けて、ホバー状態のスタイルを書きます:

変わるのは :hover ルールの宣言だけで、それ以外は .btn から引き継がれます。ポインターが離れると、要素は通常のスタイルに戻ります。

transition でなめらかなホバー効果

通常の ルール (:hover ルールではなく) に transition を追加しない限り、ホバーの変化は一瞬で切り替わります。通常のルールに書けば、入るときも出るときもアニメーションします:

アニメーションさせるのにいちばん軽いプロパティは transform と opacity です。周りの要素を動かしません。width、height、margin をアニメーションさせると、フレームごとにページのリフローが起きます。所要時間、遅延、イージングは CSS transition のページ で解説しています。

リンクの色: :link、:visited、:hover、:active

リンクには昔からの 4 つの状態と、キーボードフォーカスがあります。ルールの順番が重要です:

疑似クラス適用される条件
:linkまだ訪問していないリンク
:visitedURL がブラウザの履歴にある
:hoverポインターが上にある
:active押されている
:focus-visibleキーボードでフォーカスされている

これらはすべて詳細度が同じなので、2 つが一致したときは後のルールが勝ちます。訪問済みのリンクにホバーすると :visited と :hover の両方に一致し、:visited が最後にあるとホバーの色は表示されません。安全な順番は Link、Visited、Hover、Active (LVHA) です:

ページが閲覧履歴を読み取れないよう、ブラウザは :visited で変更できるものを制限しています。効くのは色に関係するプロパティ (color、background-color、border-color、outline-color など少数) だけで、スクリプトからは常に未訪問の値が見えます。

:active: 押されている状態

:active は要素が押されている間に一致します。少し動かすだけで、ボタンに押した手応えが生まれます:

親要素のホバーで子要素をスタイルする

ホバー状態は、ポインターの下にある要素とそのすべての祖先に属します。そのため .card:hover .title は、カードのどこかにホバーしたときにタイトルをスタイルします。同じ考え方で、隠れた要素を表示することもできます:

:focus-within の行は重要です。これがないと、Tab キーで Delete ボタンに移動したキーボード利用者は、見えないボタンを押すことになります。ホバーで表示する仕組みには、必ずフォーカスのルールを組み合わせましょう。

タッチスクリーンでのホバー

スマートフォンやタブレットには、要素の上に置いたままにできるポインターがありません。ほとんどのモバイルブラウザは最初のタップで :hover を適用し、別の場所をタップするまで維持するため、ホバーのスタイルが残ったままに見えることがあります。次の 2 つのルールで対処できます:

  • コンテンツにたどり着く唯一の手段を :hover の後ろに置かない。ホバーで開くメニューは、クリックでも開くようにします。
  • 純粋に装飾的なホバー効果は、本物のホバーができる端末かを確認するメディアクエリで囲みます:
@media (hover: hover) {
  .card:hover { transform: translateY(-4px); }
}

よくある間違い

  • コロンの前にスペースを入れる。 .btn :hover は「.btn の中でホバーされた要素」という意味です。.btn:hover と書きましょう。
  • :hover ルールにだけ transition を書く。 入るときはアニメーションしますが、出るときはパッと戻ります。通常のルールに書きましょう。
  • リンクの順番を間違える。 :link、:visited、:hover、:active の順を守ります。
  • ホバーだけでフォーカスのスタイルがない。 キーボード利用者は :hover を発生させません。操作できる要素には :focus-visible のスタイルも付けましょう。
  • 別の要素に覆われた要素へのホバー。 見えないオーバーレイ (よくあるのは absolute の疑似要素) がポインターを受け取ってしまうことがあります。オーバーレイに pointer-events: none を指定すれば直ります。

よくある質問

CSS でホバー効果を付けるには?

セレクタの後に :hover を付けたルールを書きます: .btn:hover { background: #1d4ed8; }。ポインターが要素の上にある間、宣言が適用されます。変化をアニメーションにするには、通常のルールに transition: background 0.2s; を追加します。

:hover と :active の違いは何ですか?

:hover はポインターが要素の上にある間に適用されます。:active は要素が押されている間、つまりマウスボタンを押してから離すまでに適用されます。押されているボタンは、ふつう hover と active の両方の状態にあります。

リンクの疑似クラスはどの順番で書けばいいですか?

:link、:visited、:hover、:active の順です (LVHA、英語では "LoVe HAte" と覚えます)。詳細度が同じなので後のルールが勝ちます。ほかの順番では、visited や hover のスタイルが hover や active のスタイルを隠してしまうことがあります。

CSS でリンクの色を変えるには?

a 要素をスタイルします: a { color: #2563eb; }。ほかの状態には a:visited { color: #7c3aed; } と a:hover { color: #1d4ed8; } を書きます。a に color を指定すれば、未訪問と訪問済みの両方のリンクに効きます。

スマホでも hover は効きますか?

タッチスクリーンには、要素の上に置いたままにできるポインターがありません。ほとんどのモバイルブラウザはタップ時に :hover を適用し、別の場所をタップするまで維持するため、ホバーのスタイルが残ったままになることがあります。ホバーだけの効果は @media (hover: hover) で囲み、大事なコンテンツをホバーの後ろに隠さないでください。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める