こんにちは。サイト開発担当のshoです。
今回は「これまでのサイト開発まとめ」シリーズの11回目です。前回はこちら、初回はこちら。
アピールエリアの矢印に動きを追加しました。
CSSアニメーション
CSSアニメーションとは、CSSのanimationプロパティを使用した記述によって、CSSで設定したスタイルを別のスタイルに変化させるものです。
同様の効果を持つプロパティに「transition」というものもありますが、こちらはもっと単純な動きを付けるときに使用します。
また、要素を動かすにはJavaScriptやjQueryを利用することも可能で、こちらの方がCSSアニメーションより複雑な動きを付けられますが、処理が重くなりやすいデメリットがあります。
animationプロパティと@keyframes
CSSアニメーションは、animationプロパティのみでは動きません。
animationプロパティは、主にCSSアニメーションの再生方法を指定するものです。
だとすれば、CSSアニメーションの中身を定義するものが必要になりますよね?
それを定義できるのが「@keyframes」です。
CSSアニメーションの最初、中間(複数可)、最後のスタイルをそれぞれ指定できます。
CSSアニメーションの設定方法
それでは、animationプロパティと@keyframesの実際の使い方を見ていきましょう。
簡単な例を使って説明していきます。
以下を見てください。「あいうえお」の文字がゆっくり点滅していますね。
See the Pen animation by sho (@sho_codepen) on CodePen.
まずは、「div p { animation: fadein 4s infinite; }」の部分です。
これは「<div><p>あいうえお</p></div>」という要素に「fadein」というアニメーションを適用し、それを4秒間かけて再生(4s)して、それを永遠に繰り返す(infinite)という指定になります。
「fadein」というアニメーション名は、特にCSSの文法で決まっているものではなく、こちらが分かりやすいと思う名前を任意に付与できます。このアニメーション名は、後ほど説明する@keyframesの記述で使用します。
さて、animationプロパティで指定できる項目は以下の8つです。
・animation-name → @keyframesで定義する任意のアニメーション名。初期値はnone。
・animation-duration → アニメーションの再生時間。初期値は0s。
・animation-timing-function → アニメーションの速度変化のスタイル。初期値はease(次項で説明)。
・animation-delay → アニメーションが開始するまでの時間。初期値は0s。
・animation-iteration-count → アニメーションの再生回数。初期値は1。無限ループはinfinite。
・animation-direction → アニメーションの再生方向。初期値はnormal(後ほど説明)。
・animation-fill-mode → アニメーションの再生前後に適用されるスタイル。初期値はnone(後ほど説明)。
・animation-play-state → アニメーションの再生(running)・一時停止(paused)の切り替え。初期値はrunning。
これらは単体のプロパティとして使用することもできますが(「animation-duration: 4s;」のように)、先程の例のようにまとめて記述(ショートハンド)すると、見た目を簡潔にできます。
また、各プロパティには初期値が設定されているため、必ずしも全ての項目を指定する必要はありません。何も書かなければ初期値として扱われます。
ただし、animationプロパティにおける時間指定は、1つ目の値がanimation-durationに、2つ目の値がanimation-delayに割り当てられる仕組みになっています。
そのため、ショートハンドで記述する場合は、① animation-durationを指定せずにanimation-delayのみ指定しても、CSSではanimation-durationとして判別されてしまうこと(秒数を1つだけ指定してある先程の例がそうですね)、② 必ずanimation-duration、animation-delayの順で記述すること、この2点に注意してください。
animation-timing-function
CSSアニメーションの速度変化のスタイルには、主に以下の7つがあります。
・ease → アニメーションの開始から中間に向けて変化量が増加し、中間から終了までは変化量が減少する。
・ease-in → アニメーション開始時はゆっくりの速度で、終了まで加速する。
・ease-out → アニメーション開始時は速い速度で、終了まで減速する。
・ease-in-out → アニメーションはゆっくり変化し、開始から中間までは速度が増加して、中間から終了までは速度が減少する。
・linear → アニメーションの開始から終了まで変化量が一定。
・steps → コマ送りのように指定したタイミングごとにアニメーションが変化する。
・cubic-bezier → アニメーションの変化を任意の三次ベジェ曲線で指定する。
実際にコードを書いてみたのが以下です。
See the Pen animation_exanple by sho (@sho_codepen) on CodePen.
animation-direction
CSSアニメーションの再生方向のスタイルには、以下の4つがあります。
・normal → アニメーションの開始から終了まで順方向に再生される。
・reverse → アニメーションの終了から開始まで、逆方向に再生される。
・alternate → アニメーションを順方向から逆方向へ、交互に途切れず再生し続ける。
・alternate-reverse → アニメーションを逆方向から順方向へ、交互に途切れず再生し続ける。「alternate」を逆方向にしたもの。
実際にコードを書いてみたのが以下です。
See the Pen animation-direction by sho (@sho_codepen) on CodePen.
animation-fill-mode
アニメーションの再生前後に適用されるスタイルには、以下の4つがあります。
・none → スタイルの指定なし。
・forwards → アニメーション終了時、そのスタイルを維持する。
・backwards → アニメーション終了時、再生前のスタイルに戻る。
・both → アニメーション開始時に「forwards」、終了時に「backwards」が適用される。
実際にコードを書いてみたのが以下です。
See the Pen animation-fill-mode by sho (@sho_codepen) on CodePen.
@keyframes
animationプロパティについて理解できたところで、もう一度先程の例です。
See the Pen animation by sho (@sho_codepen) on CodePen.
今度は、「@keyframes fadein { 0% { opacity: 0; } 50% { opacity: 1; } 100% { opacity: 0; } }」の部分を見ていきましょう。
これは、animationプロパティで指定した「fadein」というアニメーションの内容を定義するものです。
この例の場合は、「アニメーション開始時(0%)の不透明度(opacity)が0、アニメーションが50%まで進行した時点での不透明度が1、アニメーション終了時(100%)の不透明度が0」、つまり「『あいうえお』という文字列について、アニメーション開始時は透明で、中間にかけて不透明になっていき、そこから終了時に向けて透明になっていく」というスタイルの変化になります。
もちろん、ここで指定できる内容は不透明度だけではないので、基本的にあらゆるスタイルについて盛り込むことが可能です。
ちなみに、@keyframes内でスタイルを指定する際、0%と100%しか定義しない場合は、以下のように、それぞれ「from」と「to」で表記することもできます。
@keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}
今回追加したCSS
改めて、今回設置する動く矢印のCSSアニメーションを定義する箇所を見てください。
.appeal-content::before {
display: inline-block;
content: "";
position: absolute;
width: 40px;
height: 40px;
border-bottom: solid 4px #060E1C;
border-left: solid 4px #060E1C;
transform: rotate(-45deg);
bottom: 7%;
right: 0;
left: 0;
margin: auto;
animation: scroll_1 4s 0s forwards,scroll_2 3.5s 2s infinite none
}
@keyframes scroll_1 {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes scroll_2 {
0% {
transform: rotate(-45deg) translate(0, 0);
opacity: 0;
}
40% {
opacity: 1;
}
80% {
transform: rotate(-45deg) translate(-30px, 30px);
opacity: 0;
}
100% {
opacity: 0;
}
}
まずは擬似要素「::before」の箇所からです。
前回の記事の言葉をそのまま引用すると、幅と高さが40pxである空の「content」に対して、「solid 4px #060E1C」の「border-bottom」と「border-left」を適用し、左に45°回転させていることが分かります。
次に、animationプロパティの箇所です。
「animation: scroll_1 4s 0s forwards, scroll_2 3.5s 2s infinite none」となっており、アニメーションの名前が2つ(「scroll_1」と「scroll_2」)記述されていることが分かります。
animationプロパティでは、カンマで区切って記述することにより、一つの要素に対して、複数のアニメーションを適用させることができます。
この場合は、「scroll_1」の再生時間が4sなので、「scroll_2」の再生タイミングを同じだけ遅らせることにより、順番にアニメーションが再生されているかのように見せることができます。
そして、@keyframesの箇所です。
ここでは、「scroll_1」の内容と「scroll_2」の内容を、それぞれ分けて定義しています。
「scroll_1」の方は、アニメーション開始から終了に向けて不透明度が増すだけの簡単なものです。
「scroll_2」の方が複雑で、「transform」プロパティで「rotate(回転)」と「translate(平行移動)」の変化を定義しています。同プロパティでは、他に「scale(拡大縮小)」と「skew(傾斜変形)」の変化を定義できます。
rotateは、右方向への回転がプラス、左方向への回転がマイナスです。
translateはX軸とY軸から成り立っており、1つ目の値がX軸の変化量、2つ目の値がY軸の変化量になります。
ちなみに、原点(0, 0)は左上にあるため、X軸の変化量がプラスであれば左から右に、Y軸の変化量がプラスであれば上から下に移動します。数学でよく使う直交座標系の第1象限ではなく、第4象限をイメージしていただくと良いでしょう。
ところで、「rotate(-45deg)」と「translate(-30px, 30px)」ですが、これらの順番を入れ替えて記述すると、矢印の動きが変わってしまいます。
次項で簡単な例を使って説明しましょう。
transformプロパティ内の書き順について
黒い四角形が「.origin」、青緑色の四角形が「.transform」です。
以下は、transformプロパティに対して、translate→rotateの順で指定した例です。
See the Pen transform_2 by sho (@sho_codepen) on CodePen.
次が、同じ値をrotate→translateの順で指定した例です。
See the Pen transform_1 by sho (@sho_codepen) on CodePen.
指定した値は同じなのに、出力結果は異なってしまいましたね。
これには先述の通り、rotateとtranslateの指定順序が関わっています。
CSSは書かれた順に一つずつ読み込まれ、処理されていきます。
上の例であれば、まず行われる処理は「『.transform』を右と下に50pxずつ動かすこと」ですね。
そして、次に行われる処理は「その場で(要素の中心を基準に)『.transform』を右に45°回転させること」です。
こちらは理解しやすいと思います。
それに対して、下の例の場合、まず行われる処理は「その場で(要素の中心を基準に)『.transform』を右に45°回転させること」です。
次に行われる処理は「『.transform』を右と下に50pxずつ動かすこと」ですが、このときのX軸とY軸は、「.origin」ではなく、「.transform」を基準としたものなのです。
どういうことかと言うと、最初に「.transform」を右に45°回転させているので、その時点で「.transform」のX軸とY軸も一緒に回転しています。
反対に、「.origin」に対しては何の変化も定義していないので、そのX軸とY軸も回転しません。
その結果、「.transform」と「.origin」では、X軸とY軸の角度がそれぞれ異なってきます。
そのため、初めに「.transform」を右に45°回転させたなら、次に我々も首を右に45°傾けてから、「.transform」を動かさなければならないわけです。
逆に言えば、上の例の場合、「.transform」のX軸とY軸は、「.origin」のものと同じ傾きだったので、結果的に難しく考える必要がなかったと分かりますね。
そういうわけで、下の例の場合、「.transform」をX軸とY軸に対して同じ距離だけ動かせば、「.origin(=我々から見た画面の向き)」から見て、結果的に上下に移動させたことになります。
ちなみに、当サイトのトップページにおける動く矢印の場合、左に45°回転させているので、X軸の移動距離をマイナス、Y軸の移動距離をプラスにすることで「.origin」や画面から見て下に移動します。
逆にX軸の移動距離をプラス、Y軸の移動距離をマイナスにすれば上に移動します。
そして、X軸とY軸の移動距離のプラスマイナスを揃えた場合は、横移動になりますね。
というわけで、動く矢印の「scroll_2」の中身は、要素の不透明度を変化させつつ、上下移動させているものになります。
コメント