CSS を使ったフルページ アニメーション
Internet Explorer 10 Developer Preview では、Internet Explorer 9 でサポートが導入された CSS 2D Transforms に加えて新たに CSS 3D Transforms (英語) と CSS Animations (英語) のサポートが追加されました。GPU の能力を活用して通常の JavaScript から非同期で実行される IE10 のこれらの機能は、スクリプトを使った従来の Web コンテンツ用アニメーションに対する、よりパフォーマンス効率に優れた、より柔軟な代替方法となります。
以前のブログ記事では CSS 3D Transforms、さらには CSS Animations および Transitions について紹介しました。今回の記事では、こうしたテクノロジの掟破りとも言える使用方法を紹介します。説明するのは "フルページ アニメーション" の概念で、これをナビゲーション プロセス中に使うことで、ブラウジングに滑らかさと連続性を加えることができます。今回の目標は、ユーザーが訪れたページの視界にコンテンツがスムーズに表示され、リンクのクリックや関連付けられた操作の実行に合わせてページが遷移しながら消えるのを、シームレスなブラウジング エクスペリエンスとして提供することです。
これらの効果は CSS Animations を使って HTML の <body>
要素を変形させることで実現されます。一方、このような使用方法には、レイアウトへの影響や <body>
を変形させる際のサイズ、ページ ナビゲーションのタイミングを適切に設定してナビゲーションとアニメーションと意図通りに連携させる方法などいくつかの考慮事項があるため、これらについても説明します。
この記事のコード サンプルでは、IE10 Release Preview がサポートする、プレフィックスのない CSS マークアップを使用しています。その他のブラウザーで CSS Animations と CSS Transforms のプロパティを使う場合、ベンダー プレフィックスが必要になる場合があります。
ページのコンテンツ全体を変形させる
CSS Transforms は HTML DOM 要素のスタイル関係のプロパティで定義されます。たとえば、要素を Z 軸上で 45°回転させるマークアップは以下のようになります。
#element {
transform: rotateZ(45deg);
}
HTML ドキュメントの <body>
要素に変形をアタッチしてもまったく同じ動作が発生します。つまり、同じ効果をドキュメントの <body>
に追加する記述は、以下のようなマークアップになります。
body {
transform: rotateZ(45deg);
}
body 要素に変形を適用する前と適用した後のページのスクリーンショットを見てみましょう。
ドキュメントの body 要素に rotateZ(45deg) の変形を適用する。
3 次元の変形には、CSS Transforms 仕様が定義する perspective
プロパティを、変形させる要素の親に指定します。コンテンツの <body>
要素を変形させる場合、DOM 階層でその上位に配置される <html>
要素に対してこのプロパティを適用します。以下のとおりとても単純です。
html {
perspective: 500px;
}
この変形と <body>
要素の rotateY(45deg)
の変形を組み合わせると、以下のような効果になります。
rotateY(45deg) の変形を <body> に適用し、perspective: 500px を <html> に設定する。
body 要素の transform-origin
プロパティを変化させると面白い効果が生まれます。いくつか例を見てみましょう。
body {
transform-origin: 50% 100%;
transform: rotateX(45deg);
}
このマークアップは、body 要素に X 軸上の回転を設定すると同時に、transform-origin
を使って回転の原点を要素の下方向に移動しています。これによってドキュメントのコンテンツは、以下のように画面の奥に向かって回転します。
ドキュメントのルート要素で perspective-origin
プロパティを変化させると、不等角投影の効果を適用できます。<html>
のスタイルを以下のように変更してみます。
html {
perspective: 500px;
perspective-origin: 90% 50%;
}
ページは以下のように表示されます。
CSS Transforms を使ってページ コンテンツ全体の表示を簡単に変化させられるようすをご紹介しました。レイアウトやサイズに関する通常の規則がそのまま当てはまるので、body 要素の変形によって (パーセント値や transform-origin
プロパティを使う変形の場合は特に)、ページ上のコンテンツに応じたさまざまな視覚効果を実現できます。transform-origin
を 50% 100%
に設定した rotateX(45deg)
の例をもう一度見てみましょう。
以下は、変形を適用する前と適用した後のページのスクリーンショットです。
コンテンツの基点がウィンドウの底辺ではなくビューポート外の点であることにご注目ください。これが CSS Transforms の動作です。<body>
は、通常どおり配置された後に、画面外に配置された底辺上で回転しています。また、コンテンツの実際の使用領域も広くなっています (適用後のスクリーンショットのスクロール バーを見るとわかります)。これは変形後のコンテンツをすべて表示するための処理です (ここで透視投影を使っていることも、この処理がわかりやすく強調される一因でもあります)。
このように、body 要素に変形を適用するとコンテンツが任意のサイズで変化しますが、この変化に対応する方法を説明します。すべてのコンテンツを独自に調整して、body のサイズを一定の枠内に収めようとするのは現実的ではありません。ここでは、シンプルな HTML/CSS パターンを使って body 要素のサイズをブラウザー ウィンドウのサイズに合わせて変更し、ラッパー <div>
の中にコンテンツを追加します。これを行うシンプルなマークアップは以下のようになります。
html, body {
width: 100%;
height: 100%;
min-width: 100%;
max-width: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
#Wrapper {
position: absolute;
width: 100%;
height: 100%;
overflow: scroll;
}
以下のスクリーンショットは、rotateY(45deg)
の変形をドキュメントの <body>
要素に直接適用した場合 (左) と、ラッパー パターンを使った場合 (右) で、ページを上下方向にスクロールしたようすです。
変形を直接適用した場合の表示は、不等角投影によって斜めがきつくなっています (これは私たちが既に body 要素の "中心" を見ていないためです)。ラッパー パターンを使うと、<html>
要素の perspective-origin
プロパティ (既定値は 50% 50%
) が常に <body>
要素の中心に配置されることによって、適切な視覚効果が得られるようになります。
可能な限りこのパターンを使い、さらに CSS Transforms をパーセント値で設定することで、コンテンツのサイズに関係なく、<body>
要素の変化に一貫性を持たせることができます。
Transforms から Animations へ
CSS Transforms を <body>
要素に適用する際の考慮事項を整理できたら、次のステップは CSS Animations です。これまで説明した原則に従って、Web コンテンツを視界に表示する (または視界から消す)、楽しいアニメーションを作成できます。
以下の基本的な @keyframes
規則を考えてみます。
@keyframes rotateInLeft {
from {
transform-origin: 0% 0%;
transform: rotateY(180deg);
}
to {
transform-origin: 0% 0%;
transform: rotateY(0deg);
}
}
このアニメーションを要素に適用すると、要素が左端上で回転します。先ほどのラッパー パターンを使う <body>
要素に同じアニメーションを適用すると、さらに面白い視覚効果が生まれます。ブラウザー ウィンドウの視界の外からドキュメントの回転が始まり、その後すべてが表示されるようになります。
同様に Web コンテンツを視界から滑らかに消すアニメーションを構成することも可能です。たとえば、ページが回転しながら遠くに消えていくようにするには、以下のようにします。
@keyframes whirlOut {
to {
transform: scale(0)rotateZ(1260deg);
}
}
以下のような視覚効果になります。
Web コンテンツ全体に CSS Animations のすべてを適用できることで、ページ効果の選択肢はとても広くなります (また、使えるのは CSS Transforms だけにもちろん限定されません)。次は、コンテンツに適用する効果を作成した後に、作成した効果をページ ナビゲーション プロセスの中でトリガーする方法を考えてみましょう。
アニメーションを <body> にアタッチする
目標は、ブラウザー エクスペリエンスの意図したタイミングでアニメーションがトリガーされ、コンテンツが遷移しながら視界に表示され、リンクがクリックされたらコンテンツが遷移しながら消えるようにすることです。
body 要素にアニメーションを追加する場所として最初に思いつくのは onload
JavaScript イベントかもしれません。ただし実際は onload
の起動時でのアニメーション適用は遅すぎます。このイベントは、(画像やその他の帯域幅を多く消費するリソースを含む) ページ コンテンツ全体の読み込み完了時にトリガーされます。帯域幅を多く消費するページの onload
イベントにアニメーションを追加すると、コンテンツが通常どおり表示された後にアニメーションがトリガーされ、コンテンツが視界にもう一度表示されるような処理になります。これは適切な効果ではありません。
ここでは、ブラウザーによるコンテンツの DOM 構造の解析完了時 (ただしリソース読み込みは完了していない可能性が高い) にトリガーされる DOMContentLoaded
イベントを使うことができます。これら 2 つのイベントの違いは、IE Test Drive の DOMContentLoaded
のデモ (英語) でご覧いただけます。ただし複雑な Web コンテンツで最新ブラウザーが "プログレッシブ レンダリング" を実行する場合は、DOM ツリー全体の読み込み完了よりも前にページが表示されます。こうした場合の視覚効果は onload
のときと同様になります。
ページ コンテンツが遷移しながら視界に表示されるアニメーションを設定する最適な場所は、<body>
要素の最上位のインラインです。これによってコンテンツのレンダリング中にアニメーションが開始されるようになります (さらに、コンテンツの開始位置が、選択したアニメーションの from
キーフレームの開始位置になります)。複雑なコンテンツで発生するプログレッシブ レンダリング、再レイアウト、リソースの読み込みがアニメーションによってマスクされることも、この手法で得られるプラスの効果です。
コンテンツが視界から遷移して消えるアニメーションの設定も興味深い処理になります。この場合、コンテンツ内で対象となる要素すべて (すべての <a>
タグなど) に onclick
ハンドラーをアタッチして、関連するアニメーション プロパティ (animation-name
、animation-duration
など) をコールバック関数に設定するだけでよいと考えるかもしれませんが、実際には、期待どおりの滑らかな遷移を表示させるには、ナビゲーションの発生を遅らせることが必要になります。
ここで活用できるのが、CSS Animations 仕様が規定するアニメーション イベント (英語) です。特に animationend
イベントを使ってアニメーションの完了を検出し、(たとえば window.location.href
を使って) ナビゲーションをトリガーすることができます。これによって onclick
によって視界から消えていくアニメーションがトリガーされ、animationend
のハンドラーが <body>
に登録され、目的のナビゲーション イベントが発生するようになります。
ライブ デモをご覧ください
私たちが作成した、CSS Transforms と Animations を使った動きのあるページのデモンストレーションとチュートリアル (英語) では、この記事以上に充実した説明と豊富な例をご覧いただけます。このチュートリアルのページ ナビゲーションで使われているフルページ アニメーションは、Windows 8 の Internet Explorer 10 の他、Chrome と Firefox の最新バージョンで動作します。
各ページの右下にある [Continue to ~] のリンクを使って各ページを進めていくと、ページ間のアニメーションだけをご覧いただくことができます。
チュートリアルの最後では、これらのアニメーションを皆さんの Web コンテンツに組み込む際の追加のガイダンスとサンプル コードを紹介しています。
まとめ
CSS Transforms と CSS Animations の 2 つの強力な機能セットを通して、よりリッチで没入的な Web エクスペリエンスを実現できます。今回のブログ記事では CSS Transforms と CSS Animations を使って Web コンテンツ全体に動きを与える際の考慮事項を紹介しました。ほんのわずかな手間だけで、アプリにも似た滑らかなエクスペリエンスを (静的なページを含む) Web ページに適用できることがおわかりいただけたと思います。
—Internet Explorer グラフィックス担当プログラム マネージャー インターン、Charilaos “Harris” Papadopoulos