May 02, 2010
CSS Transitions(CSSだけで簡単なアニメーション)の使い方・覚え方のまとめ
いろんな人がいろんな解説を既に書いてるみたいだけど、ツリー型タブでタブのインデントや折り畳みのアニメーションをCSS Transitionsで書き直してみるにあたり、自分で書いてみるまでよく分からんかったので、理解している内容をまとめてみることにした。
CSS Transitionsのフルスペックの説明でもないし、「こんなことができるぜすげーだろ!」というデモでもない。現実的にどういう場面でどういう風に使う事ができるのか、という事を淡々と述べます。いろんな機能を詰め込んだよく分からんデモやスクリプトと組み合わせること前提の変なデモを見たせいで混乱してる僕みたいな人が、CSS Transitionsを理解するための手助けになれれば幸いです。
主な用途
マージンや色などの値を数値で表せるプロパティや、画像を表示する系のプロパティなどについて、スクリプトあるいは:hoverなどの疑似クラスによって動的に値が変化するようにしている場面で、元の状態と新しい状態の間をなめらかに変化させるようにする。
例えば、こんな風に。
ul.menu li {
transition: margin-left 0.25s ease-out;
}
ul.menu li:not(:hover) {
margin-left: 0;
}
ul.menu li:hover {
margin-left: 50px;
}
この例では、分かりやすくするために敢えて指定を分けて書いている。ここでは以下のようなことが起こっている。
- 何もしていない状態だと、
margin-left: 0;
が適用されている。 :hover
の状態になると、margin-left
が50px
になるようにアニメーションが始まる。:hover
の状態が解除されると、margin-left
が0
になるようにアニメーションが始まる。
何ができる?
- CSSだけでやれる範囲でいうと、上記のサンプルのように「:hoverになった時にぽわーんとなめらかに出てきて、
:hover
が解除されたらぽわーんとなめらかに引っ込む」ようなGUI要素をスクリプト無しで書けるようになる、という所に意義がある。例を挙げると、以下のような物が該当するだろう。:hover
の時だけ出っ張るメニュー項目が、なめらかに出っ張る/引っ込むようになる、とか。:hover
すると色が変わるボタンが、「じわっ……」と色が変わるようになる、とか。:hover
で影が付く時に、「じわっ……」と影が濃くなる、とか。- メニューが透明な状態から「じわっ……」と表示されていく、とか。
- アイコンが90°回転する時に回転がなめらかになる、とか。
- スクリプトと組み合わせて使う場合、トゥイーンのための実装が要らなくなる(ネイティブ実装に任せてしまえる)というのが多分最大のメリット。
- ポジショニングやマージンの調整で要素の表示位置を変える時、単に新しい値(=アニメーションの終了時点の値)を設定するだけでトゥイーンしてくれる。
- CSSで初期値とdurationとイージング関数を指定しておいて、スクリプトで終了値だけを動的に指定する、という使い方。
- CSSのクラスセレクタであらかじめいくつかの終了値のセットを定義しておいて、スクリプトで
className
を書き換えて終了値を間接的に指定する、という使い方。 - タイマーの管理が不要になるので、複数のアニメーションを同時に走らせる場合、アニメーションが全体的に軽くなると思われる。
- 既に前のアニメーションが行われている間にまた値を変更した場合、現在の時点の値からの変化になる。
- アニメーションの中断と再開のための面倒なコードは不要。
- 例えば、
margin-left
が0
であったのを、20px
を設定してアニメーションが始まり、20px
に向けて変化していっている最中の10px
の時点でmargin-left
を0
に再設定した場合、前のアニメーションが中断されて、新たに10px
から0
に向けて変化するアニメーションが始まる事になる。 - スクリプトでも動的疑似クラスでも。
「Windows Vista以降のAero Glass有効時のネイティブアプリのボタンみたいな物をWebに簡単に持ち込めるようにする」「GUIの端々にほんのちょっとだけ小粋なアニメーション効果を加えたい時に、スクリプトを書かなくてもよくなる」という話ですね。それ以上でもそれ以下でもないと思っておくと、CSS Transitionsを理解しやすいと思います。
何ができない?
- テレビアニメのような、長くて複雑なアニメーションは無理。滅茶苦茶頑張ればできるかもしれないけど、CSS Transitionsの仕事ではない。
- アニメーションと連動したスクリプトの複雑な制御。
- アニメーション終了時にはDOM Level2 Eventsのイベントリスナで捕捉可能な
transitionend
イベント(WebKitではwebKitTransitionEnd
)が発行されるので、アニメーションの終了だけは検知できる。 - それ以外のタイミングではイベントは発行されない(アニメーションが始まったかどうかも分からない)。
- アニメーション終了時にはDOM Level2 Eventsのイベントリスナで捕捉可能な
- 無限に繰り返すアニメーション。
- ループするアニメーションのデモではスクリプトと組み合わせていて、
transitionend
イベントを使ってその都度新しい「アニメーション終了時点の値」を設定し直してやることで、アニメーションを繰り返している。CSS Transitionsだけではループはできない。
- ループするアニメーションのデモではスクリプトと組み合わせていて、
- どんなプロパティでもアニメーションできるわけではない。仕様書(のWorking Draft)にアニメーションできるプロパティの一覧がある。
書き方
transition:
アニメーションさせたいプロパティの名前
アニメーション終了までにかける時間(省略すると0)
イージングの種類(省略するとease)
アニメーションが始まるまでの遅延(省略すると0);
これで1セットと考えると分かりやすい。複数のプロパティをアニメーションさせたい時は、
transition: margin-left 1s ease;
transition: margin-top 1s ease;
とは書けないので、カンマ区切りにして
transition: margin-left 1s ease,
margin-top 1s ease;
と書く。
アニメーション終了までにかける時間はCSS3 Values and Unitsの時間の値で指定する。例えば250ミリ秒で完了させたい時は250ms
(ミリ秒単位)または0.25s
(秒単位)と書く。アニメーションが始まるまでの遅延も同様。
イージング関数(値の変化の仕方)には、以下のいずれかを指定できる。
linear
- 等速直線運動的な変化
ease-in
- 最初はゆっくり、最後にいくにつれて激しく変化
ease-out
- 最初は激しく、最後にいくにつれてゆっくり変化
ease
- ゆっくり始まって、途中で最高速になり、最後はまたゆっくり変化
ease-in-out
ease
をもう少しきびきびさせたような感じcubic-bezier()
- ベジェ曲線でアニメーションの変化の仕方を指定
現状ではまだ仕様が固まっていなくてどのベンダも先行実装の段階なので、ベンダープレフィクス付きの指定を書いてやらないといけない。
-webkit-transition: SafariとGoogle Chrome用の指定;
-moz-transition: Firefox用の指定;
-o-transition: Opera用の指定;
transition: 仕様通りの指定;
CSS TransitionsがRecommendationになったら、ベンダープレフィクス無しの記述だけでいけるようになるはず。
wikieditish message: Ready to edit this entry.