GODRICH
#cssアニメーション#ボタン#ローディング#トランジション#スクロール#ダッシュボード#実用ui#デザイントレンド

【コピペOK】CSS カード ホバー 効果9選

css カード ホバーとは、商品カードやブログ記事カードにマウスを乗せたりキーボードでフォーカスを移したりした瞬間だけ、画像が拡大したり隠れていた説明が現れたりする短い動きのことです。商品・記事カードにそのまま貼り付けられる9種類を、実際にブラウザで描画して動きを測定してからまとめました。

自動再生 · タイルを押すとその項目へ · すべて1つのzip

文字側の並びが気になる方は、同じfeedback柱の前後にあたるcss テキスト アニメーションとデコード演出もご覧ください。9個の css カード アニメーション は人気の高い順ではなく、カードを一枚じっくり見るときに視線と操作が実際にたどる順に並べました。まず画像が主役として大きくなり(01)、カーソルを置いた位置に応じてカード自体が傾き(02)、気になって見ていると裏面がめくれます(03)。続けてブラケット・バッジ・下線という3つの小さな合図で狙いを絞ったことを伝えたあと(04〜06)、少し止まると詳細パネルが横に現れ(07)、ガラス質の表面が光を受けたように濃くなり(08)、最後にリングが一周描かれて選択が確定します(09)。

番号 名前 何が動くか JS
01 画像ズーム+キャプションスライド 画像scale・キャプションtranslateY なし
02 ゾーン別3Dチルト カードrotateX・rotateY なし
03 裏面フリップ公開 カードrotateY(180deg) なし
04 コーナーブラケットフレーム ブラケットopacity・位置 なし
05 バッジの弾む登場 バッジscaleのオーバーシュート なし
06 CTA下線スイープ 下線scaleX なし
07 アンカー配置のミニパネル パネルopacity・位置 なし
08 グラスモーフィズムブラー backdrop-filter・影 なし
09 選択リングの描画 SVGstroke-dashoffset なし

01画像ズーム+キャプションスライド

画像が1.08倍まで広がる

カードにカーソルを乗せると内側の画像がゆっくり1.08倍まで拡大し、同時に下に隠れていたキャプションが上へスライドして重なります。

画像ズーム+キャプションスライド
新しいタブで開く

01 · 画像ズーム+キャプションスライド — 計測 累積面積 4.11% · 動いたフレーム 13/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

transform: scaletranslateYoverflow: hidden

画像が主役の場面に

旅行先や商品を紹介するカード、ブログのサムネイルカードに向いています。

.card__media {
  transform: scale(1);
  transition: transform $duration $easing;
}
.card__caption {
  transform: translateY(60%);
  opacity: 0;
  transition: transform $duration $easing, opacity $duration $easing;
}
.card:hover .card__media,
.card:focus-visible .card__media { transform: scale(1.08); }
.card:hover .card__caption,
.card:focus-visible .card__caption { transform: translateY(0); opacity: 1; }

02ゾーン別3Dチルト(CSSのみ)

ゾーンに応じて傾く

カードを4分割した見えないゾーンのうち、カーソルが乗ったゾーンに応じて:has()セレクタが異なる傾きの値を選び、座標を読み取るJSなしでもその方向へ傾きます。

ゾーン別3Dチルト(CSSのみ)
新しいタブで開く

02 · ゾーン別3Dチルト(CSSのみ) — 計測 累積面積 2.811% · 動いたフレーム 16/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

:has() 선택자rotateX/rotateYperspective

JSなしでチルトを出す

JSに頼らずチルトを実装したい機能紹介カードやポートフォリオカードに向いています。

.card__inner {
  transform-style: preserve-3d;
  transition: transform $duration $easing;
}
.card:has(.zone--tl:hover) .card__inner { transform: rotateX(8deg) rotateY(-10deg); }
.card:has(.zone--tr:hover) .card__inner { transform: rotateX(8deg) rotateY(10deg); }
.card:has(.zone--bl:hover) .card__inner { transform: rotateX(-8deg) rotateY(-10deg); }
.card:has(.zone--br:hover) .card__inner { transform: rotateX(-8deg) rotateY(10deg); }
.card:focus-visible .card__inner { transform: rotateX(8deg) rotateY(-10deg); }

03裏面フリップ公開

カード ホバー アニメーション で裏面を見せる

カードにカーソルを乗せるとY軸を軸に180度回転して裏面が現れ、表面には収まらなかった詳細説明やボタンが姿を見せます。

裏面フリップ公開
新しいタブで開く

03 · 裏面フリップ公開 — 計測 累積面積 13.908% · 動いたフレーム 13/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

perspectiverotateY(180deg)backface-visibility

情報が二層あるカードに

料金カードの細かい条件やチームメンバー紹介のように、情報が二層あるカードに向いています。

.card__flip {
  transform-style: preserve-3d;
  transition: transform $duration $easing;
}
.card__face--back {
  backface-visibility: hidden;
  transform: rotateY(180deg);
}
.card:hover .card__flip,
.card:focus-visible .card__flip {
  transform: rotateY(180deg);
}

04コーナーブラケットフレーム

四隅のブラケットが伸びる

カードの四隅にたたまれた短いブラケットが普段は内側に小さく隠れていて、ホバーすると縁のほうへ伸びてカメラのフォーカス枠のようにカードを囲みます。

コーナーブラケットフレーム
新しいタブで開く

04 · コーナーブラケットフレーム — 計測 累積面積 0.773% · 動いたフレーム 13/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

transform: scaleopacity.corner 4개

1枚を選ばせたいとき

何枚も並ぶギャラリーグリッドで1枚を選ばせたいときに向いています。

.corner {
  opacity: 0;
  transition: transform $duration $easing, opacity $duration $easing;
}
.corner--tl { transform: translate($sp-2, $sp-2); }
.card:hover .corner,
.card:focus-visible .corner {
  opacity: 1;
  transform: translate(0, 0);
}

05バッジの弾む登場

弾んでから収まる

普段は隠れている「NEW」や「SALE」のバッジが、ホバーすると弾むイージングで一度大きくなってからわずかに縮んで収まります。

バッジの弾む登場
新しいタブで開く

05 · バッジの弾む登場 — 計測 累積面積 0.917% · 動いたフレーム 15/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

@keyframescubic-bezier 오버슈트transform: scale

もう一押し目を引く

セール商品や新着アイテムのように、もう一押し目を引きたいカードで使います。

.badge {
  transform: scale(0);
  transition: transform $duration $ease-pop;
}
.card:hover .badge,
.card:focus-visible .badge {
  transform: scale(1);
}

06CTA下線スイープ(親ホバー)

どこに乗せても下線が引かれる

「詳しく見る」の文字そのものではなくカードのどこにカーソルを乗せても、親の.card:hoverが子の下線を選んで左から右へ描きます。

CTA下線スイープ(親ホバー)
新しいタブで開く

06 · CTA下線スイープ(親ホバー) — 計測 累積面積 0.082% · 動いたフレーム 13/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

부모 :hover → 자식 선택transform: scaleXtransform-origin

カード全体が合図になる

ブログカードの続きを読むリンクやランディングページのCTAに合います。

.cta__underline {
  transform: scaleX(0);
  transform-origin: left;
  transition: transform $duration $easing;
}
.card:hover .cta__underline,
.card:focus-visible .cta__underline {
  transform: scaleX(1);
}

07アンカー配置のミニパネル

パネルが自動で吸い付く

カードにanchor-nameを付け、CSSアンカーポジショニングでその下に小さな情報パネルをつなぐと、ホバー時にパネルがカードへ自動で吸い付いて現れます。

アンカー配置のミニパネル
新しいタブで開く

07 · アンカー配置のミニパネル — 計測 累積面積 2.903% · 動いたフレーム 12/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

anchor-nameposition-anchorposition-area

在庫やスペックを先に

在庫やスペックを先に見せたい商品一覧に向いています。

.card { anchor-name: --c7; }
.panel {
  position: absolute;
  position-anchor: --c7;
  position-area: block-end;
  position-try-fallbacks: flip-block;
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity $duration $easing, transform $duration $easing;
}
.card:hover ~ .panel,
.card:focus-visible ~ .panel {
  opacity: 1;
  transform: translateY(0);
}

08グラスモーフィズムブラー

ホバーでガラスが明るくなる

半透明のカード背景にbackdrop-filter: blur()がかかっていて、ホバーするとぼかしと彩度がさらに深まり、光を受けたガラス面のように表情が明るくなります。

グラスモーフィズムブラー
新しいタブで開く

08 · グラスモーフィズムブラー — 計測 累積面積 12.276% · 動いたフレーム 12/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

backdrop-filter: blurrgba 배경saturate()

ダーク背景の上で

ダーク背景の上のプレミアムカードやダッシュボードウィジェットに向いています。

.card {
  background: rgba(255, 255, 255, .14);
  backdrop-filter: blur(6px) saturate(120%);
  transition: backdrop-filter $duration $easing, transform $duration $easing;
}
.card:hover,
.card:focus-visible {
  backdrop-filter: blur(14px) saturate(160%);
  background: rgba(255, 255, 255, .26);
  transform: translateY(-4px);
}

09選択リングの描画

リングが一周描かれる

選べるカードにホバーしたり選択したりすると、縁を囲んだSVGのリングがstroke-dashoffsetで一周ぶん描かれて「選択済み」だと知らせます。

選択リングの描画
新しいタブで開く

09 · 選択リングの描画 — 計測 累積面積 1.335% · 動いたフレーム 11/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

SVG stroke-dashoffsetstroke-dasharray:focus-visible

選択を締めくくる動き

プラン選択やラジオ形式のカード選択UIを締めくくる動きです。

.ring__rect {
  fill: none;
  stroke-dasharray: 500;
  stroke-dashoffset: 500;
  transition: stroke-dashoffset $duration $easing;
}
.card:hover .ring__rect,
.card:focus-visible .ring__rect {
  stroke-dashoffset: 0;
}

どこで壊れるか — 落とし穴ひとつ

強度0.0が出た理由

08番のグラスモーフィズムを最初にレンダリングしたとき、測定値が明らかにおかしいものでした。カード全体のぼかしが目には見えて変わっているのに、強度平均は0.0、動いたフレームは23コマ中0コマと出たのです。この計測はブラウザで実際に再生するのではなく、Web Animations APIでcurrentTimeをコマごとに強制的に動かしてスクリーンショットを撮る仕組みで、ヘッドレスChromeはbackdrop-filterだけが変わる合成レイヤーをこの方式では毎コマ塗り直してくれないようでした。

transformをひとつ足した

同じkeyframesの中にtransform: translateY(-4px)をひとつ足し、ぼかしと一緒にカードがわずかに浮き上がるようにしただけで、同じ条件で強度平均53.9・動いたフレーム12コマという正常な値になりました。圧縮ファイルの合言葉はtvyct8zbで、この検証記録が残っていなければ08番は「動いていないカード」のまま残っていたはずです。ぼかしや彩度のように合成レイヤーだけにかかる値は、transformやopacityを添えてはじめて計測でも人の目でもはっきり動いて見えます。質感を厚く重ねるスキューモーフィズムデザインの質感パーツも、影と光沢だけを動かすと08と同じように計測から消えてしまいます。

アクセシビリティ

遷移を止めても最終状態は残る

OSで「動きを減らす」設定を有効にしている方には、9個すべてでprefers-reduced-motion: reduceのときにトランジションと自動アニメーションを止めます。01・03・04・05・06・08・09はホバーやフォーカスが当たった瞬間、アニメーションなしでそのまま最終の見た目(画像が広がりきった・裏返った・ブラケットが点いた・バッジが座った・下線が引かれた・ぼかしが濃いまま固定・リングが一周描かれた状態)に切り替わるので、情報が欠けることはありません。02は傾きが遷移なしでそのまま適用され、07はパネルが遷移なしで現れたり消えたりします。

三つの状態を一つの規則に

マウスを乗せたときだけでなく、キーボードでフォーカスが移ったときや指で押したときも同じ最終状態になるよう、:hoverと:focus-visible(一部は:activeも)をひとつの規則にまとめています。

関連リンク

カードのホバー表現をもっと見たい方はカードホバーアニメーション9選、ガラス質の質感だけをじっくり見たい方はグラスモーフィズム効果9選もあわせてどうぞ。

FAQ

02のゾーン別チルトは:has()に対応していないブラウザではどうなりますか?

:has()に対応していないブラウザではそのセレクタを含む規則自体がマッチしないため、カードは平らなまま止まります。レイアウトが崩れたりエラーが出たりしない安全な劣化で、最新のChrome・Safari・Firefoxはすでに対応しています。

07のアンカー配置パネルはすべてのブラウザで同じように表示されますか?

Chrome・Edgeでは表示されますが、この記事を書いている時点のFirefox・SafariはCSSアンカーポジショニングに対応しておらず、パネル自体が現れません。対応していないブラウザでもカード本体(画像・タイトル・価格)は普通に表示されるので、肝心な情報が欠けることはありません。

css カードデザイン の選択リングをReact版で使うときstateはどう管理しますか?

SelectRingCardコンポーネントは専用のstateを持たず、CSSの:hover・:focus-visible・:activeだけでリングを描きます。実際のフォーム選択のようにクリックしたあとも選択状態を保ちたい場合は、親コンポーネント側でaria-pressedと専用クラスをもうひとつ重ねて管理してください。カーソルの座標そのものを読み取って反応させる手法はマウス カーソル エフェクト 9選で別に扱っています。

解凍パスワードを入力してください

パスワードはこの記事の本文の中にあります。読み進めると出てきます。