必見の記事

HTML5 × CSS3 × jQueryを真面目に勉強 – #9 CSS3アニメーション(Transition)

2012.11.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

そんな訳で、現状イマイチ扱いに困るCSS3アニメーションについて学習した内容をまとめておくとします。

はじめに - CSS3のアニメーション機能

ひと口にCSS3アニメーションと言っても、その実装方法は以下の二種類に大きく分類されます。

  1. Transition
  2. Animation

Transitionは対象となる要素の始点終点の状態をそれぞれ定義し、その二点間をスムーズに変化させることでアニメーションを実現させるという仕組みです。

対するAnimationは始点と終点だけでなく、二点間の任意のタイミングにキーフレームを配置してその時点ごとの状態をそれぞれ指定し、よりダイナミックなアニメーションを実現させることが出来る仕組みです。

両者似ているようで異なる機能ですが、この仕組みを混同せずにキチンと押さえておけば、これといって泥沼にハマることなく習得することが出来ます(たぶん)

今回はTransitionに的を絞って進めていくとします。

Transition - 時間的変化

Transitionプロパティの詳細は、コチラのサイトにて非常に分かりやすく的確にまとまっているので、当ブログでは割愛します。

Transitonプロパティでは、以下の4つの項目をまとめて指定することが出来ます。

trantision
transition-duration アニメーションにかかる時間
transition-property アニメーションをどのプロパティに対して行うか
transition-timing-function アニメーションのタイミングやどのように進行するかを指定 (イージング)
transition-delay アニメーションが開始されるまでの時間 (遅延時間)

この順序で指定するのが必須というわけではありませんが、durationdelayの順序だけは決まっており、逆にすることが出来ません。

記述例) transition

/*
 * @transition-duration
 * @transition-property
 * @transition-timing-function
 * @transition-delay
 */
transition: .3s background ease .5s;

当記事執筆時点(2012年11月)では、このプロパティに対してベンダープレフィックスをつけて指定することになります。

ベンダープレフィックスをつけてみた - transition

-webkit-transition: .3s background ease .5s;
-moz-transition:    .3s background ease .5s;
-o-transition:      .3s background ease .5s;
-ms-transition:     .3s background ease .5s;
transition:         .3s background ease .5s;

結構行数増えるんだね、仕方ないね。
同じコードを繰り返し書くことは、デクレといったバグの要因になりかねないので、SCSS(Sass)LESSといった拡張メタ言語を積極的に活用することを強くオススメします。

Transition 事始め

マウスオーバー時にdiv要素のスタイルをアニメーションで変化させてみます。変化させるプロパティはbackgroundborder-radiusです。

transition1.css ※ベンダープレフィックスは省略していますが、実際のコードでは必要となります。

div {
  background: #e61374;
  box-shadow: 0 20px 40px #888;
  height: 150px;
  margin: 60px auto;
  padding: 15px;
  width: 150px;
  transition: 0.5s background linear, 0.3s border-radius ease-in 0.8s;
}
div:hover {
  background: #ccff00;
  border-radius: 50%;
}

transition1.html

<div>
  <dl>
    <dt>background</dt>
    <dd>#e61374 -> #ccff00</dd>
    <dt>border-radius</dt>
    <dd>0 -> 50%</dd>
  </dl>
</div>

まずアニメーションの始点となる background を2行目で指定、そして終点となるbackgroundを11行目で指定します。border-radius の始点はデフォルトのままで良いので指定はせず、終点となる border-radius の値を12行目で指定します。

次にアニメーションの設定です。backgroundとborder-radiusに対する設定をカンマ区切りでそれぞれ指定しています。このようにTransitionプロパティを一括指定するだけでなく、カンマ区切りで対象となる要素ごとに異なるアニメーションを設定することが可能となります。

transition-property

transition-propertyでアニメーションさせたいプロパティを指定することができます。デフォルトはallで、この場合は始点と終点で異なる要素全てがアニメーションで変化します。

div {
  background: #e61374;
  border-radius: 0;
  transition: 0.5s;
}

div:hover {
  background: #ccff00;  // アニメーションで変化
  border-radius: 50%; // アニメーションで変化
}

コレに対して特定のプロパティのみをtransitionに指定した場合は、そのプロパティのみがアニメーションで変化し、それ以外の項目は瞬時に状態が変化します。

div {
  background: #e61374;
  border-radius: 0;
  transition: 0.5s background;
}

div:hover {
  background: #ccff00;  // アニメーションで変化
  border-radius: 50%; // 瞬時に変化
}

transition-timing-function

Transitionのイージング機能について押さえておくとします。

ものすごく簡単に言うと、イージング機能とはアニメーションが始点から終点までの間にどのように変化するかといった進行割合のパターンを指します。あまり深く突っ込むと数学の込み入った話になるので、「イージング!そういうのもあるのか」といった程度に押さえておけば、そこまで困ることはないでしょう。

transition-timing-functionで指定できるイージングは、以下の5種類です。

transition-timing-function
ease cubic-bezier(0.25,0.1,0.25,0.1)
始点から徐々に加速し、終点間近で急激に減速する
※初期値
linear cubic-bezier(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()でオリジナルのイージングを設定することが可能です。

// 三次ベジェ曲線のP1とP2を指定
transition-timing-function: cubic-bezier(x1, y1, x2, y2);

CSS3 の機能を活かしたスライドメニューを作ってみる

最近チラホラと見かけるようになった、画面左からナビゲーションがスライドインし、同時にコンテンツ領域が画面奥に3D効果でパタンッと折れ曲がるアニメーションを作ってみます。少しトリッキーな小技も使いますが、基本的にはこれまでに紹介したテクニックを組み合わせれば何とかなります(たぶん)

完成予想イメージはこんな感じです。

ではひとつずつ実装していきます。

1 | HTMLコードを作成

sidemenu.html

<body>
  <nav>
    <h2 id="toc-menu">Menu</h2>
    <ul>
      <li><a href="#">HOME</a></li>
      <li><a href="#">PROFILE</a></li>
      <li><a href="#">WORKS</a></li>
    </ul>
    <h2 id="toc-links">Links</h2>
    <ul>
      <li><a href="#">Twitter</a></li>
      <li><a href="#">facebook</a></li>
      <li><a href="#">Google +</a></li>
    </ul>
  </nav>

  <article>
    <h1>Side menu | CSS3 samples</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, ...</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, ...</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, ...</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, ...</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, ...</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, ...</p>
  </article>
</body>

HTMLはいたってシンプルです。nav要素が画面端からスライドインするメニュー領域であり、article要素がメインコンテンツ領域となります。

2 | 見栄えの実装 - article領域

続いてCSSです。とりあえずアニメーションの実装は後回しにして、見栄えだけ組んでいくとします。

/* article
 ----------------------------------------*/
article {
  background: #fff;
  overflow: auto;
  padding: 30px 15%;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 70%;
  z-index: 0;
}

article領域をbody要素に見立てるために、positionプロパティをfixedにしてウィンドウいっぱいに表示させます。

3 | 見栄えの実装 - nav領域

nav要素はpositionプロパティで画面左に固定させ、ナビ領域の幅(14em)の分だけ左側に移動させます。

nav {
  background: #e61374;
  border-right: 28px solid #e61374;
  box-shadow: 4px 0 4px rgba(64, 64, 64, 0.4);
  cursor: pointer;
  padding: 20px 0 20px 20px;
  position: fixed;
  top: 0;
  bottom: 0;
  left: -14em;
  z-index: 10;
}
  nav:after {
    border: 15px solid;
    border-color: transparent transparent transparent #e61374;
    content: " ";
    height: 0;
    margin-top: -7px;
    position: absolute;
    top: 50%;
    right: -58px;
    width: 0;
  }

ナビ領域の右側に幅28pxのボーダーを指定してナビゲーション表示のトリガーとします。更に擬似要素をつかって三角形のアイコンを作ります。

4 | 見栄えの実装 - メニュー部分

a {
  border-radius: .2em;
  color: #fff;
  display: block;
  padding: 4px;
  text-decoration: none;
}
  a:before {
    color: #fff;
    content: "-";
    margin-right: 5px;
  }
  a:hover, a:active {
    background: #ccff00;
    color: #4d4d4d;
  }

/* ---------- Navigation menu ---------- */
  nav h2 {
    font-size: 1em;
    margin: 0;
    padding: 0;
  }
  nav ul {
    margin-top: 10px;
    padding-left: 10px;
  }
  nav li {
    list-style: none;
    margin: 0;
    padding: 3px 10px;
    width: 12em;
  }

ここまでで基本的な見栄えは実装できました。

5 | アニメーションの実装

まずは全体のトランジションを一括で設定します。

/* ---------- CSS Transition ---------- */
article,
article:after,
nav,
nav * {
  -webkit-transition: all 0.6s ease;
  -moz-transition:    all 0.6s ease;
  -o-transition:      all 0.6s ease;
  transition:         all 0.6s ease;
}

続いて各要素の動きをそれぞれ実装していきます。

6 | アニメーションの実装 - ナビゲーション領域

画面左端に隠れているnav領域を表示させます。

nav:hover {
  left: 0;
}

初期状態で-14emに設定されているleft要素をホバー時に0にします。アニメーションの設定は先ほど行ったので、コレだけです。

7 | アニメーションの実装 - article領域

まずはarticle領域が3D変形する際の原点を指定します。

※ハイライト部分を追加

/* article
 ----------------------------------------*/
article {
  background: #fff;
  overflow: auto;
  padding: 30px 15%;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 70%;
  z-index: 0;
  -webkit-transform-origin: 0 50%;
  -moz-transform-origin:    0 50%;
  -ms-transform-origin:     0 50%;
  -o-transform-origin:      0 50%;
  transform-origin:         0 50%;
}

次にnav領域がホバー時にarticle領域を3D変形するようにCSSを追記します。

nav:hover ~ article {
    -webkit-transform: perspective(600px) translateX(16em) rotateY(10deg);
    -moz-transform:    perspective(600px) translateX(16em) rotateY(10deg);
    -o-transform:      perspective(600px) translateX(16em) rotateY(10deg);
    -ms-transform:     perspective(600px) translateX(16em) rotateY(10deg);
    transform:         perspective(600px) translateX(16em) rotateY(10deg);

    background-image: -webkit-gradient(linear, 100% 50%, 0% 50%, color-stop(0%, rgba(0, 0, 0, 0.5)), color-stop(40%, #ffffff));
    background-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0.5) 0%, #ffffff 40%);
    background-image: -moz-linear-gradient(right, rgba(0, 0, 0, 0.5) 0%, #ffffff 40%);
    background-image: -o-linear-gradient(right, rgba(0, 0, 0, 0.5) 0%, #ffffff 40%);
    background-image: linear-gradient(right, rgba(0, 0, 0, 0.5) 0%, #ffffff 40%); }

nav要素の後ろにある同じ階層のarticle要素といった兄弟要素の指定がCSS3から使えるようになりました。詳しくはこちらを参照ください。

これで完成です。以下のリンクよりデモをご覧いただけます。

ここまでCSS3 Transitionの基本について紹介しました。次回はCSS3 Animationについて学んだことを綴っていきます。

参考サイト