CSS / animation

transition を使ってアニメーションを実装する

─ Guide to page sections ─

CSS だけで本格的なアニメーションを組み立てる場合、メインの動きに付随して、あるパーツを段階的に消したり、出現させたり、移動させたりと細かな動きが時差をもって同時進行する必要がある。そのひとつひとつの方式をモジュールとして扱うことができるのが「:checked」をトリガーにした「transition」であると思う。

完成イメージ
このページのケーススタディになるアニメーション(タップして確認)

First

transition(遷移)とは

上のように、ボタンにマウスポインターを乗せたときに、ハイライトさせたい。こういう場面でトランジションを使うと、とても簡単に機能する。

<nav style="margin: 1em 0;">
  <a href="#">button A</a>
  <a href="#">button B</a>
</nav>
    
nav a {
  flex: 1;
  background-color: #777;
  color: #fff!important;
  font-size: 12px;
  border: 1px solid;
  padding: 0.5rem;
  text-align: center;
  text-decoration: none;
  transition: all 0.5s ease-out;
}

nav a:hover,
nav a:focus {
  background-color: #6495ED;
  color: #fff;
  border: solid 1px #ccc;
  text-decoration: none;
}

CSS トランジションは、 CSS プロパティが変化する際の速度を操作する手段を提供する。

先頭に掲げるページでは、アニメーションが発動する前の画面(A)とアニメーション後の画面(B)を用意し、(A)にトランジションを定義する。

(A)の画面には、アイテムとして、画像、ボタン、タイトル、サブタイトルが配置されている。(B)の画面にはブルーの背景とテキストが配置される。そのひとつひとつを対象にアニメーションを仕掛けることができるのが「:checked」をトリガーにしたトランジションである。

transition
トランジションを定義する

CSS トランジションは、アニメーションを開始する時間、トランジションの持続時間、およびタイミング関数を定義してアニメーションするためのプロパティを決定する。

    

transitionプロパティ(ショートハンド)

    

transition: の設定は、変化の始まる方の要素に記述する。以下の例は「 2 秒遅延後に 3 秒間のアニメーションをゆっくり実行する」という定義の構文である。

    
transition:all 3s 2s ease-out;

Second

transition で使えるトリガー

transition を使用してアニメーションを実行するためには、トリガーという発火点が必要である。お馴染みのものに hover があり、ポインティングデバイスが要素に触れて発動する。

:hover をトリガーにする

<div class="activation"></div>

<style>
.activation{
  width:30px;
  height:30px;
  background-color: #fe001a;
  transition :all 1s; /* transitionの記述は:hoverの方に入れるのではなく、変化する前の方に記述する。 */
  margin-bottom: 1em;
}
.activation:hover{
  width:300px;
}
</style>

A + B(隣接セレクタ)をトリガーにする

Wow!
<div class="activation-2"></div>
<div class="this">Wow!</div>
<style>
.activation-2{
  width:30px;
  height:30px;
  background-color: red;
}
.this{
  width:60px;
  height:30px;
  background-color: silver;
  text-align: center;
  color: #fff;
  transition :all 1s;
}
.activation-2:hover + .this{
  width:300px;
}
</style>
    

A ~ B(要素の後ろにある同じ階層のセレクタ)をトリガーにする

哲学は、知識の所有であるよりも所有への行程であり、従って哲学することを措いて哲學はないのである。
<div class="activation-3"></div>
<div class="normal">…</div>
<div class="normal">…</div>
<div class="normal">…</div>
<div class="target">哲学は、知識の所有であるよりも所有への行程であり、従って哲学することを措いて哲學はないのである。</div>

<style>
div.normal{
  background-color: #f7f7f7;
  margin: 4px 0;
  padding: 4px;
}
.activation-3{
  width: 30px;
  height: 30px;
  background-color: #fe001a;
}
.target{
  width:300px;
  height: 140px;
  background-color: #66ccff;
  color: #fff;
  padding: .6em;
  transition :all 1s;
}
.activation-3:hover ~ .target{
  width:200px;
}
</style>

フォーム :focus をトリガーにする

<p><input type="text" id="activation-4"></p>

<style>
#activation-4{
    transition :all 1s;
  }
  #activation-4:focus{
  background-color: pink;
  }
</style>

「:checked」をトリガーにする

そして、キーになる最も重要なトリガーを演出する「:checked」がある。詳細は次のセクションで述べる。

    

Third

「:checked」を備える

先頭の画像をタップすると今回の完成ページが表示できる。

展開する画面はふたつ。トグルスイッチボタンはふたつ目の画面を開くのと閉じるのふたつ用意しなければならないが、チェックボックスの方はひとつである。

タップ(クリック)でアニメーション(transition)させるには、「:checked」を利用して、トグルスイッチ(ボタン)になるテキストや img 要素を「label」で囲むと、チェックボックスと連動したトグルスイッチが出来上がる、という構成だ。とてもシンプルで使い勝手が良い。

まず、簡単なトリガーを作ってみよう。html は以下のようになる。label要素にはテキスト、img 要素を使った画像を入れることができ、label 属性の for の値と input 要素の id の値を一致させることで紐づけする。

<div class="moves-container">
  <input type="checkbox" id="trigger">
  <label for="trigger">
    <img src="images/logo.png" width="50" height="50" class="moves">
  </label>
</div>
<style>
.moves {
  display: block;
  width: 30px;
  height: 30px;
  background: #EFCECF;
  border: 1px solid #C79A9B;
  margin-left: 0;
  transition: all 1s;
}
#trigger { /* サンプルは表示 */
  display: none;
}
#trigger:checked ~ label .moves {
  transform: translate(200px);
  width: 100px;
  height: 100px;
  background: #F17C7E;
}
</style>

Fourth

複数アニメーションのメカニズム

チェックボックスの「:checked」と、階層構造でセレクタを指定する「 > (子を指定する)」や「 + (兄弟で弟を指定する)」や「 ~ (兄弟で離れている弟も指定できる)」などを組み合わせて、数種類のアニメーションを設定することができる。

以下は「:checked」が ON になった「.wrapper .cover」のアニメーションを定義したひとつの例である。

ON になると表示されていた(opacity:1;)「.wrapper .cover」が上方(transform:translateY(-100%);)へ移動しつつ、徐々に消滅(opacity:0;)していく。「transition:all .6s ease-in-out .4s;」を定義しているので、0.4 秒遅延させてから 0.6 をかけてゆっくり開始してゆっくり終了する。

次のセクションではトグルボタンが押されたときの複数のアニメーションを実践で挙動を確認することができる。

.toggle:checked + .wrapper .cover{
  opacity:0;
  transform:translateY(-100%);
}
.wrapper .cover{
  width:100%;
  height:auto;
  opacity:1;
  transform:translateY(0);
  transition:all .6s ease-in-out .4s;
}

Fifth

ON で複数のアニメを発動する

さて、実践に入ろう。まず、トグルボタンを押しても何も発生しない「ベースの」ページを用意した。このページではトグルボタンを押す度にチェックボックスのチェックが ON と OFF を繰り返す。

    

このベースのページに以下のアクションを CSS で加える。トグルボタンが押されると以下のアクションを発動する。(リンクは CSS をフィックスしたもの)

これをひとつひとつ CSS にすると以下のようになる。

CSS の最後に記述されている「.wrapper .overlay」(青色背景とテキスト)は、最初はトグルがオフの場合は、「transform:scale(0);」と定義しているから消えているが、トグルがオンになると、「.toggle:checked + .wrapper .overlay{ transform:scale(1);」の設定により、表示される。尚、「.wrapper .overlay」は「transition:all 1s ease-in-out 0s;」が定義されているから、表示されるときは「transform:scale(0);から「transform:scale(1);へ」アニメーションすることになる。

<body>
 <input class="toggle" id="toggle" type="checkbox">
  <!-- wrapper -->
  <div class="wrapper">
    <!-- cover photo -->
    <div class="cover"> <img class="image" src="images/jaco.jpg" alt="Jaco Pastorius"> </div>
    <!-- //cover photo -->
    <div class="content">
      <!-- 発動ボタン --><label class="label" for="toggle"><i class="fa fa-arrows-h"></i></label>
      <!-- //発動ボタン -->
      <div class="subtitle"><small>ジャズ・フュージョンの革命的ベース奏者</small></div>
      <div class="title">Jaco Pastorius<br></div>
    </div> 
    <!-- blue screen -->
    <div class="overlay" style="padding-top: 4rem;"> <label class="close" for="toggle">&times;</label>
      <div class="explain">
        <p>ジャコのトレードマークにもなっている「Bass Of Doom」と名付けられたベースギターは、1970年代前半にフレットレスに改造された。フレットが抜かれた指板にはパテ埋めを施し、指板全体には「マリーン・エポキシ」を塗布、乾燥後には強く硬化するためエポキシ樹脂製のクリア塗料が塗られた。</p>
      </div>
    </div>
    <!-- //blue screen -->
  </div>
  <!-- //wrapper -->
</body>
/* -- トグルがオンになるとブルー背景画面が表示する -- */
.toggle:checked + .wrapper .overlay{ 
  transform:scale(1);
}
/* -- トグルがオンになると画像が上方へ移動し消滅する -- */
.toggle:checked + .wrapper .cover{
  opacity:0;
  transform:translateY(-100%);
}
/* -- トグルがオンになるとボタンが消滅する -- */
.toggle:checked + .wrapper .content .label{
  transform:scale(0);
}
/* -- トグルがオンになると背景青色の文字列が表示する -- */
.toggle:checked + .wrapper .overlay .explain p {
  opacity:1;
  transform:translateY(0);
}
/* 初期は transform:scale(0); で非表示 */
.wrapper .overlay{
  top:0;
  left:0;
  right:0;
  bottom:0;
  padding:15px;
  position:absolute;
  transform:scale(0);
  transition:all 1s ease-in-out 0s;
}