カードがふわっと浮く ホバーの動き

通称:ホバーリフトHover Lift

見本のカードにマウスを重ねてください。Tab キーで選んでも同じ姿になります。

マウスを重ねると、カードが数px持ち上がり、下の影が少し濃くなります。一覧のカードが押せるものだと、触る前に伝わります。

自分のサイトの中身で、この形を作らせる指示文です。最初の「サイトの情報」を書き換えてから渡します。今あるページを直させるときは、その HTML を貼ります。

この形で作る
# 動かすもの(ここを書き換える)
- 動かす要素:〈例:各セクションの見出しとカード、商品の写真〉
- 今あるページ:〈今のページに付けるなら、その HTML と CSS を貼る。新しく作るなら空ける〉

# 動きの呼び名
一般に「ホバーリフト」(Hover Lift)と呼ばれる動きです。

# 作ってほしい動き
Hover Lift(カードがふわっと浮く)。マウスを重ねると、カードが 4px 持ち上がり、下の影が少し濃くなる。離すと元へ戻る。

# 動き
- きっかけ:カードにマウスを重ねたとき。キーボードで選んだとき(:focus-visible)も同じ姿にする
- 浮く:transform: translateY(0) から translateY(-4px) へ
- 影:濃い影(0 12px 24px rgba(15, 23, 42, 0.16))を ::after に置き、opacity 0 → 1 で出す。box-shadow の値そのものは動かさない
- 時間:0.2秒。速さの変わり方は cubic-bezier(0.22, 1, 0.36, 1)(すっと止まる)。離したときも同じ時間で戻る

# 付ける場所
- お知らせや施工例など、押すと詳しいページへ進むカードの一覧

# 守ってほしいこと
- :hover の指定は @media (hover: hover) の中にだけ書く(スマホでタップしたあと、浮いたまま残らないように)
- カード全体を1つの a 要素にし、Tab キーで届くようにする。:focus-visible では、浮く・影に加えて focus の輪も出す
- 浮くのは 8px まで。それより大きいと、カードが跳ねて見える
- 動きを控える設定では浮かせず、影が濃くなる変化だけを残す

# 軽さと配慮(どの動きでも守る)
- 動かすのは transform と opacity だけにする(top・left・width・height・margin は動かさない)
- 動きを控える設定(prefers-reduced-motion: reduce)のときは動かさず、最後の状態で表示する
- 画面に入ったかは IntersectionObserver で見る。scroll イベントで毎回位置を測らない
- JavaScript が動かない環境でも中身が見えるようにする(最初に隠す指定は、JavaScript が付ける class の下に書く)
- will-change を付けるなら動いている間だけにする

# 出力
- 足す CSS と JavaScript を分けて出す。ライブラリは使わない
- 時間・距離・速さの変わり方は CSS 変数にまとめ、あとから変えやすくする
- 今あるページを渡したときは、HTML に足す class や属性だけを書き、ほかの見た目は変えない

カード・写真・ボタン・メニューの文字に、マウスを重ねたときの動きを6種類の型に分け、AIへの指示文・マウスで試せる見本・コードを載せています。見本の下で量や時間を変えると、指示文とコードも同じものに変わります。

ホバーの動きはどの型を選ぶか

ホバーの動きは、マウスを重ねたところが押せるものだと、押す前に伝えるための演出です。動きの量は小さく、時間は短くするほど、上品に見えます。形の型(カードや写真をどう並べるか)は UIパターン集にあり、ここでは動き方だけを扱います。

こんなとき 向いている動き 形の型(UIパターン集)
一覧のカードが押せるものだと、触る前に伝えたいカードがふわっと浮く(ホバーリフト)お知らせ(カード型)
施工例や作品の写真を、並びを崩さずに目立たせたい枠の中で画像が少し大きくなる(ホバーズーム)ギャラリー(グリッド型)
申し込みのボタンに、触る前の手ごたえを付けたいボタンがカーソルに吸い寄せられる(マグネティックボタン)CTA
作品や商品を、手に取ったような奥行きで見せたいカードがカーソルの向きに傾く(3Dチルト)ギャラリー・お知らせ(カード型)
ページで1つだけのボタンに、さりげなく目を留めてほしい光の帯がすっと横切る(シャインエフェクト)CTA(セクション末尾型)
メニューの文字で、どこを指しているかを示したい下線が左から伸びる(アンダーラインアニメーション)ヘッダー(横並び型)

どの型でも守ること

  1. マウスがある画面でだけ動かす。:hover の指定は @media (hover: hover) の中に書きます。指で触る画面では、タップしたあとに浮いたまま・大きいまま残ることがあるためです。
  2. キーボードで選んだときも同じように知らせる。:focus-visible にも同じ見た目を書きます。マウスを使わない人にも、どこを選んでいるかが伝わります。
  3. 動きは小さく、短くする。浮くのは数px、大きくするのは 1.08倍くらい、傾きは 10度まで、時間は 0.2〜0.4秒が目安です(光の帯だけは 0.6〜0.8秒)。
  4. 動かすのは transform と opacity だけ。影は濃い影を別の層に描いて opacity で出し入れし、吸い寄せ・傾きは requestAnimationFrame で1フレームに1回だけ書き換えます。
  5. 動きを控える設定の人には、色や影の変化だけを残す。@media (prefers-reduced-motion: reduce) で動きを外しても、押せることは色や影で伝わります。見本の「動きを控える設定で見る」で確かめられます。

よくある質問 (FAQ)

ここのコードでは、スマホでは動きません。指で触る画面では、タップすると :hover の状態になり、別の場所を触るまで浮いたまま残ることがあります。そのため :hover の指定を @media (hover: hover) の中に書き、マウスがある画面でだけ動かしています。スマホで押した手ごたえを付けたいときは、部品の動きの「ボタンが押し込まれる」のような :active の動きを使います。

box-shadow を動かすと、動いている間ずっと影を描き直すからです。カードが多い一覧では、かくつく原因になります。濃い影を描いた層を ::after に重ねておき、その opacity だけを変えると、ブラウザは描き直さずに重ね方を変えるだけで済みます。

マウスの動きのイベントは、画面の描き直しより多く届くことがあるからです。届くたびに書き換えると、1フレームに何度も計算が走ります。イベントでは位置を覚えるだけにして、requestAnimationFrame の中で1回だけ CSS 変数を書き換えると、描き直しの回数に合わせて動きます。

動きの量と、マウスを使わない人への配慮です。「ホバーでふわっと」だけだと、大きく動きすぎる作りや、スマホで浮いたまま残る作り、キーボードでは何も起きない作りになりがちです。ここの指示文は、量(px・倍率・角度)と時間、@media (hover: hover)・:focus-visible の扱いを書き、Hover Lift のような英語の一般名も添えています。