これは何
CSSだけで、ループアニメーションを作る方法と仕組みについてまとめました。
CSSでループアニメーションをする方法を解説する記事はいろいろありますが、それぞれ微妙に内容が違ったり使いたい条件によってカスタムが必要だったので、ちゃんと仕組みを理解をしようと思い整理しました。
動き続ける要素があると、本来集中したいコンテンツに集中できないなどの弊害もあるので、使い所は要検討しましょう。
また、ストップボタンなどを用意してアニメーションを停止できるようにするのがおすすめです。
詳しくはWCAG2.1の達成基準 2.2.2 一時停止、停止、非表示やUnderstanding WCAG 2.1の達成基準 2.2.2: 一時停止、停止、非表示を理解するなどをご覧ください。
(基礎知識) CSS animation とは
CSSだけで簡単にアニメーションが作れるプロパティです。
transiton
との大きな違いは以下の3点です
- アニメーションが発火するタイミング
- アニメーションを指定できるプロパティ
-
@keyframes
が使える
transiton
は、要素に何らかの変化があったときにその変化の間を埋めるアニメーションを作ります。
例えば、ホバーして色が黒から緑に変わる時に、ゆっくりと色を変化させるなどです。
animation
では要素が読み込まれた時にアニメーションが始まり、キーフレームごとのスタイルを指定してアニメーションさせることができます。
例えば、常に回転していて一定間隔で色が変わるオブジェクトなどの装飾的なアニメーションが作れます。
アニメーションを実行するか停止するかも指定できるので、「hoverをしている時だけアニメーションさせる」といったことも可能です。
ざっくりとtransition
とanimation
のできることの違いを以下の表にまとめてみました。
種類 | transition |
animation |
---|---|---|
発火タイミング | 指定したプロパティproperty が変化する時 |
要素が読み込まれた時 |
待ち時間 delay
|
○ | ○ |
実行時間 duration
|
○ | ○ |
イージング timing-function
|
○ | ○ |
アニメーションの実行/停止 play-state
|
× | ○ |
再生の向き direction
|
× | ○ |
アニメーションの再生回数 iteration-count
|
× | ○ |
アニメーション実行前後のスタイル適用 fill-mode
|
× | ○ |
アニメーションをキーフレームごとに設定 @keyframes
|
× | ○ |
CSSだけでアニメーションがループする仕組み
基本的には、画像を「端から端に動かす」アニメーションを「繰り返す」ことでループしているように見せます。
途切れずにアニメーションしているように見せたい時は、ループさせるエリアより大きいオブジェクトを2つ用意します。
実際に動かしてみたものは以下です。(目がチカチカするので、折りたたんでます)
ループアニメーションのデモ
See the Pen Untitled by kabechiyo_shunkaaizawa (@kabechiyo) on CodePen.
応用すると、こんな感じで回転するループの動きも作れます。
回転しながらループするアニメーションのデモ
See the Pen Untitled by kabechiyo_shunkaaizawa (@kabechiyo) on CodePen.
ループアニメーションの作り方
ようやくアニメーションの作り方です。
一個だけの要素を動かすとき
まずはループさせる要素と、ループさせるエリアを用意します。
<section class="loop_area">
<div class="loop_right">
ループする要素
</div>
</section>
次に、ループさせるエリアに適当なwidthを指定します。(100%でもOK)
はみ出す部分は表示されないようにしたいので、overflow: hidden
も指定します。
.loop_area {
width: 400px;
overflow: hidden;
}
次にループアニメーションを作っていきます。
@keyframes
で0%の時はtranslateX(0)
、100%の時にtranslateX(100%)
になるようにします。
animation
でループアニメーションの秒数を指定し、infinite
でアニメーションを繰り返すようにします。
width: 100%
を当てて、translateX(100%)
の時にちょうどエリア外に到達するようにします。
@keyframes loop_animation_right {
0% {
transform: translateX(0);
}
100% {
transform: translateX(100%);
}
}
.loop_right {
animation: loop_animation_right 3s linear infinite;
width: 100%;
}
これでループアニメーションの完成です。
「Result」でアニメーションの様子を見れます。
ループする向きを逆方向にしたいときは、animation-direction: reverse;
を指定するか、@keyframes
の値を0%
の時にtransform: translateX(100%);
・100%
の時にtransform: translateX(0);
に変更します。
See the Pen loop_animation_right by kabechiyo_shunkaaizawa (@kabechiyo) on CodePen.
ずっとループしているように見せるとき
先ほどと同じようにループするエリアを作り、中にループさせたい要素を「ループエリアよりも大きいサイズ」で「2つ」作ります。
<section class="wrapper">
<div class="loop_right_double">
ループ ループ ループ ループ ループ ループ ループ ループ ループ
</div>
<div class="loop_right_double">
ループ ループ ループ ループ ループ ループ ループ ループ ループ
</div>
</section>
先ほどと同じくループさせるエリアにwidth
とoverflow: hidden;
を指定します。
また、ループさせる要素が横並びになるようにdisplay: flex;
を指定します。
.wrapper {
display: flex;
width: 400px;
overflow: hidden;
}
そして、アニメーションを作っていきます。
今回ははじまる位置をtranslateX(-100%)
にし、最初は「2個目」の要素が見えているようにし、だんだん「1個目」の要素が見えてくるようにします。
また、今回はテキストをループさせているので、テキストが折り返さないようにwhite-space: nowrap;
を指定しておきます。
@keyframes loop_animation_right_double {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(0);
}
}
.loop_right_double {
animation: loop_animation_right_double 3s linear infinite;
white-space: nowrap;
}
これでループアニメーションの完成です。
「Result」でアニメーションの様子を見れます。(分かりやすいように2個目の要素の色を変えてます。)
See the Pen Untitled by kabechiyo_shunkaaizawa (@kabechiyo) on CodePen.
【番外編】回転しながらループするアニメーション
練習がてら遊びに作ってみました。
今までのループはtransform
で作っていましたが、こちらはtop, left
で位置を指定しています。
これは、端まで行った時にエリア外にはみ出すのではなくエリア内で止めるためです。
例えば右端まで行った時の位置は、left: 100%
でエリア外にはみ出した位置に持っていき、transform: translateX(-100%)
を重ねて自分のサイズ分左にずらすことで、エリア外にはみ出さない位置を指定しています。
動かしてみたものはこちらです。「Result」でアニメーションが確認できます。
See the Pen Loop_circle by kabechiyo_shunkaaizawa (@kabechiyo) on CodePen.