DigiPress

Highly Flexible WordPress Theme

メニュー

CSSのみでグローバルメニューを3Dアニメーションで開閉表示するサンプル


いわゆるハンバーガーメニューアイコン(こんなの : )のみを表示して、クリックすると左端からオフキャンバスナビゲーション(グローバルメニュー)がスライド表示すると共に、メインコンテンツエリアは3Dアニメーションで斜め奥に移動するエフェクトのサンプルをご紹介します。

Javascriptは使用せず、CSSのみで表現しています。

概要としては、label要素であるハンバーガーメニューアイコンをクリックすると、関連付けられているチェックボックスの属性を持たせた input要素のチェック状態が変化し、これをCSSの疑似セレクタ(:checked)を利用してチェックされた状態のときに、オフキャンバス状態にしてあるサイドメニューをCSSのtransition, transformプロパティによってスライド表示させる、というものです。

言葉ではわかりにくいので、まずは完成サンプルをご覧ください。

See the Pen Sliding side menu with CSS 3D transition by digistate (@digistate) on CodePen.

大まかなHTMLの構成とCSS

HTMLは、ハンバーガーメニューアイコン用要素 → サイドメニュー用要素 → メインコンテンツ の順番で構成しています。

<!-- ハンバーガーメニューアイコンここから -->
<input type="checkbox" role="button" title="menu" id="nav_check">
<label for="nav_check" aria-hidden="true">
    :
</label>
<!-- ハンバーガーメニューアイコンここまで -->

<!-- サイドメニューここから -->
<nav>
    :
</nav>
<!-- サイドメニューここまで -->

<!-- メインコンテンツここから -->
<main>
    :
</main>
<!-- メインコンテンツここまで -->

z-indexによるレイヤー構成

このHTMLの構成を、CSSのz-indexで以下のように重ね合わせ順序を変更しています。
capture-2016-11-07-13-18-58
ハンバーガーメニューアイコンを表示するlabel要素の:before疑似セレクタは、ハンバーガーアイコンが変形した「」アイコン以外に、サイドメニュー外のエリアをクリックしてもチェックボックスが反応する、つまりサイドメニューが再びオフキャンバスになるように、フルサイズで固定表示にしておきます。

そして、z-indexで、サイドメニュー要素(nav)よりも背面かつメインコンテンツ(main)よりも前面にくるようにしておき、メニューが表示されていない状態では不透明度を0(opacity:0)にし、ポインターイベントを無効(pointer-events:none)にしておきます。

オフキャンバス判定用の:before疑似セレクタのCSS

.burger.wrapper::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1; /* mainよりも前面に */
  background-color: rgba(0, 0, 0, 0.4);
  pointer-events: none;  /* メニューが閉じているときはポインターイベントを無効に */
  opacity: 0;  /* メニューが閉じているときは見えなくしておく */
}

ハンバーガーメニューアイコンの構成

サイドメニューの開閉は、チェックボックスの状態をトリガーとするため、最初にinput要素のチェックボックスがありますが、チェックボックスの表示自体は不要なのでvisibility:hiddenで非表示にしておきます。

その代わり、このチェックボックスに関連付けられた次の要素であるlabelをハンバーガーメニューアイコンで表示しています。

<input type="checkbox" role="button" title="menu" id="nav_check">
<label for="nav_check" id="burger" class="burger wrapper" aria-hidden="true" title="menu">
  <span class="burger box">
    <span class="burger inner"></span>
  </span>
</label>

ハンバーガーメニューアイコンはこちらを参考にお好みのものをCSSに落とし込めます。

サイドメニューの構成

サイドメニューは、単純にnavタグで実際のメニューとなるリストタグを括り、translateX(-100%)で左端(X軸マイナス方向)にずらしてオフキャンバスの状態に隠しておきます。

HTML

<nav>
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Projects</a></li>
    <li><a href="#">Products</a></li>
    <li><a href="#">Company</a></li>
  </ul>
</nav>

CSS

nav {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 25vw;
  overflow-y: scroll;
  text-align: left;
  background-color: #000;
  z-index: 2;
  -moz-transform: translateX(-100%);
  -ms-transform: translateX(-100%);
  -webkit-transform: translateX(-100%);
  transform: translateX(-100%);
}

ハンバーガーメニューアイコンをクリックしたときのCSS

ハンバーガーメニューアイコンをクリックしたとき、つまり関連付けされたlabel要素がクリックされてチェックボックスにチェックが付いたときは、input要素の:checked疑似セレクタでスタイリングできます。

サイドメニューを表示

チェックボックス(input)要素の後にある隠れているサイドメニュー(nav)要素を元の位置に戻して表示します。

#nav_check:checked ~ nav {
  -moz-transform: translateX(0);
  -ms-transform: translateX(0);
  -webkit-transform: translateX(0);
  transform: translateX(0);
}

オフキャンバス判定用の:before疑似セレクタ要素を表示する

チェックボックス要素の次にあるlabel要素の:beforeセレクタの要素を表示し、チェックボックスが反応するよう、ポインターイベントも有効にします。

#nav_check:checked + .burger.wrapper::before {
  opacity: 1;
  pointer-events: auto;
}

メインコンテンツエリアのスタイリング

この部分は機能面とは関係ないため、デザイン上の装飾としてお好みでスタイリングする部分ですが、スライドメニューが表示されたときは、今回はメインコンテンツエリアは斜め奥に移動してブラーがかかった状態にしてみます。

#nav_check:checked ~ main #content {
  transform-origin: left center;
  -moz-transform: translateX(15vw) translateZ(-20vw) rotateY(-13deg);
  -ms-transform: translateX(15vw) translateZ(-20vw) rotateY(-13deg);
  -webkit-transform: translateX(15vw) translateZ(-20vw) rotateY(-13deg);
  transform: translateX(15vw) translateZ(-20vw) rotateY(-13deg);
  -webkit-filter: blur(3px);
  filter: blur(3px);
}

今回のサンプルでは、Javascriptを利用せず、フォーム要素(チェックボックス)のステータス判断に使える疑似セレクタ(:checked)を利用してCSSのみでオフキャンバスのグローバルメニューを表示することができるので、応用すれば全画面の検索フォーム表示などメニュー以外にもてっとり早く簡単にオフキャンバスコンテンツのアニメーションを表現できますね。

参考

UI with UX improvements with only CSS

Share / Subscribe
Facebook Likes
Tweets
Hatena Bookmarks
Pinterest
Pocket
Feedly
Send to LINE