CSS3 transitionのまとめ
個人的に使うことがとても多いCSS3のtransition。
細かい設定をするとなると忘れてしまっている事柄もあるので整理してまとめておきます。
<目次>
- transitionができること
- transitionが適応できるcssプロパティ
- 対応ブラウザ
- 各プロパティの概要・構文
- プロパティ値の数による注意
- transitionendイベント
- まとめ
- 参考記事
transitionができること
変更前と変更後の間の状態をアニメーションで結んでくれます。
例えばこちらのMDNのデモでは、マウスオーバーすると背景色と文字色が反転しますがその変化をtransitionを用いて滑らかに見せています。
transitionが適応できるcssプロパティ
基本的に数値で指定するプロパティは適応できます。
詳細はCSS animatable propertiesを参照。
対応ブラウザ
IEは10以上、それ以外のモダンブラウザでは基本的に問題なく使用できます。
ベンダープレフィックスに関してはandoroidだと4.3までは-webkit-が必要になります。
案件の要件に合わせて-webkit-を付けるか否か判断すればよいでしょう。
そのほか細かい問題として、IE11だとSVGのfillプロパティに対して、IE(10と11)だとbackground-sizeプロパティに対して、transitionが効かない等の問題があります。
詳しくはCan I useをご確認ください。
各プロパティの概要・構文
transition-property
トランジションを適応(アニメーション)させたいプロパティを指定する。
selector1 { transition-property: all; /* 初期値。トランジションが適応できる全てのプロパティでアニメーションさせる */ } selector2 { transition-property: none; /* どのプロパティもアニメーションしない */ } selector3 { transition-property: color, opacity[, <propertyName>[,...]]; /* 複数指定の場合はカンマで区切る */ }
transition-duration
トランジションが完了するまでの時間。
単位はs
(秒)、もしくはms
(ミリ秒)。
selector1 { transition-duration: 0s; /* 初期値。実質アニメーションさせない意味なのでほぼ使わない */ } selector2 { transition-duration: .3s(300ms); /* 0.3秒(300ミリ秒)アニメーションさせる */ } selector3 { transition-duration: .2s, 1s[, <time>[,...]]; /* 複数指定の場合はカンマで区切る。transition-propertyの値の数によって適応され方が異なる */ }
transition-timing-function
3次ベジェ曲線を指定します。
基本的にはイージングと考えれば良いと思います。
プロパティ値 | 動き方 |
---|---|
ease | 初期値 |
linear | 等速 |
ease-in | 開始がゆっくり |
ease-out | 終了がゆっくり |
ease-in-out | 開始と終了がゆっくり |
step-start | 開始時に終了時点へ |
step-end | 終了時に終了時点へ |
steps(<number>,start) | <number>段階で変化。開始時に1段階目実行 |
steps(<number>,end) | <number>段階で変化。終了時に<number>段階目実行 |
cubic-bezier(.69,-0.33,.34,1.27) | 任意のベジェ曲線を指定 |
selector1 { transition-timing-function: ease; /* 初期値 */ } selector2 { transition-timing-function: ease, linear[, <function-name>[,...]]; /* 複数指定の場合はカンマで区切る。transition-propertyの値の数によって適応され方が異なる */ }
分かりやすいようにデモを作成してあります。
stepsの考え方に関しては、下記の図が分かりやすいです。
https://www.w3.org/TR/css3-transitions/#transition-timing-function-propertyより引用
また任意のイージングを作ることができるcubic-bezier(...)
は動きにこだわりたい時に重宝します。
数値を直接打ち込んで動きを作成するのはとても大変なので、下記のようなwebツールを利用すると良いでしょう。
具体的な使い方としては、Easing Function 早見表を見てざっくりとした動きの目安を決めて、その数値をcubic-bezier.comで微調整するのがおすすめです。
transition-delay
トランジション実行までの遅延時間。
単位はtransition-duration
と同じs
(秒)もしくはms
(ミリ秒)。
selector1 { transition-delay: 0s; /* 初期値。遅延することなく即実行されます。 */ } selector2 { transition-delay: 1s, 2s[, <time>[,...]]; /* 複数指定の場合はカンマで区切る。transition-propertyの値の数によって適応され方が異なる */ }
このプロパティは使い方次第では非常に強力なアニメーション効果をもたらします。
こちらもわかりやすいようにデモを作成しました。
demo1から順に少しずつ複雑になっていますが、transition-delay
を使えば簡単に実装できます。
demo1ではtransition-property
にheight
とwidth
を指定し、widthだけ.5s
、トランジションの実行を遅らせています。
demo2では各<li>
要素に対して.2s
ずつトランジションの実行を遅らせています。
こういった見せ方の場合は、JavaScriptのループ処理でtransition-delay
を指定すると修正が楽です(sassのfor文でもできますが、要素の数を指定しないとならないのが難点)。
demo3もdemo2と同じことをしています。
transition-duration
の時間との組み合わせで4辺のラインが一筆書きのようにつながって見えるようにしているのですが、この辺りはtransitionの話とは少し違うので、後日別の形でまとめたいと思います。
transition
上記4つのプロパティをまとめて指定できるため最もよく使うショートハンドプロパティです。
これまでのデモでは便宜上、transition-property
とか細かく設定していましたが、実際はtransition
プロパティだけで事足りることが多いです。
使用する上で最低限必要となるのはtranstion-duration
の値で、値を省略したプロパティは、各々の初期値が適応されます。
selector1 { transition: none; /* アニメーションさせない。transition-prperty: none;と同じ意味 */ } selector2 { transition: 1s; /* 下記と同じ意味 transtion-property: all; transition-duration: 1s; transition-timing-function: ease; transition-delay: 0s; */ selector3 { transition: width 1s linear, height .5s ease-in 1s[,...]; /* 複数指定の場合はカンマで区切る。(改行すると分かりやすい) */ /* 下記と同じ意味 transtion-property: width, height; transition-duration: 1s, .5s; transition-timing-function: linear, ease-in; transition-delay: 0s, 1s; */ }
こちらも簡単なデモを作成してあります。
transitionは指定値の順番が重要で、最初に指定した時間の値はtransition-duration
の値として解釈され、2番目の時間の値はtransition-delay
の値として解釈されます。
プロパティ値の数による注意
transition-propertyの値の数が、他のtransitionプロパティの値と異なる場合、数の大小によって異なる適応され方になります。
基本的には、よしなにうまいこと処理しようとしてくれます。
selector1 { transition-property: color, height, width, opacity; transition-duration: 2s, 4s; /* 下記と同じ意味(繰り返し) transition-property: color, height, width, opacity; transition-duration: 2s, 4s, 2s, 4s; */ } selector2 { transition-property: width, opacity; transition-duration: 2s,3s,4s,5s; /* 下記と同じ意味 (切り捨て) transition-property: width, opacity; transition-duration: 2s, 4s; */ }
transitionendイベント
transitionはアニメーションが完了した時点でtransitionendイベントが発生します。
このイベントを利用することでコールバック関数の実行が可能になります。
var elm = document.querySelector('.selector1'); elm.addEventListener('transitionend', callback, false); // コールバック関数の定義 function callback(event) { ... }
注意すべき点として、transitionが適応されるプロパティの数だけイベントが発生します。
1回だけイベントを実行させたい場合は、発生するイベントオブジェクトのプロパティを利用する必要があります。
こちらもデモを作成しました。
width
とheight
の2つのプロパティに対してtransitionendイベントが発生するため、demo1では2回コールバック関数が実行されています。
demo2ではheight
に対してのtransitionendイベントのみコールバック関数が実行されています。
クロスブラウザの問題に関して、以前はoTransitionEnd mozTransitionEnd webkitTransitionEnd transitionend
と記述することが多かったですが、今ではtranstionend
のみでよいでしょう。
もしくはやや古いandroidを心配するのであればwebkitTransitionEnd
も記述しておくと良いと思われます。
使いどころはwill-change?
正直今までtransitionendイベントは使う場面がありませんでした。
今回transitionendイベントの使いどころを考えたところ、will-change
プロパティの解除に使えそうだと思い、こちらもデモを作成しました。
下記はChromeの開発者ツールでレンダリングの状態を見ながら試してみた結果です。
各ボタンをマウスダウンしたときにwill-change: transform;
にして、transitionend
でwill-change: auto;
にしています。
GPUレイヤー(オレンジ色の線)がon/offされているのが確認できたので狙い通りの形にはできました。
まとめ
複数のプロパティに対してtransitionを使用する場合は、値の並び順、数に注意です。
transitionは手軽ながら使い方次第では複雑なアニメーションの実装が可能です。
transitionに非対応のブラウザの場合は、アニメーションはしませんが、変化後の状態は見せられますのでフォールバック(代替)をそこまで対応することなく使えるのが魅力だと感じています。