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

矢印 CSS アニメーション9選【コピペOK】

リンクの矢印にマウスを乗せた瞬間にすっと伸びたり、ボタンの矢印が絶えずゆっくり跳ねたりする動きを見たことはありませんか。この記事はそうした矢印 css アニメーションを、一行でコピペOKなコード9個にまとめたものです。

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

9個は、矢印が画面で担う役割の順に並んでいます。最初はリンクの横で方向を示すもの(01・05)、続いてマウス操作なしでも動き続けて目を引く自動再生タイプ(02・03・07・08)、そのあいだにボタンの上で反応するもの(04)と手描き風の演出(06)を挟み、最後は位置を入れ替える交差型(09)で締めくくります。矢印が弾みながら方向を知らせる側に興味があればバウンスアニメーションがその落下を作っており、リンクの上で線が引かれる動きはCSS下線アニメーションが相棒です。

01伸びる矢印

何が動くか

「続きを読む」のようなリンクにマウスを乗せると、矢印の軸(棒の部分)がすっと横に伸び、先端の矢じりもその分だけ右へ動きます。

伸びる矢印
新しいタブで開く

01 · 伸びる矢印 — 計測 累積面積 0.163% · 動いたフレーム 15/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

scaleXtranslateXhover

コードの読み方

軸はtransform: scaleX、矢じりはtransform: translateXを使い、どちらも同じ220ミリ秒で一緒に切り替わります。新たに伸びる動きへ$ease-elastic(cubic-bezier(.34,1.56,.64,1))のゴムひも状オーバーシュートを足し、矢じりの後ろには時間差で減衰しながら追いかける点2つのトレイルも付きました。

.ae-link__shaft {
  transform-origin: left center;
  transform: scaleX(1);
  transition: transform 220ms;
}
.ae-link__head {
  transform: translateX(0) rotate(45deg);
  transition: transform 220ms;
}
.ae-link:hover .ae-link__shaft { transform: scaleX(1.8); }
.ae-link:hover .ae-link__head { transform: translateX(10px) rotate(45deg); }

02流れ続ける矢印

どこで使うか

矢印(シェブロン)が3つ並び、マウスを乗せなくても右へ向かって順番に浮かび上がっては消えることを繰り返します。

流れ続ける矢印
新しいタブで開く

02 · 流れ続ける矢印 — 計測 累積面積 1.146% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

opacitytranslateXstagger

コードの要点

3つとも同じ動きを使い、animation-delayだけをずらしてあるので、水が流れているように見えます。3つの流れに26%→38%のオーバーシュート-定着ストップが加わり、末尾にはさらに小さく薄いトレイルの点がひとつ遅れて流れます。

@keyframes sl-flow {
  0% { opacity: 0; transform: translateX(-8px); }
  30%, 70% { opacity: 1; transform: translateX(0); }
  100% { opacity: 0; transform: translateX(8px); }
}
.sl-chevron { animation: sl-flow 1.6s infinite; }
.sl-chevron--2 { animation-delay: 180ms; }
.sl-chevron--3 { animation-delay: 360ms; }

03下に跳ねる

見えるもの

下向きの矢印がひとつ、上下にぴょんぴょんと跳ねながら、スクロールして続きを見るよう優しく促します。

下に跳ねる
新しいタブで開く

03 · 下に跳ねる — 計測 累積面積 0.637% · 動いたフレーム 22/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

translateYkeyframesauto

動く仕組み

矢印の形自体はborderで組んだL字を45度回転させただけなので、コードはとても軽くなっています。バウンスの頂点(42%→50%)にオーバーシュート-定着が加わり、矢印の上を小さな残像が遅れて追いかけ下ります。

.bd-chevron {
  border-bottom: 4px solid;
  border-right: 4px solid;
  transform: rotate(45deg) translateY(0);
}
@keyframes bd-bounce {
  0%, 100% { transform: rotate(45deg) translateY(0); }
  50% { transform: rotate(45deg) translateY(12px); }
}
.bd-chevron { animation: bd-bounce 1.4s infinite; }

04円+矢印ホバー

css ボタン 矢印 アニメーション をどこで使うか

円形のボタンにマウスを乗せると、重なっていた矢印のうち一枚が右へ抜けながら消え、代わりにもう一枚が左から入ってきて位置を引き継ぎます。

円+矢印ホバー
新しいタブで開く

04 · 円+矢印ホバー — 計測 累積面積 1.206% · 動いたフレーム 19/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

translateXopacityhover

組み立て方

同時に円の枠もひとまわり大きくなり、色も変わります。円ボタンのスケールと矢印の入れ替わりが$ease-elasticでオーバーシュートするようになり、交差する2本の矢印それぞれの後ろにトレイルの点が付きました。

.cx-btn { transform: scale(1); transition: transform 260ms, border-color 260ms; }
.cx-btn__arrow--a { opacity: 1; transform: translateX(0); }
.cx-btn__arrow--b { opacity: 0; transform: translateX(-16px); }
.cx-btn:hover .cx-btn__arrow--a { opacity: 0; transform: translateX(16px); }
.cx-btn:hover .cx-btn__arrow--b { opacity: 1; transform: translateX(0); }
.cx-btn:hover { transform: scale(1.06); border-color: #2f6df6; }

05外部リンク45度回転

何が起きるか

外部サイトへのリンクの横にある矢印にマウスを乗せると、矢印がちょうど45度余分に回転しながら少し外へ抜け出し、このリンクが新しいタブで開くことを静かに知らせます。回転のトランジションが$ease-elasticで45度を少し超えてから定着するようになり、回転する矢印の後ろには薄い残像がひとつ追いかけます。

外部リンク45度回転
新しいタブで開く

05 · 外部リンク45度回転 — 計測 累積面積 0.103% · 動いたフレーム 15/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

rotatetranslatehover

なぜこう書くか

.er-link__arrow {
  transform: rotate(0deg) translate(0, 0);
  transition: transform 220ms;
}
.er-link:hover .er-link__arrow {
  transform: rotate(45deg) translate(2px, -2px);
}

06線が描かれる矢印

画面で起きること

矢印の形をしたSVGの線が、始点から終点まで手で描いたようにすっと現れ、また逆側から消えることを繰り返します。

線が描かれる矢印
新しいタブで開く

06 · 線が描かれる矢印 — 計測 累積面積 2.082% · 動いたフレーム 18/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

SVGstroke-dashoffsetpathLength

実装の核

stroke-dashoffsetの値を100から0まで減らすと線が描かれ、さらに-100まで減らすと反対側から消えていきます。描画が終わる瞬間(58%→66%)に矢じりの位置で小さな円がゴムひものように膨らんで定着するオーバーシュート・ポップと、90ミリ秒遅れて追う薄いトレイルパスが加わりました。

.ds-path {
  stroke-dasharray: 100;
  animation: ds-draw 2.2s infinite;
}
@keyframes ds-draw {
  0% { stroke-dashoffset: 100; }
  55% { stroke-dashoffset: 0; }
  80% { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: -100; }
}

07シェブロンウェーブ

見え方

上下に重ねて並べたシェブロン3つが、順番に明るくなっては暗くなることを繰り返し、波が流れているように見えます。

シェブロンウェーブ
新しいタブで開く

07 · シェブロンウェーブ — 計測 累積面積 0.931% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

opacitytranslateYstagger

何が肝心か

マウス操作は不要で、ページを開いた瞬間から自動で動き続けます。パルスの頂点(42%→50%)にオーバーシュート-定着が加わり、450ミリ秒遅れてさらに小さく薄いシェブロンのトレイルがひとつ追いかけます。

@keyframes cw-pulse {
  0%, 100% { opacity: .3; transform: translateY(0); }
  50% { opacity: 1; transform: translateY(6px); }
}
.cw-chevron { animation: cw-pulse 1.5s infinite; }
.cw-chevron--2 { animation-delay: 150ms; }
.cw-chevron--3 { animation-delay: 300ms; }

08マウス型スクロール案内

いつ使うか

マウスの形をした枠の中で、小さな点が下へ流れるように動きながら薄くなって消えることを繰り返し、下にまだコンテンツがあることを伝えます。ヒーローセクションの下部に置くのにぴったりです。点が落ちきる終点(55%→63%→70%)にオーバーシュート-定着が加わり、点の上を120ミリ秒遅れて小さなトレイルが追いかけ下ります。

マウス型スクロール案内
新しいタブで開く

08 · マウス型スクロール案内 — 計測 累積面積 0.236% · 動いたフレーム 19/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

translateYopacityborder-radius

押さえておく点

.ms-mouse { border: 3px solid; border-radius: 999px; padding-top: 12px; }
.ms-dot { animation: ms-scroll 1.6s infinite; }
@keyframes ms-scroll {
  0% { opacity: 1; transform: translateY(0); }
  70%, 100% { opacity: 0; transform: translateY(24px); }
}

092本の矢印が入れ替わる

どの画面か

同じ斜め線の上に乗った矢印2本が、互いに反対方向へすべるように動きながらすれ違い、位置を入れ替えます。

2本の矢印が入れ替わる
新しいタブで開く

09 · 2本の矢印が入れ替わる — 計測 累積面積 0.637% · 動いたフレーム 22/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

translaterotatestagger

どう作るか

並べ替えの向きを切り替えるボタンなどに付けると「入れ替わった」感覚が伝わります。交差してすれ違う頂点(46%→50%)にオーバーシュート-定着が加わり、2本の矢印それぞれの後ろに60ミリ秒遅れたトレイルの点が付きました。

@keyframes xs-swap-a {
  0%, 100% { transform: translate(-6px, 6px) rotate(-45deg); }
  50% { transform: translate(6px, -6px) rotate(-45deg); }
}
@keyframes xs-swap-b {
  0%, 100% { transform: translate(6px, -6px) rotate(135deg); }
  50% { transform: translate(-6px, 6px) rotate(135deg); }
}

CSS矢印アニメーションはどこで壊れるか

何が問題か

css 矢印 アニメーション 伸びる 系の01番ではなく、9個の中で最初につまずいたのは08番のマウス型スクロール案内でした。点を4×8ピクセル、動く距離を14ピクセルととても小さく作ってレンダリングし、実際に測定してみたところ、変化したピクセルの面積はキャンバス全体のわずか0.06%しかありませんでした。目には確かに動いて見えても、全体に占める割合が小さすぎて「動いていない」のとほとんど区別がつかない数値だったのです。点を8×16ピクセルに、動く距離を24ピクセルに広げ、マウスの枠も44×68ピクセルまで大きくしてはじめて0.236%まで余裕を持って測定値が伸びました。

どう避けるか

アイコンが背景の模様に埋もれる瞬間は、点と波が画面を埋めるメンフィスパターンのLPではさらに早く訪れるため、模様の側を休ませる規則で防ぎます。

矢印のようにもともと小さい図形は、思い切って大きめに作らないと動き自体が伝わりません。01番の伸びる矢印も同じ理由で余裕は大きくなく、transform-origin: left centerを書き忘れると軸が中心を基準に伸びてしまい矢じりとずれるので注意が必要です。奥行きを出すのに便利だからとz-indexを負の値にする前には、その要素にposition以外でスタッキングコンテキストが生まれる条件があるかどうかも合わせて確かめておくと、意図した層より下へ潜り込んで矢印ごと見えなくなる失敗を避けられます。こうした小さなつまずきを一通り直したあと、9個をまとめた圧縮ファイルを開く鍵は8dggvep3という場所にそっと隠れていて、太字や枠で目立たせていないぶん、流し読みではなくゆっくり読むと見つかります。

アクセシビリティ — 9個がreduced-motionで残すもの

reduced-motion で残るもの

OSの動作を減らす設定をオンにしている方には、prefers-reduced-motion: reduceのなかで9個すべての動きを止めるようにしてあります。01・04・05番のようにマウスを乗せたときだけ動く項目は、ホバー前の普段の形に戻るだけなので情報は欠けません。常に動き続けていた項目は二つのグループに分かれます。02番の流れる矢印と07番のシェブロンウェーブは、透明度を中間の値(それぞれ0.6・0.7)で固定してあり、動きは止まっても矢印の並びそのものは薄く見え続けます。一方で03番のバウンス・08番のマウス型案内・09番の入れ替えは、周期の始まりにあたる姿勢でぴたりと止まり、跳ねたり流れたりする途中の値ではなく矢印本来の向きだけが残ります。06番のSVG矢印は線がすべて描き終わった状態(stroke-dashoffset: 0)に固定してあるので、こちらも情報が消えることはありません。今回9個すべてに加えたオーバーシュートと後方のトレイル(点・残像・パス)も同じprefers-reduced-motion: reduceの中で丸ごと停止するので、動きを控えたい方に新しい揺れや尾が見えることはありません。

そのほかに気をつけること

矢印を含むSVGの動きをもっと詳しく知りたい方はCSSアイコン・SVGアニメーションの記事もあわせてどうぞ。ほかのCSSアニメーションはCSSカテゴリーから一覧できます。stroke-dashoffsetの正確な仕様はMDNのドキュメントで確認できます。

FAQ

矢印アニメーションにJavaScriptは必要ですか?

この9個はすべて純粋なCSS(06番のみSVGを併用)だけで作られています。ホバーへの反応は:hoverセレクター、自動再生は@keyframesだけで処理していて、JavaScriptは一行も使っていません。

リンク 矢印 css には01番と04番のどちらを使えばいいですか?

テキストリンクの横に添える簡単な合図なら01番の軸が伸びるタイプで十分です。円形ボタンのように独立したクリック領域があり、そのなかで矢印自身が反応してほしい場合は、04番のように矢印が入れ替わるタイプのほうが目に留まります。

zipの中のvanillaとreactのコードは違いますか?

画面に見える動きは同じで、中身の受け渡し方だけが異なります。vanilla側のSCSS変数3つ($duration $easing $color)を、React版ではコンポーネントのpropsとして受け取り、内部でCSSカスタムプロパティ(--duration --easing --color)に変換して渡しています。矢印をアイコンボタンへ育てたいなら、アイコン・フローティングボタンのパターンに押して広がる動きがあります。

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

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