CSS TransitionとCSS Animationの違い
CSSによるアニメーションには、CSS TransitionとCSS Animationの2種類があります。
項目 | CSS Transition | CSS Animation |
---|---|---|
プロパティの変化 | 単純なもののみ対応可能 | 複雑なものも対応可能 |
ループ | 不可 | 可 |
変化前の状態に戻る時 | アニメーションあり | アニメーションなし |
使い分け
CSS Transitionの用途の例
- メニューのスライドインアウト
- ホバー時のプロパティ変化
CSS Animationの用途の例
- ローディングアニメ
- 複雑なプロパティの変化
CSSで対応できないアニメーションの例
- バウンド
- 停止、一時停止
- 巻き戻し
- スローダウンなど速度の変化
より高度な効果を実現したい場合は、CSSアニメーションだけでは対応できないのでJavaScriptアニメーションを使います。
アニメーションのパフォーマンス
LayoutとPaintに影響を与えるCSSプロパティの変更はレンダリングコストが高いので、アニメーションの品質劣化に繋がります。
Layoutに影響を与えるCSSプロパティ
display, width, height, left, topなど
Paintに影響を与えるCSSプロパティ
border-radius, background-colorなど
LayoutやPaintに影響を与えない
transformなど
CSS Transition
CSS Transition開始のきっかけを作る
CSS Transitionでのアニメーションには、動作のきっかけが必要です。
:hoverなどの疑似クラスや、JavaScriptでのクラスの着脱がよく使われます。
疑似クラスを使う場合の例
例:ボックスにマウスを乗せると色が変わり、外すと色が戻るアニメーション
<div class="box"></div>
.box{
background-color: #e74c3c;
width: 100px;
height: 100px;
transition: background-color 500ms ease-in-out;
}
.box:hover{
background-color: #2ecc71;
}
クラスの着脱を使う場合の例
例:動作ボタンを押すとボックスが右へ移動し、再度押すと元の位置へ戻るアニメーション
<div class="box" id="js-moveTarget"></div>
<button id="js-moveSwitch">動作ボタン</button>
.box{
background-color: #e74c3c;
width: 100px;
height: 100px;
transition: transform 500ms 0s ease-in-out;
}
.box.active{
transform: translateX(500px);
}
const moveTarget = document.getElementById("js-moveTarget");
const moveSwitch = document.getElementById("js-moveSwitch");
const moveAction = ()=>{
moveTarget.classList.toggle("active");
}
moveSwitch.addEventListener("click",moveAction);
CSS Transitionで利用できるプロパティ
プロパティ | |
---|---|
transition | 下4つをまとめて指定可能 |
transition-property | どのプロパティにアニメーションを適用するか指定する(all/none/プロパティ名) |
transition-duration | アニメーション開始から終了までの時間を指定する(単位はs、ms) |
transition-delay | アニメーションが開始するまでの時間を指定する(単位はs、ms) |
transition-timing-function | アニメーションのイージングを指定する |
※transition-propertyは意図しない動きを避けるために、allではなく、カンマ区切りでプロパティ名を列記する方が安全です。 |
transitionプロパティでまとめて指定する場合
/* transition: transition-propertyの値 transition-durationの値 transition-delayの値 transition-timing-functionの値 */
transition: all 300ms 0s ease;
transition-timing-functionの値
値 | 内容 | cubic-bezierで表現すると |
---|---|---|
ease | 開始と完了を滑らかにする(初期値) | cubic-bezier(0.25, 0.1, 0.25, 1.0) |
linear | 一定速度 | cubic-bezier(0.0, 0.0, 1.0, 1.0) |
ease-in | ゆっくり始まる | cubic-bezier(0.42, 0, 1.0, 1.0) |
ease-out | ゆっくり終わる | cubic-bezier(0, 0, 0.58, 1.0) |
ease-in-out | ゆっくり始まってゆっくり終わる | cubic-bezier(0.42, 0, 0.58, 1.0) |
cubic-bezier | 指定による | - |
cubic-bezierの指定方法
/* cubic-bezier(x1, y1, x2, y2); */
cubic-bezier(0.42, 0, 0.58, 1.0);
Chrome DevToolsのcubic-bezierの前のアイコンをクリックすると、設定したイージングの動きを見ながら調整できて便利です。
transition-timing-functionの値(コマ送り)
値 | 内容 | steps(n,start/end)で表現すると |
---|---|---|
step-start | アニメーション開始直後に完了状態になりそのままキープ | steps(1, start) |
step-end | アニメーションが完了するまで初期状態で、完了時にいきなり完了状態になる | steps(1, end) |
steps(n, start) | step-startをn(任意の数)で分割してコマ送りアニメーション | - |
steps(n, end) | step-endをn(任意の数)で分割してコマ送りアニメーション | - |
steps()の指定方法
transition-timing-function: steps(10,start);
CSS Transitionのイベントを取得する
Transitionのイベント | 発生タイミング |
---|---|
transitioncancel | CSS Transtionのキャンセル時 |
transitionend | CSS Transtionが完了時 |
transitionrun | transition-delay開始時 |
transitionstart | transition-delayの終了時 |
moveTarget.addEventListener('transitioncancel', () => {
console.log('Transitionがキャンセルされました。');
});
moveTarget.addEventListener('transitionend', () => {
console.log('Transitionが完了しました。');
});
moveTarget.addEventListener('transitionstart', () => {
console.log('Transitionが始まりました。');
});
moveTarget.addEventListener('transitionrun', () => {
console.log('Transitionが始まります。');
});
CSS Transitionの対象プロパティが複数の場合
対象プロパティの数だけ同じイベントが発生してしまうので、取得対象プロパティを絞ります。
例:transformプロパティだけに絞った場合
moveTarget.addEventListener('transitioncancel', () => {
if (event.propertyName == 'transform') {
console.log('Transitionがキャンセルされました。');
}
});
moveTarget.addEventListener('transitionend', () => {
if (event.propertyName == 'transform') {
console.log('Transitionが完了しました。');
}
});
moveTarget.addEventListener('transitionstart', () => {
if (event.propertyName == 'transform') {
console.log('Transitionが始まりました。');
}
});
moveTarget.addEventListener('transitionrun', () => {
if (event.propertyName == 'transform') {
console.log('Transitionが始まります。');
}
});
CSS Animation
CSS Animation開始のきっかけを作る
ページのローディングアニメーションなどのように、きっかけが不要な場合もあります。
クラスの着脱
例:動作ボタンを押すとボックスがアニメーションのループを開始し、再度押すとアニメーションが終了して初期状態に戻るアニメーション
<div class="box" id="js-moveTarget"></div>
<button id="js-moveSwitch">動作ボタン</button>
.box{
background-color: #e74c3c;
width: 100px;
height: 100px;
}
.box.active{
animation: moveTest 4s ease-in-out 0s infinite alternate-reverse none running;
}
@keyframes moveTest {
0% {
background-color: #e74c3c;
}
50% {
transform: scale(2) rotate(10deg) translateX(200px);
background: red;
}
100% {
transform: scale(1) rotate(0deg) translateX(0px);
background-color: #2ecc71;
}
}
const moveTarget = document.getElementById("js-moveTarget");
const moveSwitch = document.getElementById("js-moveSwitch");
const moveAction = ()=>{
moveTarget.classList.toggle("active");
}
moveSwitch.addEventListener("click",moveAction);
CSS Animationで利用できるプロパティ
プロパティ | 内容 |
---|---|
animation | 下記の8つのプロパティをまとめて設定できる |
animation-name | 適用するキーフレームアニメーション名を指定 |
animation-duration | アニメーション開始から終了までの時間を指定(単位はs、ms) |
animation-timing-function | アニメーションのイージングの種類を指定 |
animation-delay | アニメーション開始までの時間を指定(単位はs、ms) |
animation-iteration-count | アニメーションのループ回数を指定(数字/infinite) |
animation-direction | アニメーションの再生方向を指定(normal/reverse/alternate/alternate-reverse) |
animation-fill-mode | キーフレームアニメーションで指定したプロパティをアニメーション開始前、終了後に適用するかどうかの指定(none/forwards/backwards/both) |
animation-play-state | アニメーションを再生中か一時停止にするかの指定(running/paused) |
animationプロパティでまとめて指定する場合
/* animation: animation-nameの値 animation-durationの値 animation-timing-functionの値 animation-delayの値 animation-iteration-countの値 animation-directionの値 animation-fill-modeの値 animation-play-stateの値
animation: anime1 2s ease -2s infinite alternate both running;
複数のアニメーションを連続する場合
カンマ区切りで、複数のアニメーションを指定できます。
animation-delayを調整して、アニメーションが連続再生されるようにします。
次のアニメーションに状態を引き継ぐので、animation-fill-modeはforwardsかbothにしてください。
変更するプロパティは、前のアニメーションの最後と次のアニメーションの最初の数値を合わせます(未指定の場合は初期値)。
animation:
anime1 1s ease 0s 1 alternate forwards running,
anime2 1s ease 1s 1 alternate forwards running,
anime3 1s ease 2s 1 alternate forwards running;
animation-timing-functionの値
値 | 内容 | cubic-bezierで表現すると |
---|---|---|
ease | 開始と完了を滑らかにする(初期値) | cubic-bezier(0.25, 0.1, 0.25, 1.0) |
linear | 一定速度 | cubic-bezier(0.0, 0.0, 1.0, 1.0) |
ease-in | ゆっくり始まる | cubic-bezier(0.42, 0, 1.0, 1.0) |
ease-out | ゆっくり終わる | cubic-bezier(0, 0, 0.58, 1.0) |
ease-in-out | ゆっくり始まってゆっくり終わる | cubic-bezier(0.42, 0, 0.58, 1.0) |
cubic-bezier | 指定による | - |
cubic-bezierの指定方法
/* cubic-bezier(x1, y1, x2, y2); */
cubic-bezier(0.42, 0, 0.58, 1.0);
Chrome DevToolsのcubic-bezierの前のアイコンをクリックすると、設定したイージングの動きを見ながら調整できて便利です。
animation-timing-functionの値(コマ送り)
値 | 内容 | steps(n,start/end)で表現すると |
---|---|---|
step-start | アニメーション開始直後に完了状態になりそのままキープ | steps(1, start) |
step-end | アニメーションが完了するまで初期状態で、完了時にいきなり完了状態になる | steps(1, end) |
steps(n, start) | step-startをn(任意の数)で分割してコマ送りアニメーション | - |
steps(n, end) | step-endをn(任意の数)で分割してコマ送りアニメーション | - |
steps()の指定方法
animation-timing-function: steps(10,start);
CSS Animationのイベントを取得する
Transitionのイベント | 発生タイミング |
---|---|
animationend | CSSAnimationend完了時 |
animationiteration | CSS Animationendの繰り返し時 |
animationstart | CSS Animationend開始時 |
moveTarget.addEventListener('animationend', () => {
console.log('Animationが完了しました。');
});
moveTarget.addEventListener('animationiteration', () => {
console.log('Animationが繰り返されました。');
});
moveTarget.addEventListener('animationstart', () => {
console.log('Animationが開始しました。');
});