フェードイン・アウトのスライドメニューをCSSアニメーションで簡単に実装!
ブログをご覧のみなさま、こんにちは。デザイン戦略部のJKと申します。
今回は弊社サイトにて実装したCSSアニメーションをご紹介しようと思います。
少々前にサービスサイト「URIHO」のリニューアルを行い、私はマークアップエンジニアとして携わりました。
さて、本稿ではスマホ・タブレットのヘッダの動きに関して取り上げようと思います。
見てもらいますとメニューをクリックした後に左から右へスライドし、中のリンク達がずらら~っと表示されます。
実はこれ全てCSSのみで対応しているんです。
そんなCSSのみで作成したこちらのアニメーションを簡単にご紹介していきたいと思います。
今回のポイント
- 疑似セレクタ「checked」によるボタンの実装
- label要素でボタンとチェックボックスを関連付ける
- transitionプロパティを使いアニメーションにする
- 各アニメーションを時間に差をつけて実装する
ヘッダー要素作成
まずは簡単にヘッダー要素を作ります。
html
<header class="header">
<a href="/" class="logo">URIHO</7a>
<div class="button">メニュー</div>
<nav class="menu">
<li class="link1">リンク1</li>
<li class="link2">リンク2</li>
<li class="link3">リンク3</li>
<li class="link4">リンク4</li>
<li class="link5">リンク5</li>
<li class="link6">リンク6</li>
</navi>
</header>
css
.header {
position: fixed;
z-index: 100;
width: 100%;
height: 60px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #ccc;
}
.logo {
font-size: 30px;
font-weight: bold;
line-height: 1;
color: #333;
margin-left: 15px;
}
.button {
display: inline-block;
margin-right: 15px;
}
.menu {
position: fixed;
box-sizing: border-box;
width: 100%;
height: 100%;
background: #3e4847;
color: #fff;
padding: 20px;
top: 60px;
}
.menu>li {
border-bottom: 1px solid #fff;
padding: 10px 0;
}
こんな形で作り、とりあえずページ上にドンと載せます。
見た目
動きも何もなくただメニューが開いている状態です。
left:-100%;指定
次にメニューを左から右にスライドさせたいので初期位置を画面外の左に置きます。
.menuに対しleft:-100%;を指定して画面上から綺麗サッパリ左に追いやりましょう。
メニューの追いやり成功です。(もちろん消えてはいません)
チェックボックス設置
今回はcheckedという疑似セレクタを使い実装していくのでチェックボックスも設置します。
html
<header class="header">
<a href="/" class="logo">URIHO</a>
<input type="checkbox" id="menu-checkbox">
<label for="menu-checkbox">
<div class="button">メニュー</div>
</label>
<nav class="menu">
<li class="link1">リンク1</li>
<li class="link2">リンク2</li>
<li class="link3">リンク3</li>
<li class="link4">リンク4</li>
<li class="link5">リンク5</li>
<li class="link6">リンク6</li>
</navi>
</header>
labelタグを使いチェックボックスとボタンを関連付けさせる事も忘れないで対応しましょう。
チェックボックスと関連付いた様子
こんな感じです。
メニューを押せばcheckboxにチェックが付きます。
チェックボックスは見た目上邪魔なので#menu-checkboxに対しdisplay:none;で非表示にしてしまいましょう。
スライド実装
さて、次はボタンがクリックされたらメニューを左から右にスライドさせる部分を実装します。
つまり内部的にはチェックボックスにチェックが入ったら~という事になります。
css
#menu-checkbox:checked+label+.menu {
left: 0;
}
この「+」というのは隣の要素を指定する疑似セレクタとなります。
また「checked」はチェックされたら~という指定の疑似セレクタです。
なので上記の場合、チェックボックスがチェックされたらその隣にあるlabel要素の隣のメニュー要素~という指定となるわけです。
#menu-checkbox:checked | チェックボックスがチェックされたら |
+label | 隣にあるlabel要素の |
+.menu | 隣にある.menuクラスが付与されている要素 |
チェック部分実装
クリックされたら(チェックボックスにチェックが付いたら)leftが0になるので画面外から画面内に表示されるようになりました。
逆にもう一度クリックすると(チェックボックスにチェックがはずれたら)leftが-100%になるので再度画面外に消えます。
しかし一瞬で表示・非表示されるのでまだ意図した動きにはなっていません。
そこで時間をかけて動かすtransitionプロパティの登場です。
transitionプロパティ
css
.menu {
position: fixed;
box-sizing: border-box;
width: 100%;
height: 100%;
background: #3e4847;
color: #fff;
padding: 20px;
top: 60px;
left: -100%;
transition: left 0.7s;
}
使い方はいたって簡単で「transition: 対象プロパティ 時間;」という指定の仕方になります。
連続してプロパティを指定することも可能で、その場合は「transition: 対象プロパティ 時間, 対象プロパティ 時間;」というようにカンマ区切りとなります。
スライド実装
0.7sと指定したことで0.7秒かけてleftが実行されるようになったのでだいぶ意図した動きに近づきました。
css
.menu {
position: fixed;
box-sizing: border-box;
width: 100%;
height: 100%;
background: #3e4847;
color: #fff;
padding: 20px;
top: 60px;
left: -100%;
opacity: 0;
transition: left 0.7s, opacity 0.7s;
}
#menu-checkbox:checked+label+.menu {
left: 0;
opacity: 1;
}
更にフェードイン・アウト効果も入れるためメニュー要素に対してopacityを指定します。
デフォルトは完全透過のopacity: 0;を指定、またチェックされたときは透過なしのopacity: 1;を指定し、transitionプロパティにopacityを追加します。
フェードイン・アウト実装
いい具合にフェードイン・アウトしながらスライドされるようになりました。
各リンクのアニメーションを時間差実装
最後にメニュー内の各リンクがずららっと表示される部分を実装します。
css
.menu>li {
border-bottom: 1px solid #fff;
padding: 10px 0;
left: -100%;
position: relative;
}
#menu-checkbox:checked+label+.menu>li {left: 0;}
.link1 {transition: left 0.2s;}
.link2 {transition: left 0.4s;}
.link3 {transition: left 0.6s;}
.link4 {transition: left 0.8s;}
.link5 {transition: left 1s;}
.link6 {transition: left 1.2s;}
この動きは各リンクのアニメーションにかける時間に差異を付けることで実装しています。
なので今回はtransitionプロパティの時間指定をそれぞれ変えます。
完成
実装できました!
と、こういった感じでとても簡単に実装できると思うのですがいかがでしょう。
なによりCSSのみで実装できるというのがとても強みです。
ぜひ本稿をご覧いただいたみなさまもお試しください。