Webデザインの教科書
- CSS 上級編 -
Scroll

CSSだけで簡単に作れる実際に使えるアニメーションの作り方

今回はCSSだけで出来るアニメーションのやり方を紹介します。

アニメーションは難しいイメージがありますが、実はとても簡単です。

ぜひ習得して、Webデザインに取り入れてみてください。

CSSアニメーションは、CSSだけで出来るアニメーションです。

動作が軽快で、重くなりにくいのが特徴です。

CSSでアニメーション
  • CSSアニメーションの種類
    A
    N
    I
    M
    A
    T
    E

    CSSアニメーションは「変化の前後をなめらかにする」方法と「複雑な動きを演出する」方法の2つがあります。

    • 変化の前後をなめらかにする

      この方法はマウスカーソルを乗せた時など、シンプルなアニメーションに向いている方法です。

      このアニメーションの方法は下記の様な特徴があります。

      1. CSSの変化をアニメーション

        CSSを上書きする時に変化前変化後をなめらからにアニメーションすることが出来ます。

      2. 変化を一直線にアニメーション

        変化前変化後だけを決めて、アニメーションして切り替えます。

        アニメーションは一直線に変化するので、複雑な動きは出来ません。

      3. 反対方向にもアニメーション

        アニメーションは変化後から変化前に戻す時もアニメーションすることが出来ます。

      transition: all 1s;
    • 複雑な動きを演出する

      この方法はより複雑な動きを取り入れたアニメーションが可能です。

      このアニメーションの方法は下記の様な特徴があります。

      1. 複雑なアニメーション

        CSSで複雑なアニメーションをすることが出来ます。

        CSSで変化前変化後の状態を決めて、さらに変化途中も細かく設定することが出来ます。

      2. 反対方向は出来ない

        変化前変化途中変化後を決めてアニメーションします。

        複雑な動きが出来るのに対して、変化後から変化前にアニメーションを戻すことは出来ません。

      3. アニメーション後は最初に戻る

        アニメーションが終了したあとは、アニメーションが始まる前の状態に戻ります。

      @keyframes koro-koro {
      0% {
      /* 右に転がる */
      }
      80% {
      /* バウンドする */
      }
      100% {
      /* 右に転がる */
      }
      }

アニメーションの方法は2種類あることが分かりました。

実際に作ってそれぞれの特徴に触れてみましょう。

まずはトランジションを使って変化をなめらかにアニメーションします。

いろんな使い方がああるので、よく使う方法を紹介します。

ホバーアニメーション

<ul class="menu">
<li>Top</li>
<li>Address</li>
<li>About Us</li>
</ul>
.menu {
margin: 0;
padding: 0;
list-style: none;
background: black;
color: white;
display: flex;
}
.menu li {
width: 100%;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
transition: all .8s;
}
.menu li:hover {
background: white;
color: black;
}
ホバーアニメーション

メニューのリストにマウスカーソルを乗せた(ホバー)時にリストの背景の色と文字の色をなめらかに変更します。

スマホやタブレットはタッチした時にホバーと同じ状態になります。
  • アニメーション設定
    • トランジション

      ホバーした時のCSSプロパティの変更を感知して、変更前の状態から変更後の状態になめらかに変化します。

    • アニメーションする対象

      背景の色と文字の色を対象にしたいので、「all」にしてすべてを対象にします。

    • 変化させる時間

      変更前と変更後を「0.8秒」かけてアニメーションさせたいので、「.8s」にして0.8秒かけてなめらかに変化します。

    transition: all .8s;
  • ホバーした時の設定

    ホバーした時にメニューのリストのCSSを同時に変化させます。

    • 変更する前

      背景の色: black
      文字の色: white

      .menu li {
      background: black;
      color: white;
      }
    • 変更した後

      背景の色: white
      文字の色: black

      .menu li:hover {
      background: white;
      color: black;
      }

はい!とても簡単ですね!

アニメーションさせた要素にトランジションを追加するだけです。

続いてはアコーディオンを作ってみましょう。

アコーディオン

<div class="accordion">
<div class="menu" onclick="toggle()">
メニュー
</div>
<ul>
<li>ハンバーガー</li>
<li>チーズバーガー</li>
<li>テリヤキバーガー</li>
<li>ベーコンバーガー</li>
<li>ベジタブルバーガー</li>
<li>ライスバーガー</li>
</ul>
</div>
<script>
function toggle() {
document.querySelector('.accordion').classList.toggle('open');
}
</script>
.menu {
background: #01558d;
color: white;
padding: 5px 0 5px 10px;
cursor: pointer;
}
.accordion ul {
margin: 0;
background: #e7e7e7;
max-height: 0;
overflow: hidden;
transition: all .8s;
}
.accordion.open ul {
max-height: 300px;
}
.accordion li {
padding: 5px 0;
}
  • ハンバーガー
  • チーズバーガー
  • テリヤキバーガー
  • ベーコンバーガー
  • ベジタブルバーガー
  • ライスバーガー
アコーディオンメニュー
メニュー
  • ハンバーガー
  • チーズバーガー
  • テリヤキバーガー

メニューをクリックした時にそれに関する項目をアコーディオンのように表示します。

  • アニメーション設定
    • トランジション

      クリックされた時に、リストの高さをなめらかに変化させます。

    • アニメーションする対象

      今回は高さの変更だけですが、「all」にしてすべてを対象にします。

    • 変化させる時間

      変更前と変更後を「0.8秒」かけてアニメーションさせたいので、「.8s」にして0.8秒かけてなめらかに変化します。

    transition: all .8s;
  • メニューの開閉の設定

    クリックした時にメニューの高さをCSSで変えて開閉します。

    • クリックする前

      リストの最大の高さを「0」にして、ulタグの高さが「0px」になります。

      さらに、高さが「0px」になってはみ出てしまった部分は非表示にします。

      .accordion ul {
      max-haight: 0;
      overflow: hidden;
      }
      はみ出てしまった部分って?

      高さが「0px」にしたから非表示になると思った方がいると思います。

      実際に高さは「0px」になっていますが、実はそれだけでは非表示になりません。

      • overflow 設定なし
        みなさん。
        こんにちは。
        このサイトを作っているヒツジです。CSSテクニックや体験したバグなどの情報を発信しようと思っています。

        要素の高さを「100px」にしてわざとはみ出るようにしました。

        この場合、高さは「100px」になっていますが、文章は下にはみ出てしまっている状態です。

        height: 100px;
      • overflow: hidden

        「overflow: hidden」を設定すると、要素の高さの「100px」からはみ出た部分は表示されなくなります。

        高さを変更すれば見える範囲も変わります。この特徴を利用してアコーデオンメニューを作ります。

        height: 100px;
        overflow: hidden;
    • クリックした時

      「メニュー」をクリックした時は、JavaScriptというものを使ってメニューのリストを開いたり閉じたりします。

      メニューが開いたり閉じたりする仕組みはこのようになっています。

      1. 「メニュー」をクリック

        「メニュー」をクリックすると「onclick」が反応します。

        onclick」の中に設定している「toggle()」という処理を開始します。

      2. クラス付加と消去

        「toggle()」の処理は「script」タグの中に記述します。

        accordion」クラスに「open」クラスを付加します。

        もし「open」クラスがある場合は反対に「open」クラスを消去します。

        <script>
        function toggle() {
        document.querySelector('.accordion').classList.toggle('open');
        }
        </script>
      3. CSSで大きさを変える

        CSSで「open」クラスがある時とない時でメニューリストの高さを変更します。

        「open」クラスがない時の最大の高さを「0」に設定します。

        「open」クラスが付加された時の最大の高さを「300px」にして、メニューリストを開きます。

      <div class="accordion">
      <div class="menu" onclick="toggle()">
      メニュー
      </div>
      <ul>
      ...
      </ul>
      </div>
      <script>
      function toggle() {
      document.querySelector('.accordion').classList.toggle('open');
      }
      メソッド名:toggle {
      'accordion'クラスにトグルで'open'クラスを付加または消去する;
      }
      </script>
      .accordion.open ul {
      max-height: 300px;
      }

ちょっとだけ難しくなりました。

「open」クラスがあるかないかでメニューを開きました。

JavaScriptの部分はなんとなく覚えとく程度で大丈夫です。

続いては、スマホ用のメニューボタンを作ってみます。

<div class="menubutton" onclick="toggle()">
<i></i>
<i></i>
<i></i>
</div>
<script>
function toggle() {
document.querySelector('.menubutton').classList.toggle('open');
}
</script>
.menubutton {
position: fixed;
top: 0;
left: 0;
width: 40px;
height: 40px;
background: black;
cursor: pointer;
z-index: 100;
}
.menubutton i {
display: block;
position: absolute;
left: 50%;
transform: translate(-50%,-50%);
width: 30px;
height: 5px;
background: white;
transition: all .5s
}
.menubutton i:first-child {
top: 10px;
}
.menubutton i:nth-child(2) {
top: 50%;
}
.menubutton i:last-child {
top: 30px;
}
.menubutton.open i:first-child {
top: 50%;
transform: translate(-50%,-50%) rotate(45deg);
}
.menubutton.open i:nth-child(2) {
opacity: 0;
}
.menubutton.open i:last-child {
top: 50%;
transform: translate(-50%,-50%) rotate(-45deg);
}
メニューボタン
  • メニューボタンの作成
    1. 黒の正方形を作る

      「40px」の黒の正方形を作ります。

      この後の工程で3本の白いバーの設置とメニューボタンの配置します。

      その際に「fixed」が重要になるので、忘れないようにしましょう。

      .menubutton {
      position: fixed;
      width: 40px;
      height: 40px;
      background: black;
      }
    2. 白い3本の長方形を作る

      「iタグ」を使って白い3本のバーを作ります。

      <i></i>
      <i></i>
      <i></i>
      .menubutton i {
      display: block;
      width: 30px;
      height: 5px;
      background: white;
      }
      「iタグ」について
      1. 本来は斜め文字に装飾するタグ

        iタグの本来の使い方は「Naname Letter」のように斜め文字にしたい時に使用するタグですが、今回のようにアイコン用のためにiタグを使用します。

        斜め文字はCSSでも出来るのでiタグは使われなくなりました。そのため、よくアイコン用に使われるようになりました。
      2. displayプロパティの上書き

        iタグのdisplayプロパティの初期値は「inline」という値で、大きさを変えられません。なので、大きさを変えられるように「block」に上書きします。

        デザインの都合上必要な上書きという認識で大丈夫です。
        display: block;
    3. 白いバーを配置する
      • 共通部分

        3本の共通部分をまとめて設定します。

        1. 左から50%の位置に指定する

          黒の正方形の左から50%(半分)の位置に指定します。

        2. 位置を修正する

          白いバーの縦横それぞれの50%(半分)の大きさ分を左と上に位置を修正します。

        3. アニメーション設定

          クリックされた時の白いバーの変化を「0.5秒」かけてアニメーションさせます。

        .menubutton i {
        position: absolute;
        left: 50%;
        transform: translate(-50%,-50%);
        transition: all .5s
        }
      • 1本目

        上から1本目のバーの縦方向の位置を指定します。

        1. 上から10pxの位置に指定する

          黒の正方形の上から「10px」の位置に指定します。

        2. 位置を修正する

          上記の共通部分で指定した「translate」で上に修正します。

        .menubutton i:first-child {
        top: 10px;
        }
      • 2本目

        上から2本目のバーの縦方向の位置を指定します。

        1. 上から50%の位置に指定する

          黒の正方形の上から「50%」の位置に指定します。

        2. 位置を修正する

          上記の共通部分で指定した「translate」で上に修正します。

        .menubutton i:nth-child(2) {
        top: 50%;
        }
      • 3本目

        上から3本目のバーの縦方向の位置を指定します。

        1. 上から30pxの位置に指定する

          黒の正方形の上から「30px」の位置に指定します。

        2. 位置を修正する

          上記の共通部分で指定した「translate」で上に修正します。

        .menubutton i:last-child {
        top: 30px;
        }
  • メニューボタンの配置
    • position: fixed

      メニューボタンを画面に固定してスクロールしても付いてくるようにします。

    • top: 0

      画面の上部に固定して配置します。

    • left: 0

      画面の左側に固定して配置します。

    • cursor: pointer

      マウスを乗せたの時にマウスカーソルの形をポインターに変えます。

    • z-index: 100
      100
      50
      20

      positionで要素同士が重なるデザインの時に「z-index」というプロパティで重ねていく順番を指定します。

      もしヘッダーの裏に隠れて見えなかったらもったいないので必ず上に重ねて表示されるようにします。

      このz-indexの数字が大きいほど優先的に上に重なるようになります。

      .menubutton {
      position: fixed;
      top: 0;
      left: 0;
      cursor: pointer;
      z-index: 100;
      }
      z-indexについて

      z-indexの初期値は「0」が基準になります。z-indexの値が大きい順に手前に表示されます。

      反対に背景画像など奥に表示させたい時は「-1」のようにマイナス値を指定することも出来ます。

      z-index: -1;
メニューボタンをクリックした時
  1. openクラスを付加する

    JavaScriptでopenクラスを付加します。

    openクラスが付加されたきっかけでアニメーションが動き出します。

    <div class="menubutton" onclick="toggle()>
    <i></i>
    <i></i>
    <i></i>
    </div>
    <script>
    function toggle() {
    document.querySelector('.menubutton').classList.toggle('open');
    }
    メソッド名:toggle {
    'menubutton'クラスにトグルで'open'クラスを付加または消去する;
    }
    </script>
  2. 中央のバーを消す

    中央にある必要ないので透明にして消します。

    .menubutton.open i:nth-child(2){
    opacity: 0;
    }
  3. 上下のバーをクロスさせる

    上下の2本のバーを使ってクロスさせます。

    • 上のバー

      1本目のバーを45度回転させて中央に寄せます。

      1. 45度回転する

        「rotate」を使って角度を変更します。

        45度は英語で「45 degrees」
      2. 中央に寄せる

        黒の正方形の中央に寄せます。

      .menubutton.open i:first-child {
      top: 50%;
      transform: translate(-50%,-50%) rotate(45deg);
      }
    • 下のバー

      3本目のバーを-45度回転させて中央に寄せます。

      1. -45度回転する

        「rotate」を使って先ほどとは反対の角度に変更します。

      2. 中央に寄せる

        黒の正方形の中央に寄せます。

      .menubutton.open i:last-child {
      top: 50%;
      transform: translate(-50%,-50%) rotate(-45deg);
      }
    transformの値が2つ?

    transformの値に「translate(-50%,-50%)」と「rotate(45deg)」の2つの値が指定されています。

    もちろん、要素の回転させているのは「rotate(45deg)」です。

    では、どうして「translate(-50%,-50%)」が必要なのでしょうか?

    • translateを残した理由

      理由は位置がズレてしまうからです。

      もし下記のようにした場合、元から指定していた「translate(-50%,-50%)」は上書きされて「rotate(45deg)」のみが適用されます。

      /* 下にズレるからNG */
      transform: rotate(45deg);

      これを上書きされても「translate」は残したいので1つ目に「translate」、2つ目に「rotate」を間にスペースを空けて2つ適用させています。

      /* これでOK */
      transform: translate(-50%,-50%) rotate(45deg);

どうですか?出来ましたか?

急にやることが増えてちょっと難しかったですね...。

この後は先ほど作ったメニューボタンを使って、ドロワーメニューを作ってみましょう。

ドロワーメニュー

<div class="menubutton" onclick="toggle()">
<i></i>
<i></i>
<i></i>
</div>
<div class="menu">
<ul>
<li>About</li>
<li>Access</li>
<li>Recruit</li>
<li>Contact</li>
</ul>
</div>
<script>
function toggle() {
document.querySelector('.menubutton').classList.toggle('open');
document.querySelector('.menu').classList.toggle('open');
}
</script>
/* メニューボタン */
.menubutton { ... }
.menubutton i { ... }
.menubutton i ... { ... }
.menubutton.open i ... { ... }
/* メニュー */
.menu {
position: fixed;
top: 0;
left: -100%;
width: 100%;
height: 100vh;
background: white;
transition: all .5s;
}
.menu.open {
left: 0;
}
.menu ul {
margin: 40px 0 0 0;
padding: 0;
list-style: none;
}
.menu li {
padding: 5px 0;
text-align: center;
}
ドロワーメニュー
左上のメニューボタンをクリックするとメニューがスライドしてきます。
メニュー
  • メニューを最大まで広げる
    • 横幅を画面いっぱいに広げる

      メニューの横幅を画面の最大の大きさまで広げます。

      .menu {
      width: 100%;
      }
    • 高さを画面いっぱいに広げる

      メニューの高さを画面の最大の大きさまで広げます。

      .menu {
      height: 100vh;
      }
      100vh

      「vh」という単位は「viewport height」の略で画面(ブラウザ)の縦の大きさを基準にした単位です。

      vh

      つまり「100vh」は画面の高さと同じ大きさを意味します。

      • 100vh = 画面の高さ
      • 50vh = 画面の半分の高さ
      vw

      ちなみに「vw」という単位「viewport width」は画面(ブラウザ)の横の大きさを基準にした値になります。

      • 100vw = 画面の横幅
      • 50vw = 画面の半分の横幅
  • 上部にスペースを作る

    上部に「40px」のスペースを作ります。

    左上に設置するメニューボタンと被らないようにします。

    .menu ul {
    margin: 40px 0 0 0;
    }
  • メニューの配置
    • position: fixed

      スクロールしても画面に固定されるようにします。

    • top: 0

      画面の上部に固定して配置します。

    • left: -100%

      メニュ-を画面の左側に配置して、画面の外に飛ばします。

      メニューの左側を横幅の大きさ(100%)をマイナス値で指定します。

    .menu {
    position: fixed;
    top: 0;
    left: -100%;
    }
スライドしてメニューを表示
  • アニメーションの設定
    • トランジション

      なめらかに変化させてスライドするようにします。

    • アニメーションする対象

      今回は「left」の値のみですが、「all」にしてすべてを対象にします。

    • 変化させる時間

      変更前と変更後を「0.5秒」かけてアニメーションさせたいので、「.5s」にして0.5秒かけてなめらかに変化します。

    .menu {
    transition: all .5s;
    }
  • スライドして表示
    • openクラスを付加する

      JavaScriptのトグルを使ってクラスの付加・消去をして表示・非表示を切り替えます。

      <div class="menubutton" onclick="toggle()">
      ...
      </div>
      <div class="menu">
      ...
      </div>
      <script>
      function toggle() {
      document.querySelector('.menu').classList.toggle('open');
      }
      メソッド名:toggle {
      'menu'クラスにトグルで'open'クラスを付加または消去する;
      }
      </script>
    • メニューの表示

      JavaScriptで「open」クラスが付加された時に、CSSで表示するように上書きします。

      「left: -100%」で画面の外に飛ばしていたメニューを「left: 0」で戻します。

      .menu.open {
      left: 0;
      }

モバイル用のメニューに使えますね!!

今回は左から表示していましたが、上から表示するなどアレンジしてみて下さい。

今度はアニメーションの遅延を追加してさらにオシャレにしちゃいましょう。

遅延アニメーション

<div class="menubutton" onclick="toggle()">
<i></i>
<i></i>
<i></i>
</div>
<div class="menu">
<ul>
<li>About</li>
<li>Access</li>
<li>Recruit</li>
<li>Contact</li>
</ul>
</div>
<script>
function toggle() {
document.querySelector('.menubutton').classList.toggle('open');
document.querySelector('.menu').classList.toggle('open');
}
</script>
/* メニューボタン */
.menubutton { ... }
.menubutton i { ... }
.menubutton i ... { ... }
.menubutton.open i ... { ... }
/* メニュー */
.menu {
position: fixed;
top: 0;
left: -200px;
width: 200px;
height: 100vh;
background: white;
transition: all .5s;
}
.menu ul {
margin: 40px 0 0 0;
padding: 0;
list-style: none;
}
.menu li {
padding: 5px 0;
text-align: center;
margin-left: -20px;
opacity: 0;
transition: all .5s;
}
.menu.open {
left: 0;
}
.menu.open li {
margin-left: 0;
opacity: 1;
}
.menu.open li:first-child {
transition-delay: .5s;
}
.menu.open li:nth-child(2) {
transition-delay: .7s;
}
.menu.open li:nth-child(3) {
transition-delay: .9s;
}
.menu.open li:nth-child(4) {
transition-delay: 1.1s;
}
ドロワーメニュー
左上のメニューボタンをクリックするとメニューがスライドしてきます。
メニュー
  • メニューの基本デザイン
    • 横幅の大きさ

      メニューの横幅を「200px」にして記事の部分は見えるようにします。

    • 位置

      最初はメニューが見えない状態にしたいので、「left: -200px」で画面の外に飛ばします。

      メニューの横幅と同じ「200px」をマイナス値で画面の左側に飛ばしています。

      表示する時は、「left: 0」にして見える状態にします。

    • アニメーション

      メニューの開閉を「0.5秒」かけてアニメーションします。

    .menu {
    position: fixed;
    top: 0;
    left: -200px;
    width: 200px;
    height: 100vh;
    background: white;
    transition: all .5s;
    }
    .menu.open {
    left: 0;
    }
  • メニューリストの動作
    • 透明度

      メニューが開く前は透明にして、開いた後は不透明にします。

      「opacity」の値を最初は「0」に設定して、メニューが開いた時に「1」にして見えるようにします。

    • マージン

      メニューが開く前はリストを左に寄せて、開いた後は元の位置に戻します。

      マージンの左側を「-20px」を指定して、マイナス値でリストを左に寄せます。

      メニューが開いた時にマージンの値を「0」にして元の位置に戻します。

    .menu li {
    opacity: 0;
    margin-left: -20px;
    }
    .menu.open li {
    opacity: 1;
    margin-left: 0;
    }
  • アニメーション設定

    メニューのリストを「0.5秒」かけて変化させて、さらに開始タイミングを遅らせます。

    • リスト全体

      「0.5秒」かけて変化をアニメーションさせます。

      .menu li {
      transition: all .5s;
      }
    • 1つ目(About)

      「0.5秒」遅らせて表示させます。

      メニューが完全に開くまで「0.5秒」かかるので、開き終わった後に1番目のリストを表示させます。

      .menu.open li:first-child {
      transition-delay: .5s;
      }
    • 2つ目(Access)

      「0.7秒」遅らせて表示させます。

      メニューが開くまでの「0.5秒」と1つ目のリストが開始して「0.2秒後」に表示させます。

      .menu.open li:nth-child(2) {
      transition-delay: .7s;
      }
    • 3つ目(Recruit)

      「0.9秒」遅らせて表示させます。

      メニューが開くまでの「0.5秒」と1つ目と2つ目のリストが開始して「0.4秒後」に表示させます。

      .menu.open li:nth-child(3) {
      transition-delay: .9s;
      }
    • 4つ目(Contact)

      「1.1秒」遅らせて表示させます。

      メニューが開くまでの「0.5秒」と1つ目と2つ目と3つ目のリストが開始して「0.6秒後」に表示させます。

      .menu.open li:nth-child(4) {
      transition-delay: 1.1s;
      }
遅延アニメーション

アニメーションは開始タイミングを遅らせることが出来ます。

マウスを乗せた時やクリックがきっかけでアニメーションをスタートさせていました。

そのきっかけから何秒後にアニメーションをスタートするか決めることが出来ます。

  • 遅延時間を設定する
    transition-delay: 1s;

    「transition-delay」というプロパティを使ってアニメーションの開始を遅らせます。

    1. 1s

      アニメーションが開始するタイミングを「1秒」遅らせます。

    transition: all 2s;
    transition-delay: 1s;
  • まとめてアニメーション設定する
    transition: all 2s 1s;

    これまでの書き方に1ヵ所付け加えるだけで遅延することが出来ます。

    1. all

      アニメーションさせたい対象をすべてにしています。

    2. 2s

      アニメーションで変化させる時間を「2秒」に設定しています。

    3. 1s

      アニメーションが開始するタイミングを「1秒」遅らせます。

    transition: all 2s 1s;
    記述する順番

    まとめて設定する場合は、記述する順番が重要になってきます。

    基本的には最初に「all」、次に「変化する時間」、その後に「遅延する時間」の順番で記述していきます。

    • allの位置を変えると?
      transition: 2s 1s all ;

      例えば「all」の位置を一番後ろに変えるとどうなるのでしょうか?

      この場合は、特に問題はありません。

      「all」は順番に関係なく記述可能です。

    • 秒数を入れ替えると?
      transition: all 1s 2s;

      秒数の記述する順番が変わるとどうなるのでしょうか?

      上記のように「2s」と「1s」を入れ替えると意味が反対になってしまいます。

      この場合、「1秒かけて変化」「2秒遅延する」という意味なってなってしまいます。

      もし「2秒かけて変化」「1秒遅延」のアニメーションを設定する場合は、下記の順番で記述します。

      transition: all 2s 1s;

もしかしたらアニメーションの遅延はあまり使わないかもしれません。

ちょっとアレンジを加えたい時などに使えそうですね!!

今度はより複雑なアニメーションを作ってみましょう。

いろんな動きが出来たり、アニメーションを繰り返したり出来ます。

まずは、ローディングアニメーションを作ってみましょう。

ローディングスピナー

<div class="spinner"><div>
.spinner {
width: 50px;
height: 50px;
border: solid 5px transparent;
border-bottom-color: #01558d;
border-radius: 100%;
animation: guru-guru 1s linear infinite;
}
@keyframes guru-guru {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
スピナーのデザイン
  1. 正方形を作る

    まずはスピナーの大きさになる「50px」の正方形を作ります。

    width: 50px;
    height: 50px;
  2. 下に色付きボーダーを入れる

    上下左右に「5px」の紺色のボーダーを作成した後に、上/左/右の色を透明に上書きします。

    透明は「transparent」色付きは「#01558d」で指定します。

    border: solid 5px #01558d;
    border-top-color: transparent;
    border-left-color: transparent;
    border-right-color: transparent;
    コードを少なく書く

    より少ないCSSで書くとするなら、下記のように書きます。

    先に「5px」の透明のボーダーを作成した後、下のボーダーのみ色を上書きしています。

    border: solid 5px transparent;
    border-bottom-color: #01558d;
  3. 円にする

    最後に要素を丸くして円にします。

    border-radius: 100%;
ぐるぐる回転させる
  • アニメーション設定

    ローディングアニメーションのs設定をします。

    animation」プロパティを使って設定を行います。

    .spinner {
    animation: guru-guru 1s linear infinite;
    }
    • guru-guru

      アニメーションの名前を「guru-guru」にします。

      名前はなんでもOKですが、「opacity」「color」などCSSのプロパティとして使われる文字列は避けるようにしてください。
    • 1s

      開始から終了まで「1秒」かけて1回転するようにします。

    • linear

      アニメーションの変化の速さを一定にします。

      変化を一定の速さに設定してなめらかに回転させます。

      変化に速さ

      変化の速さに緩急を付けたり、一定にしたり変化の速さを変えることが出来ます。

      すべて同じタイミング・同じ秒数でアニメーションさせてみました。

      • ease(初期値)

        開始と終了をなめらかにします。

        何も指定しなかった場合、初期値の「ease」が自動で適用されます。

        transition: all 1s;
        animation: nobi-ru 1s;
      • ease-in

        ゆっくり始まります。

        transition: all 1s ease-in;
        animation: nobi-ru 1s ease-in;
      • ease-out

        ゆっくり終わります。

        transition: all 1s ease-out;
        animation: nobi-ru 1s ease-out;
      • ease-in-out

        ゆっくり始まってゆっくり終わります。

        transition: all 1s ease-in-out;
        animation: nobi-ru 1s ease-in-out;
      • linear

        一定の速さで回ります。

        transition: all 1s linear;
        animation: nobi-ru 1s linear;
    • infinite

      アニメーションを無限に繰り返すようにします。

      アニメーションが終わったら、また最初からアニメーションをして繰り返します。

      繰り返す回数を決める
      • 何も書かなかった時

        アニメーションは1回で終わります。

        animation: guru-guru 1s linear;
      • 数字を入れた時

        数字を入れた時はその回数分繰り返します。

        下のサンプルは3回アニメーションします。

        animation: guru-guru 1s linear 3;
      • infinite

        無限に繰り返します。

        animation: guru-guru 1s linear infinite;
  • 回転アニメーションを作る
    • キーフレーム

      キーフレームで「0%〜100%」でその都度CSSを書き換えてアニメーションしています。

      最初(0%)の時は「0°」から始まり、最後(100%)の時は「360°」で終わるようにします。

      「360°」まで回転し終わったら、アニメーション設定で指定した「infinite」で繰り返します。

      角度は英語で「degrees」
      @keyframes guru-guru {
      0% {
      transform: rotate(0);
      }
      100% {
      transform: rotate(360deg);
      }
      }

どうですか?仕組みは理解出来ましたか?

ページが読み込まれて表示されるまで、飽きさせない効果があります。

ぜひ使ってみて下さい。

次はふわっと表示するフェードインという方法を紹介します。

フェードイン

<div class="fadein">
<div class="switch" onclick="toggle()">
ふわっと
</div>
<div class="hello">
HELLO
</div>
</div>
<script>
function toggle() {
document.querySelector('.hello').classList.toggle('open');
}
</script>
.fadein {
position: relative;
height: 300px;
display: flex;
justify-content: center;
align-items: center;
}
.switch {
position: absolute;
top: 10px;
left: 5px;
width: 80px;
font-size: 14px;
background: #920000;
color: white;
border: solid 1px #920000;
border-radius: 10px;
text-align: center;
cursor: pointer;
transition: all .5s;
}
.switch:hover {
background: #f05050;
}
.hello {
width: 200px;
height: 150px;
background: #01558d;
color: white;
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
}
.hello.open {
opacity: 1;
animation: Fade-In 1s;
}
@keyframes Fade-In {
0% {
opacity: 0;
transform: translateY(30px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
ふわっと
HELLO
ふわっと表示される仕組み
  1. 「ふわっと」ボタンを押す
  2. JavaScriptで「open」クラス付加
  3. CSSでふわっと表示する
<div class="fadein">
<div class="switch" onclick="toggle()">
ふわっと
</div>
<div class="hello">
HELLO
</div>
</div>
<script>
function toggle() {
document.querySelector('.hello').classList.toggle('open');
}
メソッド名:toggle {
'hello'クラスにトグルで'open'クラスを付加または消去する;
}
</script>
アニメーション作成
  • 最初の準備

    「HELLO」の要素はボタンが押されるまで見えないようにしたいので、透明にしときます。

    .hello {
    opacity: 0;
    }
  • 「ふわっと」を押した時
    • openクラスが付加される

      JavaScriptでopenクラスを付加された「HELLO」の要素はCSSでアニメーションが開始されます。

      .hello.open {
      animation: Fade-In 1s;
      }
    • キーフレーム

      ふわっと表示する部分を作成します。

      最初(0%)の時は透明にして、さらに「translateY」で縦方向に「30px」下にずらします。

      最後(100%)の時は見えるようにして、さらに「translateY」を「0」に上書きして元の位置に戻します。

      @keyframes Fade-In {
      0% {
      opacity: 0;
      transform: translateY(30px);
      }
      100% {
      opacity: 1;
      transform: translateY(0);
      }
      }
  • アニメーションが終わった時
    HELLO
    • ある問題

      ふわっとアニメーションが終わった後は、アニメーションが始まる前の状態に戻ります

      つまり、このままだとアニメーションが終わったあとに「HELLO」は透明に戻ります。

    • 解決策

      これを避けるために「open」クラスが付加された時、下記のように「HELLO」を不透明に右上書きします。

      .hello.open {
      opacity: 1;
      animation: Fade-In 1s;
      }
      アニメーション前に不透明?

      上記の書き方だとアニメーションが開始される前に一瞬表示されちゃうのではないかと思った方がいるかもしれません。

      安心してください。アニメーションと不透明は同時に適用されます。

      まず先にキーフレームのアニメーションが優先され、その後に「opacity: 1」が適用されるイメージです。

      つまり、「opacity」「animation」の書く順番を変えても全く変わりません。

ちょっと難しいですね...

少しずつキーフレームの使い方がわかってきていると思います。

実際に一つ一つ確認しながら作ってみて下さい。

次はスクロールアナウンスを作りましょう。

スクロールアナウンス

<div class="scroll-icon">
<div class="dot"></div>
<div class="text">
Scroll
</div>
</div>
.scroll-icon {
position: relative;
width: 60px;
height: 100px;
border: solid 4px black;
border-radius: 30px;
box-sizing: border-box;
}
.scroll-icon .dot {
position: absolute;
top: 20px;
left: 50%;
transform: translate(-50%,-50%);
width: 10px;
height: 10px;
background: black;
border-radius: 100%;
opacity: 0;
animation: announce 1.5s linear infinite;
}
.scroll-icon .text {
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
font-size: 20px;
}
@keyframes announce {
0% {
top: 10px;
opacity: 0;
}
20% {
opacity: 1;
}
50% {
opacity: 1;
}
70% {
top: 80px;
opacity: 0;
}
100% {
top: 80px;
opacity: 0;
}
}
Scroll
アイコンのデザイン
  • アイコンを作る
    • ベースの形

      アイコンのフレーム部分を作ります。

      「box-sizing」でボーダー領域までの大きさを指定しています。

      さらに、横幅「60px」の半分の大きさ「30px」で角を丸くしています。

      .scroll-icon {
      position: relative;
      width: 60px;
      height: 100px;
      border: solid 4px black;
      border-radius: 30px;
      box-sizing: border-box;
      }
    • ドット

      ドット(点)を作ります。

      ポジションを使って上から「20px」の位置にセットしてアニメーションが始まる前は透明にしときます。

      .scroll-icon .dot {
      position: absolute;
      top: 20px;
      left: 50%;
      transform: translate(-50%,-50%);
      width: 10px;
      height: 10px;
      background: black;
      border-radius: 100%;
      opacity: 0;
      }
    • テキスト
      Scroll

      テキストの「Scroll」部分を作ります。

      フォントサイズを「20px」に固定して、アイコンの下に設置します。

      「top: 100%」でアイコンの最下部にくるようにしています。

      .scroll-icon .text {
      position: absolute;
      top: 100%;
      left: 50%;
      transform: translateX(-50%);
      font-size: 20px;
      }
  • アニメーション
    • 移動(0%〜70%)
      1. 「0%〜70%」の間で上から下に移動します。
      2. 「70%〜100%」の間はその場に止まり続けます。
    • 透明・不透明
      1. 「0%〜20%」の間で透明から不透明に切り替えます。
      2. 「20%〜50%」の間は常に見える状態です。
      3. 「50%〜70%」の間は徐々に透明にしていきます。
      4. 「70%〜100%」の間は透明のままにします。
    .scroll-icon .dot {
    animation: announce 1.5s linear infinite;
    }
    @keyframes announce {
    0% {
    top: 10px;
    opacity: 0;
    }
    20% {
    opacity: 1;
    }
    50% {
    opacity: 1;
    }
    70% {
    top: 80px;
    opacity: 0;
    }
    100% {
    top: 80px;
    opacity: 0;
    }
    }

これはそんなに難しくはないですね。

アニメーションさせてるのはドットの部分だけです。

スクロール出来るか分かりにくいって時に作ってみて下さい。

アニメーションはちょっと置いといて擬似要素やりましょう。

擬似要素!?何それ?と思った方、ヒツジも最初「何それ?」って思いました。

簡単に言うと、「CSSで新しく要素を作っちゃおう!!」ってことです。

擬似要素とは

擬似要素
召喚!!!
キャハハ!!!

擬似要素とはCSSで新しく要素を作り出したモノ

HTMLでは要素が1つしかありませんが、CSSで要素を作ると最大2つまで架空の要素を作りだすことが出来ます。

<div class="wizard">要素使い</div> .wizard::before {
content: 'Before魔人';
}
.wizard::after {
content: 'After魔人';
}
  • 擬似要素の種類

    擬似要素は「Before」と「After」の2種類があります。

    なぜ「Before」と「After」なのか、理由は簡単です。

    • Before
      要素

      「Before」はHTMLに記述された「要素」のすぐ前(左側)に追加されます。

      今回は「☆」を要素の前に追加してみました。

      <div class="sample1">要素</div> .sample1::before {
      content: '☆';
      color: #920000;
      }
    • After
      要素

      「After」はHTMLに記述された「要素」のすぐ後(右側)に追加されます。

      今回は「☆」の色を変えて要素の後に追加してみました。

      <div class="sample2">要素</div> .sample2::after {
      content: '☆';
      color: #01558d;
      }
  • 擬似要素の使い方

    擬似要素を表示させたい時は必ず「content」が必要になります。

    もし「content」がなかった場合は一切表示されません。

    • 文字を表示させたい時

      擬似要素に何か文字を入れて表示させたい時は「content」の「''」に文字を入れます。

      .sample {
      content: '文字入れる';
      }
    • それ以外の時

      文字を表示させたいのではなく、例えば四角や丸など図形を表示させたい時は「content」の中を空にします。

      .sample {
      content: '';
      width: 50px;
      height: 50px;
      background: black;
      }

擬似要素は仮想的に作られる要素ということがわかりました。

おそらく「今まで擬似要素使わなくてもいけた!!」と思うことがあると思います。

まさにその通りですが、使い方次第ではとても便利で効率的になります。

注釈を入れる

<p>
こちらの商品は9800円<sup>※</sup>です。
</p>
<div class="notes">
消費税は含まれていません。
</div>
<div class="notes">
時期によって価格が変動する可能性があります。
</div>
<div class="notes">
お一人様3箱までとさせていただきます。
</div>
p {
margin: 0;
padding-left: 5px;
border-left: solid 4px #920000;
}
.notes {
font-size: 16px;
color: #920000;
}
.notes::before {
content: '※';
}

こちらの商品は9800円です。

消費税は含まれていません。
時期によって価格が変動する可能性があります。
お一人様3箱までとさせていただきます。
注釈を作る
  • notesクラス

    「notes」クラスがあるすべての文章の左側に「※」を挿入されます。

    このようにCSSで「※」を追加されるようにすると毎回キーボードで入力する手間は省くことが出来ます。

  • 注釈を入れる

    CSSの擬似要素で「※」を挿入します。

    要素の前(左側)に追加したいので「before」を使います。

    「content」の中に「※」を記述します。

    .notes::before {
    content: '※';
    }

注釈を例にした「Before」の使い方でした。

この方法は簡単でよく使われる方法です。

次は「After」を使ったパンくずリストを作ってみましょう

パンくずリスト

<ul class="breadlist">
<li>ホーム</li>
<li>サービス</li>
<li>修理</li>
<li>PC</li>
</ul>
.breadlist {
display: flex;
list-style: none;
margin: 0;
padding: 0;
border-bottom: dashed 2px #01558d;
font-size: 20px;
}
.breadlist li {
padding: 0;
}
.breadlist li::after {
content: '>';
margin: 0 5px;
}
.breadlist li:last-child::after {
display: none;
}
  • ホーム
  • サービス
  • 修理
  • PC
パンくずリスト
  • トップ
  • サービス
  • 修理
  • PC

よくサイトの上部にある、関連する項目を表示している部分を見たことがありませんか?

上記の場合、「トップページ」から「サービス」の中の「修理」という項目を選んで「PC」のページを今見ている状態を利用者に伝えています。

パンくずリストはページの構造がパッと理解出来るように、ほとんどサイトで設置されています。

  • パンくずリストの作成

    パンくずリストは「ul」タグと「li」タグを使うことが多いので、今回は「ul」「li」を使って作成します。

    • リストを横並びにする
      • トップ
      • サービス
      • 修理
      • PC

      Flexboxを使ってリストを横並びにします。

      さらに下に「2px」の破線を引きます。

      .breadlist {
      display: flex;
      border-bottom: dashed 2px #01558d;
      }
    • リストの後に「>」を入れる
      • トップ
      • サービス
      • 修理
      • PC

      After要素でリストの後(右側)に追加します。

      そして「>」の左右に「5px」の余白を入れます。

      .breadlist li::after {
      content: '>';
      margin: 0 5px;
      }
      最後のリストは「>」なし
      • トップ
      • サービス
      • 修理
      • PC

      最後の「pc」の後には「>」は必要ないので、最後の「>」は非表示にします。

      .breadlist li:last-child::after {
      display: none;
      }

これも簡単ですね。

CSSで擬似的に付け加えることで、HTMLの修正なしで出来るのがいいですね!!

それでは最後に「Before」「After」を使った応用編をやってみましょう。

コメントデザイン

<div class="comments">
<p>
Web制作は短期間で習得可能です。
</p>
</div>
.comments {
position: relative;
margin: 30px 15px;
padding: 10px;
border: solid 2px #01558d;
border-radius: 10px;
}
.comments::before,
.comments::after {
position: absolute;
background: #01558d;
border-radius: 5px;
}
.comments::before {
content: 'Comments';
top: 0;
left: 0;
transform: translate(-15px,-50%);
color: white;
padding: 5px 10px;
font-size: 18px;
}
.comments::after {
content: '';
bottom: 0;
right: 0;
width: 30px;
height: 30px;
transform: translate(15px,50%);
}

Web制作は短期間で習得可能です。

ヒツジは2年前にHTML&CSS超入門という本で独学で学び始めて、現在は3つのサイトを立ち上げ運用しています。

焦ってしまうこともあるかと思いますが、しっかり地道に学んで時には休んで頑張っていきましょう。

コメントデザイン
  • メインデザイン

    Web制作は短期間で習得可能です。

    • 準備

      「position」を「relative」に設定して、この後に作成する擬似要素を自由に移動出来るようにします。

      position: relative;
    • スペースを空ける

      この後に作成する擬似要素は外にはみ出たデザインにするので、マージンで上下に「30px」左右に「15px」の余白を作ります。

      また、パディングで上下左右に「10px」の余白を作って文章をみやすくします。

      margin: 30px 15px;
      padding: 10px;
    • 枠線で囲む

      「2px」の大きさで文章全体を線で囲います。

      さらに角を「10px」の大きさで丸くします。

      border: solid 2px #01558d;
      border-radius: 10px;
  • 擬似要素

    Web制作は短期間で習得可能です。

    • 共通デザイン

      擬似要素「before」「after」の共通部分を設定します。

      「absolute」を設定して、擬似要素を動かす準備をします。

      そして、背景は紺色にして角は丸めます。

      途中のカンマ「,」を忘れないようにしましょう。
      .comments::before,
      .comments::after {
      position: absolute;
      background: #01558d;
      border-radius: 5px;
      }
    • Before
      1. contentに「Comments」を入れる。
      2. 「top」「left」で左上に寄せる。
      3. translateで左に「15px」、上に擬似要素の「50%」をはみ出す。
      .comments::before {
      content: 'Comments';
      top: 0;
      left: 0;
      transform: translate(-15px,-50%);
      color: white;
      padding: 5px 10px;
      font-size: 18px;
      }
    • After
      1. contentに空っぽにする。
      2. 「30px」の正方形を作る。
      3. 「bottom」「right」で右下に寄せる。
      4. translateで右に「15px」、下に擬似要素の「50%」をはみ出す。
      .comments::after {
      content: '';
      bottom: 0;
      right: 0;
      width: 30px;
      height: 30px;
      transform: translate(15px,50%);
      }

より実用的な「Before」と「After」の使い方をやりました。

今話してるヒツジも実は擬似要素ですよ...。

本物はどこでしょうかね....。

ちょっと高度なアニメーションを作ってみましょう。

擬似要素の「Before」と「After」を使ってアニメーションします。

ちょっと難しいですが、余裕がある時にやってみて下さい。

リストアニメーション

<div class="mokuji">
<ul>
<li>CSSについて</li>
<li>CSSの書き方</li>
<li>CSSテクニック</li>
<li>CSSの注意点</li>
</ul>
</div>
.mokuji ul {
margin: 1em auto;
padding: 0;
list-style: none;
max-width: 400px;
}
.mokuji li {
position: relative;
margin: .8em 0 .8em 20px;
padding-left: 10px;
cursor: pointer;
}
.mokuji li::before,
.mokuji li::after {
position: absolute;
content: '';
transition: all .2s;
}
.mokuji li::before {
top: calc(50% - 5px);
right: 100%;
width: 10px;
height: 10px;
background: #01558d;
transition-delay: .2s;
}
.mokuji li::after {
top: 100%;
left: 0;
width: 0;
height: 2px;
background: #01558d;
transition-delay: 0s;
}
.mokuji li:hover::before {
top: 100%;
height: 2px;
transition-delay: 0s;
}
.mokuji li:hover::after {
width: 100%;
transition-delay: .2s;
}
  • CSSについて
  • CSSの書き方
  • CSSテクニック
  • CSSの注意点
リストのデザイン
CSSについて
  • リストのデザイン調整

    アニメーションさせるために、まず先にリスト(liタグ)のデザインを作ります。

    パーツごとに重要なポイントを押さえて説明していきます。

    1. relativeを指定する

      リストの左側に「Before要素」、下に「After要素」を設置するため、「relative」を必ず指定します。

    2. 左側に20pxのスペース(外側)

      リスト同士の間隔(上下)を「.8em」のスペースを作ります。

      さらに、左側に「20px」のスペースを作ります。

      これは左側に「Before要素」を設置するのでそのために空けています。

      文字サイズが「16px」の時、「12.8px」の大きさでスペースを作ります。
    3. 左側に10pxのスペース(内側)

      リストの左側にある「Before要素」と間に「10px」のスペースを作って、見やすくします。

    .mokuji li {
    position: relative;
    margin: .8em 0 .8em 20px;
    padding-left: 10px;
    }
  • 擬似要素のデザイン
    • 共通設定

      擬似要素の「before」と「after」の共通部分をまとめて指定します。

      .mokuji li::before,
      .mokuji li::after {
      position: absolute;
      content: '';
      }
    • Before要素
      CSSについて
      1. 正方形を作る

        「10px」の紺色の正方形を作ります。

      2. 左側に寄せる

        正方形をリストの左側に置くため、「right: 100%」と指定します。

        もし「right: 0」だったら右側に配置されますよね。

        「right: 100%」は、リスト本体の大きさ(100%)分を右から左に移動=左寄せにします。

      3. 中央寄せ

        上下の位置を中央寄せします。

        まず、上から「50%」の位置(半分の高さ)に設置します。

        その後、正方形の半分の大きさ「5px」を上に修正して、中央に寄せます。

      .mokuji li::before {
      top: calc(50% - 5px);
      right: 100%;
      width: 10px;
      height: 10px;
      background: #01558d;
      }
      calcってなに?

      今回は位置の指定に「calc」という計算してくれる関数を使いました。

      簡単にいうと「%」「px」「em」など、単位の違うものでも計算してくれる関数です。

      • どんな計算になる?

        例えば上記ような「10px」の正方形を中央に配置したい時の計算を考えます。

        100px」の高さのある要素の中で正方形を中央に寄せる時、その半分の高さ「50%」は「50px」の位置に配置されます。

        さらにそこから正方形の半分の大きさ「5px」を引いて上に修正します。

        計算結果は「top: 45px」が指定されます。

        top: calc(50% - 5px);
      • こんな方法でも出来る

        calc関数を使わないで、「translate」でもほぼ同じ働きが可能です。

        上から「50%」の値で中央まで移動します。

        その後に「translateY」で高さを「5px」上に戻して中央寄せしています。

        top: 50%;
        transform: translateY(-5px);
    • After要素
      CSSについて
      1. 横に長い線を作る

        高さ「2px」の紺色の線を引きます。

        横幅は「0px」にして、ホバーした時に「100%」にして広げます。

      2. 左下に寄せる

        「top: 100%」と「left: 0」で左に寄せます。

      .mokuji li::after {
      top: 100%;
      left: 0;
      width: 0;
      height: 2px;
      background: #01558d;
      }
ホバーアニメーション
CSSについて

リストをマウスカーソルでホバーした時にアニメーションさせます。

  • 共通アニメーション設定

    擬似要素の「Before」と「After」を「0.2秒」かけてアニメーションするように、まとめて指定します。

    .mokuji li::before,
    .mokuji li::after {
    transition: all .2s;
    }
  • ホバーした時
    • Before要素

      正方形のブロックを「top: 100%」で一番下まで移動しながら高さを「2px」に変えて、ブロックを潰したような演出をします。

      .mokuji li:hover::before {
      top: 100%;
      height: 2px;
      }
    • After要素

      横幅を「0」にしていたものほ「100%」にして、横に伸びる線を演出します。

      .mokuji li:hover::after {
      width: 100%;
      }
  • アニメーションの遅延
    CSSについて

    アニメーションの遅延を利用して、Before要素とAfter要素を繋がったアニメーションにします。

    • ホバーした時
      1. 先にBefore要素がスタート

        遅延を「0秒」にして先にアニメーションします。

        遅延しないのに「0秒遅延」と記述した理由は後ほど説明します。
        .mokuji li:hover::before {
        transition-delay: 0s;
        }
      2. 次にAfter要素がスタート

        「0.2秒」かけてBefore要素が変化した後、After要素がスタートします。

        After要素を「0.2秒後」にスタートさせます。

        .mokuji li:hover::after {
        transition-delay: .2s;
        }
    • ホバーを解除した時
      1. 先にAfter要素を元に戻す

        ホバーした時に「0.2秒」遅らせていたAfter要素を「0秒」の遅延に上書きして遅延をなくします。

        .mokuji li::after {
        transition-delay: 0s;
        }
      2. 次にBefore要素を元に戻す

        ホバーした時に「0秒」遅らせていたBefore要素を「0.2秒」の遅延に上書きして遅らせます。

        .mokuji li::before {
        transition-delay: .2s;
        }
    0秒の遅延の理由

    遅延しないのになぜ「0秒」の遅延を記述する必要があったのでしょうか?

    理由は、「ホバーした時」と「ホバーを解除した時」にBefore要素とAfter要素の遅延設定を入れ替えるためです。

    • ホバーした時のCSS

      ホバーした時はBefore要素の後にAfter要素がアニメーションするように、After要素を「0.2秒」を遅延しています。

      .mokuji li:hover::before {
      transition-delay: 0s;
      }
      .mokuji li:hover::after {
      transition-delay: .2s;
      }
    • ホバー解除した時のCSS

      ホバーを解除した時はAfter要素の後にBefore要素の順で元に戻します。

      そのために、遅延設定を入れ替えています。

      .mokuji li::before {
      transition-delay: .2s;
      }
      .mokuji li::after {
      transition-delay: 0s;
      }

うーん、いまいちよく分からないという方!

ちょっと面倒ですが、CSSを一つ一つ書き加えながら確認してみてください。

きっと理解出来ますよ。

波紋エフェクト

<div class="waves">
<div class="round" data-text="Wave">
<div class="wave"></div>
</div>
<div class="round" data-text="Wave2">
<div class="wave"></div>
</div>
</div>
.waves {
height: 200px;
display: flex;
justify-content: center;
align-items: center;
background: #a7dcff;
}
.round {
position: relative;
width: 120px;
height: 120px;
cursor: pointer;
}
.round::before {
position: absolute;
content: '';
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 60px;
height: 60px;
background: #3992ce;
border-radius: 100%;
z-index: 2;
}
.round::after {
position: absolute;
content: attr(data-text);
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
text-align: center;
font-size: 30px;
color: white;
z-index: 3;
}
.wave::before,
.wave::after {
position: absolute;
content: '';
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 50px;
height: 50px;
border: solid 2px white;
border-radius: 100%;
z-index: 1;
}
.round:hover .wave::before,
.round:hover .wave::after {
animation: wave 2s linear infinite;
}
.waves:hover .wave::after {
animation-delay: .7s;
}
@keyframes wave {
0% {
width: 50px;
height: 50px;
opacity: 1;
}
70% {
opacity: 1;
}
90% {
width: 100%;
height: 100%;
opacity: 0;
}
100% {
width: 100%;
height: 100%;
opacity: 0;
}
}
波紋のデザイン
  • 基本デザイン
    • 基本フレーム

      「120px」の正方形を作成していきます。

      この正方形を基準に円・テキスト・波紋を作成していきます。

      .round {
      position: relative;
      width: 120px;
      height: 120px;
      }
    • 円の作成

      Before要素を使って、直径「60px」の紺色の円を作成します。

      そして、作成した円を正方形の中心に配置します。

      .round::before {
      position: absolute;
      content: '';
      top: 50%;
      left: 50%;
      transform: translate(-50%,-50%);
      width: 60px;
      height: 60px;
      background: #3992ce;
      border-radius: 100%;
      }
    • テキストを上に重ねる

      After要素を使って「Wave」というテキストを円の上に作成します。

      「left: 0」「right: 0」で左右を最大まで広げて、その後テキストを中央寄せしています。

      また、contentにattr()という関数を使って、HTMLからCSSへ「Wave」というテキストを引き継いで表示させます。

      .round::after {
      position: absolute;
      content: attr(data-text);
      top: 50%;
      left: 0;
      right: 0;
      transform: translateY(-50%);
      text-align: center;
      font-size: 30px;
      color: white;
      }
      attr(data-text)ってなに?

      HTMLからCSSにテキスト形式で引き継いで、擬似要素の「content」に代入することができます。

      その際に「attr()」という関数を使って「data-text」の値を受け取り・代入をして表示します。

      このようにするとAfter要素またはBefore要素の「content」は修正しなくても、再利用が可能になります。

      <div data-text="Wave"></div>
      <div data-text="Wave2"></div>
      div::after {
      content: attr(data-text);
      }
  • 波紋の作成
    • 波紋のデザイン

      waveクラスの「Before要素」と「After要素」を使って2つの波紋を作成します。

      直径「50px」の円に、ボーダーで「2px」の白い枠を作成します。

      そして、作成した2つの円を正方形の中心に配置します。

      .wave::before,
      .wave::after {
      position: absolute;
      content: '';
      top: 50%;
      left: 50%;
      transform: translate(-50%,-50%);
      width: 50px;
      height: 50px;
      border: solid 2px white;
      border-radius: 100%;
      }
    • 波紋は後ろに隠す

      波紋は最初見せたくないので、要素の重なりを利用して波紋を隠します。

      z-indexを使って「1〜3」で重なる順番を指定します。

      数字が大きいほど出前に重なって表示されます。

      .wave::before,
      .wave::after {
      z-index: 1;
      }
      .round::before {
      z-index: 2;
      }
      .round::after {
      z-index: 3;
      }
波紋アニメーション
  • ホバーしたらアニメーション

    ホバーした時にアニメーションを設定して波紋を表現します。

    「round」クラスにホバーした時に、その中の波紋である「wave」クラスをアニメーションします。

    さらに、「wave」クラスの「After要素」を「0.7秒」遅らせてスタートします。

    <div class="round" data-text="Wave">
    <div class="wave"></div>
    </div>
    .round:hover .wave::before,
    .round:hover .wave::after {
    animation: wave 2s linear infinite;
    }
    .waves:hover .wave::after {
    animation-delay: .7s;
    }
  • アニメーション作成

    アニメーションの動きを作成します。

    アニメーションの遅延をすることで、2つの波紋を表現しています。

    • 大きくする(0%〜90%)
      1. 「0%〜90%」の間で「50px〜100%」まで大きくします。
      2. 「90%〜100%」の間はその場に止まり続けます。
      大きさは「100%=120px」になります。
    • 透明・不透明
      1. 「0%〜70%」の間は見える状態にします。
      2. 「70%〜90%」の間で徐々に透明にします。
      3. 「90%〜100%」の間は透明のままにします。
    @keyframes wave {
    0% {
    width: 50px;
    height: 50px;
    opacity: 1;
    }
    70% {
    opacity: 1;
    }
    90% {
    width: 100%;
    height: 100%;
    opacity: 0;
    }
    100% {
    width: 100%;
    height: 100%;
    opacity: 0;
    }
    }

はい、めちゃめちゃ複雑です。

結構意味わかったかもしれません。

これも一つ一つ確認しながら...頑張ってください!!