非表示にしたメニューをクリックでモーダルウィンドウ風に画面いっぱいに表示する
最近良く見かけるメニューですね。メニューボタンをクリックするとモーダルウィンドウが画面いっぱいに広がって項目が表示されるやつ。今まで一度も使ったことがなかったので、流行ってる(?)し、試しにちょっと作ってみました。
target擬似クラスを使えばCSSだけでも実装できるようなんですけど、フラグメント識別子を付けたり変えたりすると、ブラウザの「戻る」が反応してしまい、それが好みじゃなかったので、一般的なjQuery+CSSで実装しています。jQueryといっても、クリックイベントだけなので、実質CSSみたいなものですけど。
モーダルウィンドウメニュー
以下のリンクから試しに作ってみたもの(デモ)がご覧になれます。右上の「MENU」というところをクリックすると、モーダルウィンドウが表示されるようになっています。
以下、簡単に仕組みとかを書いておきます。
モーダルウィンドウメニューのHTML
HTMLは大きく分けて、メインのコンテンツ部分、開閉用のボタン部分、メニュー部分の3つに分かれています。body要素とかは記載していませんので適宜追加する必要があります。
<!-- メインコンテンツ-->
<div class="wrapper">
<!-- ここはコンテンツ -->
</div>
<!-- 開閉用ボタン -->
<div class="menu-btn" id="js__btn">
<span data-txt-menu="MENU" data-txt-close="CLOSE"></span>
</div>
<!-- モーダルメニュー -->
<nav class="menu" id="js__nav">
<ul>
<li><a href="#">メニュー名</a></li>
<li><a href="#">メニュー名</a></li>
<li><a href="#">メニュー名</a></li>
<li><a href="#">メニュー名</a></li>
</ul>
</nav>
HTMLはこれといって特筆すべきことはなく、普通な感じ。開閉用ボタンのところだけ、テキストを変更するためデータ属性をあてています。
モーダルウィンドウメニューのCSS
CSSは以下の通り。メインのコンテンツ部分のCSSは除外、また一部のアニメーション等は長くなるので省略しています。
開閉用ボタンのスタイル
.menu-btn {
position: fixed;
top: 20px;
right: 20px;
width: 100px;
height: 50px;
line-height: 50px;
font-size: 12px;
text-align: center;
cursor: pointer;
z-index: 1;
}
.menu-btn span {
color: #fff;
}
.menu-btn span:after {
content: attr(data-txt-menu);
}
/* 開閉用ボタンがクリックされた時のスタイル */
.open .menu-btn span:after {
content: attr(data-txt-close);
}
ボタンのスタイルにはdiv
要素を使っていますが、a
要素でもbutton
要素でも何でもいいと思います。div
の場合は、cursor: pointer;
を追加しておくといいですね。
HTMLの所でも触れましたが、ボタンのテキストはデータ属性を使って、通常時とモーダルメニュー表示時でテキストを切り替えています。HTMLのデータ属性に入力した値を、CSS(after疑似要素)のcontent:attr()
で取得しているわけですが、これだとJSを利用しなくてもいいので(間接的には利用しているけど)、簡単にテキストの切替えを行うことができます。
ボタンの位置はposition:fixed
で右上に固定しています。
モーダルウィンドウのスタイル
.menu {
position: fixed;
display: table;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,.8);
-webkit-transition: all .5s;
transition: all .5s;
visibility: hidden;
opacity: 0;
}
.menu ul {
display: table-cell;
vertical-align: middle;
}
.menu li {
width: 300px;
height: 80px;
line-height: 80px;
margin: 0 auto;
text-align: center;
}
.menu li a {
display: block;
font-size: 18px;
color: #fff;
}
.menu li a:hover {
color: #999;
}
/* 開閉用ボタンがクリックされた時のスタイル */
.open .menu {
cursor: url(../images/cross.svg),auto;
-webkit-transition: all .5s;
transition: all .5s;
visibility: visible;
opacity: 1;
}
モーダルウィンドウの部分は、visibility: hidden;
とopacity: 0;
を使って普段の状態では非表示にしています。visibility
ではなくdisplay: none
でもいいのですが、メニューを中央表示にしたかったので、display
にはtable
を指定して、visibility
で要素自体を非表示にしています。というか、この場合はvisibility
のほうがいいでしょうね、たぶん。
ちなみに、display:table
での縦位置中央表示は、子要素にdisplay:table-cell
とvertical-align:middle
を指定することで実現できます。
モーダルの表示は、開閉用のボタンをクリックした時に、jQueryで.open
というクラスをbody
に与え、事前に.open
というクラスが付与された時のスタイル(visibility:visible;
とopacity:1;
)を用意しておくことで、表示・非表示が切り替わる仕組みとなっています。
開閉用ボタンのテキストが変更するのも、.open
というクラスがあるかないかで、スタイルシートで切り替えています。
モーダルが表示されている時、メニュー名以外の部分にマウスをあてるとカーソルが「×」になるようにしていますが、これはcursor: url(../images/cross.svg),auto;
でカーソルを画像に変更しています(一部のブラウザでは表示されません)。カーソルの変更が必要なければ、この部分は削除でいいですね。
モーダルウィンドウメニューのjQuery
$(function () {
var $body = $('body');
//開閉用ボタンをクリックでクラスの切替え
$('#js__btn').on('click', function () {
$body.toggleClass('open');
});
//メニュー名以外の部分をクリックで閉じる
$('#js__nav').on('click', function () {
$body.removeClass('open');
});
});
jQueryは非常にシンプルです。開閉用のボタンがクリックされた時の処理と、メニュー名以外の部分がクリックされた時の処理が簡単に書かれているだけです。
ブラウザについて
jQueryがシンプルな分、ほとんどCSSでなんとかしている感じになるので、古いブラウザには対応していません。いずれも最新のブラウザであれば問題なく表示しているかと思います。
Chrome、Safari、Firefox、IE11で表示されることを確認しています。
使いどころとか
アニメーションを組み合わせると、なかなか良さ気な感じになりますね。今まで使ったことはないんですけど、今度使ってみようと思いました。ミニマルなサイトに合いそう。
使いどころとしては、レスポンシブなサイトと相性がいいかもしれませんね。全面に表示されるので、操作しやすそうです。コード自体にも、特に何か追加することなく、そのままレスポンシブとして使えるかと思います(文字の大きさとかは調整が必要かも)。
おわり
たいしたテクニックでもなんでもないんですが、こうやってブログにまとめておくことで、色々と気付きや新たな知識が得られたりするので、今後もくだらないテクニックをだらだらと書き残していきたいと思います。