テック技報最新号へ →
CSS

ホバーで持ち上げるのはカード本体ではなく中の子要素にする(下端のチラつき防止)

.card:hover でカード自身を translate で上げると、下端付近でホバーが外れたり付いたりを繰り返すので、動かすのは内側の .inner にする。

@sanyampunia · 2026-10-27

どんな時に使う?

  • カード、ボタン、リスト項目などに「ホバーで少し浮く」演出を付けるとき。
  • ポインターをカードの下端に置くとガタガタ震える、というバグ報告が来たとき。

なぜチラつくのか

カード本体を 6px 上に動かすと、ホバー判定の領域(カードの箱)も一緒に 6px 上がる。ポインターが元の下端から 6px 以内にあると、領域の外に出てホバーが外れる → カードが元の位置に戻る → またポインターの下に来てホバーが付く…というループになり、下端 6px の帯で震え続ける。

ホバーを受ける要素(外側)は動かさず、見た目だけの子要素を動かせば、判定領域が変わらないのでループが起きない。

コード

html
<a class="card" href="…">
  <div class="inner">…中身…</div>
</a>
css
.card > .inner {
  transition: translate 200ms ease;
}

.card:hover > .inner,
.card:focus-visible > .inner {
  translate: 0 -6px;
}

影や背景も .inner 側に付けておくと、浮いた見た目が自然になる。外側の .card は透明な「当たり判定」の箱として残る。

注意点

  • translate はレイアウトを変えないが、ホバーの判定は動いた後の位置で行われる。だから判定を受ける外側の要素は動かさないのがポイント。
  • キーボード操作でも同じ演出を出すなら :focus-visible も併記する。
  • prefers-reduced-motion: reduce のときは移動をやめて影の変化だけにするなどの配慮を。
  • translate プロパティは全モダンブラウザ対応。

出典

X の元の投稿を開く