盗んで増やそう!CSSデザインの引き出し: 第2回 ステートフルに要素をアニメーションさせる

盗んで上達 CSSテクニック

サンプルファイルをダウンロード

盗むデザインアイデア

今回は参考サイト「readme」から、「ステートフルに要素をアニメーションさせる」というアイデアを盗みます。

「ステートフル」については、後ほど説明しますので、まずは、readmeのログインページにアクセスして、フォームの「Password」欄をクリックして選択してみてください。

図1 通常時 図2 「Password」欄の選択時

中央に表示されているフクロウの両手(両翼?)が、眼の位置までアニメーションで移動しましたね。

パスワードは重要な情報であるため、入力文字が他人に認識されないようにアスタリスクなどで表示されます(input要素のtype属性値に「password」が設定されている)。参考サイトでは、他人にパスワードを認識されないように「隠す」ことと、眼を覆い「隠す」ことを上手くかけていますね。

今回このアイデアを取り上げた主な理由は、このインタラクティブな動きをCSSメインで実装しているからです。

複雑なアニメーションを持つサイトや多機能なサイトは多々ありますが、通常、そのようなサイトを制作するにはそれ相応の知識が必要になってきます。ですが、参考サイトのような「ステートフルなアニメーション」であれば比較的容易に実装することができ、この記事の想定読者でも十分実装可能なレベルといえます。

ステートフルなアニメーションとは

広義に解釈すると、アニメーションは次の2つに分類できます。

※点滅などの繰り返しアニメーションもステートフルなアニメーションの1つとします。

ここで言う「ステートフルなアニメーション」とは「現在の状態からあらかじめ定義された状態への動き」を指し、一方「動的なアニメーション」とは「現在の状態からあらかじめ定義されていない(定義できない)状態への動き」を指します。

「ステートフルなアニメーション」の例としては、クリックによるマウスの開閉アニメーションが挙げられます。開閉アニメーションは、以下の2つの状態を“あらかじめ定義することが可能”です。

このように「動きのパターン(数)を想定できる」タイプのアニメーションを「ステートフル(stateful:状態を持っている)なアニメーション」と呼びます。

「動的なアニメーション」の例としては、マウスに追従するアニメーションが挙げられます。マウスに追従するアニメーションは、次の状態を“あらかじめ定義することが不可能”です。

「事前に動きのパターン(数)を想定できない」タイプのアニメーションを「動的なアニメーション」と呼びます。

状態をあらかじめ定義できることの強み

前項では、「あらかじめ状態を定義することが可能か、不可能か」の観点でアニメーションを「ステートフルなアニメーション」と「動的なアニメーション」に分類しました。では、“あらかじめ定義することが可能”と“あらかじめ定義することが不可能”との違いは何でしょうか?

そもそも、みなさんはCSSを記述する過程において、

などと考えながら作業していますよね。この過程は、

と、“事前にデザインパターンを想定”しながらスタイルを定義しているということであり、あらかじめ動きのパターンを想定できるタイプの「ステートフルなアニメーション」と非常によく似ていますね。

次項で説明しますが、CSSで要素をアニメーションさせることが可能です。そのため、「ステートフルなアニメーション」であればCSSとの親和性が高く、実装することができるのです。

“あらかじめ定義することが可能”と“あらかじめ定義することが不可能”との違いの1つとして、この「CSSとの親和性」が挙げられます。

鍵となるtransitionsプロパティ

前説が長くなりましたが、CSSでステートフルに要素を動かすための鍵となる技術はtransitionsプロパティです。transitionsは、CSSプロパティの値の変化をアニメーション表示するためのプロパティです。

背景色が赤色の要素があるとして、この背景色を青色に変更した場合、通常であれば一瞬で赤色から青色に変化します。transitionsプロパティは、この赤色から青色への移り変わりをアニメーション表示させます。今回紹介するプロパティは次の3つです。

transition-propertyは、アニメーションが適用されるCSSプロパティを指定するためのプロパティです。複数指定したい場合は、カンマ区切りでCSSプロパティを列挙します。また、allを指定すると、アニメーション可能なCSSプロパティすべてが適用対象になります。

// 背景色と文字色をアニメーション対象にします div { transition-property: background-color, color; } // アニメーション可能なCSSプロパティすべてを対象にします div { transition-property: all; } // 何も指定しない div { transition-property: none; }

transition-durationは、アニメーション時間を指定するためのプロパティです。

// 2秒かけてアニメーションさせます div { transition-duration: 2s; }

transition-timing-functionは、アニメーション開始から終了までの間の変化具合を指定するためのプロパティです。見慣れないプロパティですが、イージングやトゥイーンと同様の効果を発揮します。ここでは詳しく説明しませんが、変化具合を数値指定する方法も用意されています。

// 最初は速く、最後はゆっくり div { transition-timing-function: ease-out; } // 数値指定する div { transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1); }

これらのCSSプロパティを使いサンプルを作ってみましょう。

サンプルでアイデアを試す

それでは、参考サイト「readme」と似たページをひな形から作成してみましょう。デモ完成形は以下のように、「Password」欄を選択したら上部に黒地の領域がフェードインで表示され、選択を解除したらフェードアウトで非表示になります。

図3 「Password」欄を選択したら上部に黒地の領域がフェードインで表示され、選択を解除したらフェードアウトで非表示になる

では、ひな形から作成していきましょう。

// ひな形 <!doctype html> <html lang=”ja”> <head> <meta charset=”utf-8″> <title>demo</title> <style> /* リセット */ html, body, header, footer, div { margin: 0; padding: 0; } div { width: 80%; margin: 10px auto; padding: 30px 0; color: #fff; background-color: #333; font-size: 20px; font-weight: bold; text-align: center; } input { display: block; width: 80%; margin: 10px auto; padding: 10px; border: none; border-radius: 10px; box-shadow: 0 0 5px #ccc inset; } </style> </head> <body> <div id=”panel”>secret</div> <form> <input type=”email” placeholder=”Email”></input> <input type=”password” placeholder=”Password”></input> </form> </body> </html>

「Email」欄と「Password」欄を設置し、上部には「secret」と書かれた黒地領域(div)を用意しました。まずは、黒地領域に次の2つの状態を持たせるためにCSSを編集します。

// 背景色(選択解除時) div { bacground-color: #fff; } // class「on」が付いた時のスタイルを追加(選択時) div.on { background-color: #333; }

このCSSにより、事前に状態を定義することができました。定義内容は次の2パターンになります。

さらに、「Password」欄が選択されたら黒地領域(div)にclass名「on」を付加するため、少しだけJavaScriptを追加します。

// </body>の上に次のコードを挿入 <script src=”https://code.jquery.com/jquery-2.1.1.min.js”></script> <script> var $panel = $(‘#panel’);// 黒地領域(div)の要素を取得 var $input = $(‘input[type=password]’);// 「Password」欄の要素を取得 $input.focus(function () {// 「Password」欄の選択時の処理を記述 $panel.addClass(‘on’);// 黒地領域(div)にclass名「on」を付加する }); $input.blur(function () {// 「Password」欄の選択解除時の処理を記述 $panel.removeClass(‘on’);// 黒地領域(div)のclass名「on」を取り除く }); </script>

JavaScriptについては説明を省きますが、「Password」欄の選択時と選択解除時に、黒地領域(div)に対してclass名「on」」の付け外しを行っています。

一度ブラウザーで表示させてみましょう。「Password」欄の選択・選択解除に伴って、黒地領域(div)の背景色が変化することが確認できます。

背景色が変化するようにはなりましたが、まだアニメーションが付いていないので、次はアニメーションを付けていきましょう。ここで鍵となるtransitionsプロパティを使います。

// divに追加 div { transition-property: background-color;// 背景色をアニメーション対象にする transition-duration: 1s;// 1秒かけてアニメーションさせる transition-timing-function: ease-out;// 最初は速く、最後はゆっくり }

これで黒地領域(div)がアニメーション付きで変化するようになりました。以下、デモの完成系です。

<!doctype html> <html lang=”ja”> <head> <meta charset=”utf-8″> <title>demo</title> <style> /* リセット */ html, body, header, footer, div { margin: 0; padding: 0; } div { width: 80%; margin: 10px auto; padding: 30px 0; color: #fff; background-color: #fff; font-size: 20px; font-weight: bold; text-align: center; transition-property: background-color; transition-duration: 1s; transition-timing-function: ease-out; } div.on { background-color: #333; } input { display: block; width: 80%; margin: 10px auto; padding: 10px; border: none; border-radius: 10px; box-shadow: 0 0 5px #ccc inset; } </style> </head> <body> <div id=”panel”>secret</div> <form> <input type=”email” placeholder=”Email”></input> <input type=”password” placeholder=”Password”></input> </form> <script src=”https://code.jquery.com/jquery-2.1.1.min.js”></script> <script> var $panel = $(‘#panel’); var $input = $(‘input[type=password]’); $input.focus(function () { $panel.addClass(‘on’); }); $input.blur(function () { $panel.removeClass(‘on’); }); </script> </body> </html>

最後に

ステートフルに要素をアニメーションさせるアイデアを紹介しました。今回は、JavaScriptを多用せずに簡単に実装できる方法として、数個のtransitionsプロパティだけを使う方法を用いましたが、他にも方法はあります。また、アニメーションさせる対象を変更するだけでも、もっと面白い見せ方ができるかもしれません。最初の一歩として、今回紹介した内容を参考にしていただければと思います。