GODRICH

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

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

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

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

01伸びる矢印

「続きを読む」のようなリンクにマウスを乗せると、矢印の軸(棒の部分)がすっと横に伸び、先端の矢じりもその分だけ右へ動きます。軸はtransform: scaleX、矢じりはtransform: translateXを使い、どちらも同じ220ミリ秒で一緒に切り替わります。

scaleXtranslateXhover
.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つ並び、マウスを乗せなくても右へ向かって順番に浮かび上がっては消えることを繰り返します。3つとも同じ動きを使い、animation-delayだけをずらしてあるので、水が流れているように見えます。

opacitytranslateXstagger
@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下に跳ねる

下向きの矢印がひとつ、上下にぴょんぴょんと跳ねながら、スクロールして続きを見るよう優しく促します。矢印の形自体はborderで組んだL字を45度回転させただけなので、コードはとても軽くなっています。

translateYkeyframesauto
.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円+矢印ホバー

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

translateXopacityhover
.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度余分に回転しながら少し外へ抜け出し、このリンクが新しいタブで開くことを静かに知らせます。

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の線が、始点から終点まで手で描いたようにすっと現れ、また逆側から消えることを繰り返します。stroke-dashoffsetの値を100から0まで減らすと線が描かれ、さらに-100まで減らすと反対側から消えていきます。

SVGstroke-dashoffsetpathLength
.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つが、順番に明るくなっては暗くなることを繰り返し、波が流れているように見えます。マウス操作は不要で、ページを開いた瞬間から自動で動き続けます。

opacitytranslateYstagger
@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マウス型スクロール案内

マウスの形をした枠の中で、小さな点が下へ流れるように動きながら薄くなって消えることを繰り返し、下にまだコンテンツがあることを伝えます。ヒーローセクションの下部に置くのにぴったりです。

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本が、互いに反対方向へすべるように動きながらすれ違い、位置を入れ替えます。並べ替えの向きを切り替えるボタンなどに付けると「入れ替わった」感覚が伝わります。

translaterotatestagger
@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矢印アニメーションはどこで壊れるか

9個の中で最初につまずいたのは08番のマウス型スクロール案内でした。点を4×8ピクセル、動く距離を14ピクセルととても小さく作ってレンダリングし、実際に測定してみたところ、変化したピクセルの面積はキャンバス全体のわずか0.06%しかありませんでした。目には確かに動いて見えても、全体に占める割合が小さすぎて「動いていない」のとほとんど区別がつかない数値だったのです。点を8×16ピクセルに、動く距離を24ピクセルに広げ、マウスの枠も44×68ピクセルまで大きくしてはじめて0.20%まで余裕を持って測定値が伸びました。矢印のようにもともと小さい図形は、思い切って大きめに作らないと動き自体が伝わりません。01番の伸びる矢印も同じ理由で余裕は大きくなく、transform-origin: left centerを書き忘れると軸が中心を基準に伸びてしまい矢じりとずれるので注意が必要です。奥行きを出すのに便利だからとz-indexを負の値にする前には、その要素にposition以外でスタッキングコンテキストが生まれる条件があるかどうかも合わせて確かめておくと、意図した層より下へ潜り込んで矢印ごと見えなくなる失敗を避けられます。こうした小さなつまずきを一通り直したあと、9個をまとめた圧縮ファイルを開く鍵は8dggvep3という場所にそっと隠れていて、太字や枠で目立たせていないぶん、流し読みではなくゆっくり読むと見つかります。

アクセシビリティ — 9個が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)に固定してあるので、こちらも情報が消えることはありません。

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

FAQ

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

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

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

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

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

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

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

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