GODRICH

CSS アニメーション バウンス 9選・一行でコピペOK

ボタンやバッジが、ただ表示されるのではなくふわっと浮いたり、ぽよんと弾んだり、ぷるぷる震えたりする動きを見たことはありませんか。この記事はそんな「css アニメーション バウンス」の実例を、まんが的な擬音語(ふわふわ・ぽよん・ぷるぷるなど)の名前で9つ集めたものです。

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

9つはひらがな順ではなく、ひとつの要素が画面の中でたどる役割の順番に並べました。まず存在を知らせ(01)、押したくさせ(02〜03)、そばで静かに息をし(04〜05)、リズムで手招きし(06)、背景を彩り(07)、選ばれたことを祝い(08)、最後に次の画面へ滑り込みます(09)。まず下の表でduration とトリガーだけ見渡してから、各項目のコードを開いてください。

クラス 動くプロパティ 秒数 トリガー
.o-float translateY・rotate 2.8s 常時
.o-poyon scale 550ms ホバー・フォーカス
.o-puru scaleX・scaleY 900ms 常時
.o-yura rotate 2.4s 常時
.o-kuru rotate 1.6s 常時
.o-pyon translateY・scaleY 900ms 常時
.o-gunya border-radius 3.2s 常時
.o-kira opacity・scale 1.8s 常時
.o-nuru translateX・scale 700ms ホバー・フォーカス

01ふわふわ浮く

.o-floatをひとつ付けるだけで、要素はtranslateYと弱いrotateを2.8秒かけて上下に行き来し、呼吸しているように見えます。マウスを乗せなくても常に動くので、新着バッジやオンボーディングの案内矢印のように、放っておいても目に留まってほしい要素に向いています。

translateYrotate 3deg2.8s
$duration: 2.8s;
$easing: ease-in-out;
$color: $subject-blue;

.o-float {
  animation: o-float $duration $easing infinite;
}

@keyframes o-float {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-14px) rotate(-3deg); }
}

02ぽよんとバウンス

.o-poyonはマウスを乗せるかキーボードでフォーカスすると、scaleが一度沈んでから大きく跳ね返るelasticイージングで550ms、1回だけ動きます。カート追加ボタンやいいねボタンのように、押した実感を先に伝えたい場面に使います。

scale overshootelastic550ms
$duration: 550ms;
$easing: cubic-bezier(.34, 1.56, .64, 1);
$color: $subject-cream;

.btn.o-poyon:hover,
.btn.o-poyon:focus-visible { animation: o-poyon $duration $easing 1; }

@keyframes o-poyon {
  0%   { transform: scale(1); }
  30%  { transform: scale(.88); }
  55%  { transform: scale(1.16); }
  75%  { transform: scale(.95); }
  100% { transform: scale(1); }
}

03ぷるぷるジェリー

.o-puruはscaleXとscaleYをごくわずかに反対方向へずらしながら900msで繰り返し、お気に入りのハートアイコンがタップを誘うように震え続けます。常時アニメーションなので、待機中のステータスドットや通知ベルアイコンにも使えます。

scale(1.07, .94)어긋난 위상900ms
$duration: 900ms;
$easing: ease-in-out;
$color: $subject-cream;

.o-puru {
  animation: o-puru $duration $easing infinite;
}

@keyframes o-puru {
  0%, 100% { transform: scale(1, 1); }
  25%      { transform: scale(1.07, .94); }
  50%      { transform: scale(.95, 1.06); }
  75%      { transform: scale(1.03, .97); }
}

04ゆらゆら揺れる

.o-yuraはtransform-originを上端に固定し、rotateだけを-6degから6degのあいだで2.4秒かけてゆっくり往復させます。吊り下げたセールタグやベルの装飾アイコンが、風に揺れているように見せたいときに向いています。

rotatetransform-origin: top2.4s
$duration: 2.4s;
$easing: ease-in-out;
$color: $subject-blue;

.o-yura {
  animation: o-yura $duration $easing infinite;
  transform-origin: top center;
}

@keyframes o-yura {
  0%, 100% { transform: rotate(-6deg); }
  50%      { transform: rotate(6deg); }
}

05くるくる回転

.o-kuruはrotateの360度を一定速度のlinearではなく、0→230→330→360degと区間ごとに通過点を変えるcubic-bezierで1.6秒かけて回します。均一な回転より一拍跳ねる感じが出るので、更新ボタンや同期アイコンに向いています。

rotate 360deg구간별 easing1.6s
$duration: 1.6s;
$easing: cubic-bezier(.65, 0, .35, 1);
$color: $subject-cream;

.o-kuru {
  animation: o-kuru $duration $easing infinite;
}

@keyframes o-kuru {
  0%   { transform: rotate(0deg); }
  55%  { transform: rotate(230deg); }
  80%  { transform: rotate(330deg); }
  100% { transform: rotate(360deg); }
}

06ぴょんぴょん跳ねる

.o-pyonは着地直前(10%・70%)にscaleYを押しつぶして平たくし、跳ぶ瞬間(40%)にはtranslateYとscaleYを伸ばして900msのリズムを作ります。「もっと見る」の矢印やスクロール誘導アイコンに使うと、弾む感じがそのまま伝わります。

translateY+scaleY착지 스쿼시900ms
$duration: 900ms;
$easing: ease-in-out;
$color: $subject-blue;

.o-pyon {
  animation: o-pyon $duration $easing infinite;
}

@keyframes o-pyon {
  0%, 100% { transform: translateY(0)     scaleY(1); }
  10%      { transform: translateY(2px)   scaleY(.9); }
  40%      { transform: translateY(-16px) scaleY(1.08); }
  70%      { transform: translateY(2px)   scaleY(.9); }
  85%      { transform: translateY(0)     scaleY(1.03); }
}

07ぐにゃぐにゃブロブ

.o-gunyaはborder-radiusの四隅を0%・33%・66%の3つの形でkeyframes内に切り替え、rotateもわずかに加えて3.2秒かけて漂わせます。ヒーロー背景の装飾ブロブや、機能カード裏のアクセント図形に向いています。

border-radius 4분할비대칭 keyframes3.2s
$duration: 3.2s;
$easing: ease-in-out;
$color: $subject-cream;

.o-gunya {
  animation: o-gunya $duration $easing infinite;
}

@keyframes o-gunya {
  0%, 100% { border-radius: 42% 58% 60% 40% / 46% 40% 60% 54%; transform: rotate(0deg); }
  33%      { border-radius: 62% 38% 45% 55% / 38% 56% 44% 62%; transform: rotate(6deg); }
  66%      { border-radius: 48% 52% 65% 35% / 60% 42% 58% 40%; transform: rotate(-5deg); }
}

08キラッと光る

.o-kiraは::beforeと::afterで作った2つの小さな星を、.4秒ずらしたdelayでopacityとscaleにより1.8秒周期で光らせます。「おすすめ」バッジや新機能マーカーに付けると、周期的にキラッと視線を集めます。

scale+opacity::before/::after1.8s
$duration: 1.8s;
$easing: ease-in-out;
$color: $subject-blue;

.badge.o-kira::before { animation: o-kira $duration $easing infinite; }
.badge.o-kira::after  { animation: o-kira $duration $easing infinite; animation-delay: .4s; }

@keyframes o-kira {
  0%, 45%, 100% { opacity: 0; transform: scale(.4); }
  62%           { opacity: 1; transform: scale(1.3); }
  78%           { opacity: 0; transform: scale(.6); }
}

09ぬるっと滑らか

.o-nuruはマウスを乗せるかフォーカスすると、矢印アイコンがease-out-expoに近いcubic-bezierで700msかけて滑らかに移動します。ほかの8つの弾む動きと対照的な、なめらかさだけが際立つ演出で、「詳しく見る」リンクに向いています。

translateXcubic-bezier(.16, 1, .3, 1)700ms
$duration: 700ms;
$easing: cubic-bezier(.16, 1, .3, 1);
$color: $subject-blue;

.link.o-nuru:hover .link__arrow,
.link.o-nuru:focus-visible .link__arrow { animation: o-nuru $duration $easing 1; }

@keyframes o-nuru {
  0%   { transform: translateX(0)    scale(1); }
  100% { transform: translateX(28px) scale(1.15); }
}

どこで壊れるか — is-demoクラスを消し忘れると起きる落とし穴

02のぽよんと09のぬるっとは、実際に使うときのトリガー(:hover:focus-visible)と、このデモページを自動で動かし続けるための.is-demoループ用ルールを、同じ要素に重ねて持っています。どちらもクラス2〜3個ぶんの特定度でぴったり同点なので、CSSのカスケードでは後に書かれた宣言のほうが勝ちます。SCSSファイルの中では:hover:focus-visibleのルールを先に、.is-demoのルールをそのあとに書いてあるため、デモページで実際にマウスを乗せても後勝ちの.is-demo側が優先され、2秒ループの自動再生アニメーションがそのまま動き続けます。zipのコードを自分のサイトに貼るときはis-demoクラスだけを外せば、隠れていた本来のホバー・トリガーがそのまま生き返ります。07ぐにゃぐにゃブロブだけは変化の強度が9つの中でいちばん低く測定されていて、背景と図形の明暗が近い色づかいなのが理由なので、対比の弱い背景に置くとほとんど見えなくなる点にも注意してください。duration・easing・色をvanilla・Reactの両方でそろえたzipファイル一式は、この段落をゆっくり読むと出てくる解凍パスワードkxj6u9k6で開きます。

アクセシビリティ

端末のOS設定でモーションを控えめにしていると、9つとも@media (prefers-reduced-motion: reduce)が効いてanimationをnoneに切り替えます。01ふわふわ・04ゆらゆら・07ぐにゃぐにゃのように常時ループする背景寄りの演出は、静止しても伝えるべき情報が失われません。02ぽよんと09ぬるっとはアニメーションが止まっても、ボタンのクリックやリンクの遷移そのものは変わらず機能します。対応状況はMDNのprefers-reduced-motionのドキュメントの互換性表で確認できます。

@media (prefers-reduced-motion: reduce) {
  .o-float, .o-puru, .o-yura,
  .o-kuru, .o-pyon, .o-gunya { animation: none; }
  .badge.o-kira::before, .badge.o-kira::after { animation: none; }
  .btn.o-poyon:hover, .btn.o-poyon:focus-visible,
  .link.o-nuru:hover .link__arrow,
  .link.o-nuru:focus-visible .link__arrow { animation: none; }
}

似た「浮く・跳ねる・回る」系の動きを英語のユーティリティ名でそろえた記事はCSSキーフレームアニメーション9選にまとめてあり、ほかのCSSアニメーションはCSSカテゴリーから探せます。

FAQ

css アニメーション バウンスを何個まで同じ画面に置いていいですか?

技術的には制限がありませんが、1画面には2〜3個までにとどめるのがおすすめです。02ぽよんと08キラッはどちらも「ここを見て」と訴える役割なので、同じ画面に並べて置くと視線が分散してしまいます。01ふわふわのように静かなものと05くるくるのように状態を伝えるものは、役割が重ならないので一緒に置いても構いません。

デモページで02と09がずっと動いているのはなぜですか?

実際のコードでは02と09はマウスを乗せるかフォーカスしたときだけ動くホバートリガーです。このデモは何もしなくても動きが伝わるよう.is-demoクラスで2秒ごとに自動再生させているだけで、実際の画面に組み込むときはこのクラスを外せば元のホバー専用の動きに戻ります。

zipの中のvanillaとReactのコードはどう違いますか?

画面に出る動きそのものは同じです。vanilla側でSCSS変数として渡している$duration$easing$colorを、React版ではコンポーネントのpropsとして受け取り、内部でCSSカスタムプロパティに変換して渡す仕組みだけが異なります。

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

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