【具体的なコードあり】スマホでグローバルメニューを表現する5パターン

目次
  1. 事前のおことわり
    1. jQueryを使用!
    2. ハンバーガーアイコンのCSSは共通
    3. ブレイクポイントは786px
  2. 改行
  3. スライドダウン
    1. コンテンツに内包されたパターン
    2. 浮かせたパターン
  4. ドロワー
    1. 浮かせたパターン
    2. 画面ごとスライドするパターン
  5. モーダル
  6. 水平スクロール
  7. おわり

スマホの限られたスペースでメニューを表現するための5つのパターンを具体的なコードと共に紹介します。

スマホメニューを表現する際の基本となる5パターンなので、しっかりと使いこなせるようにしておきましょう!

事前のおことわり

今回のサンプルコードをお使いになる際の前提条件です。目を通してから進んでください!

jQueryを使用!

今回のサンプルではjQueryを使用しています。
ですので、jQueryが動作する環境でお試しいただけますと幸いです。

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

ハンバーガーアイコンのCSSは共通

ハンバーガーアイコンを使用するサンプルがいくつかありますが、すべて共通して以下のデザインを当てています。都度コードを貼り付けることはしていないので、ハンバーガーアイコンを使っているものは、こちらのコードを適用させてください。

<div class="icon-hamburger"><span></span></div>
.icon-hamburger {
  background: #fff;
  border: 1px solid #ccc;
  cursor: pointer;
  height: 50px;
  position: relative;
  width: 50px;
	display: none;
  margin-bottom: 0.4em;
}

.icon-hamburger span {
  background: #cccccc;
  display: block;
  height: 16%;
  left: 50%;
  margin: -8% 0 0 -42%;
  position: absolute;
  top: 50%;
  width: 84%;
}

.icon-hamburger span::before,
.icon-hamburger span::after {
  background: #cccccc;
  content: "";
  display: block;
  height: 100%;
  left: 50%;
  margin: -8% 0 0 -50%;
  position: absolute;
  top: 50%;
  width: 100%;
}

.icon-hamburger span::before {
  margin-top: -38%;
}

.icon-hamburger span::after {
  margin-top: 19%;
}

@media screen and (max-width: 768px) {
  .icon-hamburger {
    display: inline-block;
  }
}

ブレイクポイントは786px

スマホ、スマホ以外の判定はiPad縦表示の786pxで行っています。この辺りは柔軟に対応してください。

改行

もっとも簡単なメニュー表現方法です。6列で表示させていたメニューを3列で表示させるみたいな感じですね。

<nav class="menu-container">
	<ul class="menu">
		<li class="menu-item"><a href="#">ホーム</a></li>
		<li class="menu-item"><a href="#">ページ A</a></li>
		<li class="menu-item"><a href="#">ページ B</a></li>
		<li class="menu-item"><a href="#">ページ C</a></li>
		<li class="menu-item"><a href="#">ページ D</a></li>
		<li class="menu-item"><a href="#">ページ E</a></li>
	</ul>
</nav>
.menu-container {
  margin: 0;
}

.menu-container .menu {
  display: flex;
  justify-content: space-between;
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu-container .menu .menu-item {
  flex: 1;
}

.menu-container .menu .menu-item a {
  background: #fff;
  border: 1px solid #ccc;
  border-right: none;
  color: #333;
  display: block;
  padding: 0.6em 0.4em;
  text-align: center;
  text-decoration: none;
}

.menu-container .menu .menu-item a:hover {
  background: #ccc;
  color: #ffffff;
}

.menu-container .menu .menu-item:last-child a {
  border-right: 1px solid #ccc;
}

@media screen and (max-width: 768px) {
  .menu-container .menu {
    flex-wrap: wrap;
    width: 100%;
  }
  .menu-container .menu .menu-item {
    flex: auto;
    width: 33.33333333%;
  }
  .menu-container .menu .menu-item:nth-child(3n) a {
    border-right: 1px solid #ccc;
  }
  .menu-container .menu .menu-item:nth-child(n + 4) a {
    border-top: none;
  }
}

メニューの数を3つずつで改行させる処理を行っています。「3」という数字は決め打ちなので、もうちょっとスマートな方法があるかもしれません…。

スライドダウン

ハンバーガーアイコンを押すと上からスライドダウンして表示されるメニューです。PCでは横並びのメニューが縦並びになるので、CSSの上書きであったり、JavaScriptの記述など面倒なことが増えます。

コンテンツに内包されたパターン

コンテンツの一部?(浮かせていない)なので、スライドダウンした面積分、下の要素が下がります。

<div class="icon-hamburger"><span></span></div>
<nav class="menu-container">
	<ul class="menu">
		<li class="menu-item"><a href="#">ホーム</a></li>
		<li class="menu-item"><a href="#">ページ A</a></li>
		<li class="menu-item"><a href="#">ページ B</a></li>
		<li class="menu-item"><a href="#">ページ C</a></li>
		<li class="menu-item"><a href="#">ページ D</a></li>
		<li class="menu-item"><a href="#">ページ E</a></li>
	</ul>
</nav>
.menu-container {
  margin: 0;
}

.menu-container .menu {
  border: 1px solid #ccc;
  display: flex;
  justify-content: space-between;
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu-container .menu .menu-item {
  flex: 1;
}

.menu-container .menu .menu-item a {
  background: #fff;
  border-right: 1px solid #ccc;
  color: #333;
  display: block;
  padding: 0.6em 0.4em;
  text-align: center;
  text-decoration: none;
}

.menu-container .menu .menu-item a:hover {
  background: #ccc;
  color: #ffffff;
}

.menu-container .menu .menu-item:last-child a {
  border-right: none;
}

@media screen and (max-width: 768px) {
  .menu-container .menu {
    display: none;
    width: 100%;
  }
  .menu-container .menu .menu-item a {
    border-bottom: 1px solid #ccc;
    border-right: none;
  }
  .menu-container .menu .menu-item:last-child a {
    border-bottom: none;
  }
}
jQuery('.icon-hamburger').on('click', function() {
	if(jQuery('.menu-container .menu').css('display') === 'block') {
		jQuery('.menu-container .menu').slideUp('1500');
	}else {
		jQuery('.menu-container .menu').slideDown('1500');
	}
});

JQueryの関数slideUp、slideDownで表示・非表示を切り替えています。1500という数字はアニメーションの時間です。1500は1.5秒を表しますので、こちらもサイトに合わせて変更してみてください。

浮かせたパターン

既存のコンテンツに影響を与えないようにメニューを浮かせるパターンです。

<div class="icon-hamburger"><span></span></div>
<nav class="menu-container">
	<ul class="menu">
		<li class="menu-item"><a href="#">ホーム</a></li>
		<li class="menu-item"><a href="#">ページ A</a></li>
		<li class="menu-item"><a href="#">ページ B</a></li>
		<li class="menu-item"><a href="#">ページ C</a></li>
		<li class="menu-item"><a href="#">ページ D</a></li>
		<li class="menu-item"><a href="#">ページ E</a></li>
	</ul>
</nav>
.menu-container {
  margin: 0;
  position: relative;
}

.menu-container .menu {
  border: 1px solid #ccc;
  display: flex;
  justify-content: space-between;
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu-container .menu .menu-item {
  flex: 1;
}

.menu-container .menu .menu-item a {
  background: #fff;
  border-right: 1px solid #ccc;
  color: #333;
  display: block;
  padding: 0.6em 0.4em;
  text-align: center;
  text-decoration: none;
}

.menu-container .menu .menu-item a:hover {
  background: #ccc;
  color: #ffffff;
}

.menu-container .menu .menu-item:last-child a {
  border-right: none;
}

@media screen and (max-width: 768px) {
  .menu-container .menu {
    display: none;
    position: absolute;
    width: 100%;
  }
  .menu-container .menu .menu-item a {
    border-bottom: 1px solid #ccc;
    border-right: none;
  }
  .menu-container .menu .menu-item:last-child a {
    border-bottom: none;
  }
}
jQuery('.icon-hamburger').on('click', function() {
	if(jQuery('.menu-container .menu').css('display') === 'block') {
		jQuery('.menu-container .menu').slideUp('1500');
	}else {
		jQuery('.menu-container .menu').slideDown('1500');
	}
});

position: relative;とposition: absolute;を追加して浮かせる処理を追加しています。スライドダウンを浮かせるかどうかは好みの問題なので、好きな方を選ぶといいかと思います。

また、浮かせる場合は、幅100%にする必要もないかもしれません。position: absolute;の下にあるwidth: 100%;をwidth: auto;などにして、要素の大きさに依存させるのもいいかと思います。

ドロワー

ドロワーで表現するパターンです。肌感覚としてはドロワーで表現しているサイトが一番多い気がします。
こちらは外部ライブラリを使っています。記事内にソースと説明を書くと長くなりすぎるので、個別記事に実装方法をまとめていました。

浮かせたパターン

コンテンツの上を覆うようにスライドしてくるドロワーです。「drawer.js」を使用します。

使い方は以下を参考にしてください。
→ ドロワーメニューが作れるjQueryライブラリ「drawer.js」のご紹介!

画面ごとスライドするパターン

画面ごとスライドするドロワーです。「hiraku.js」を使用します。
一昔前のスマホアプリでよく使われていた記憶がありますね。

モーダル

画面すべてを覆ってメニューだけに集中させるモーダル表示のパターンです。こちらもスマホメニューの主流になりつつあるように思います。

<div class="icon-hamburger"><span></span></div>
<nav class="menu-container">
	<ul class="menu">
		<li class="menu-item"><a href="#">ホーム</a></li>
		<li class="menu-item"><a href="#">ページ A</a></li>
		<li class="menu-item"><a href="#">ページ B</a></li>
		<li class="menu-item"><a href="#">ページ C</a></li>
		<li class="menu-item"><a href="#">ページ D</a></li>
		<li class="menu-item"><a href="#">ページ E</a></li>
	</ul>
</nav>
.menu-container {
  margin: 0;
}

.menu-container .menu {
  border: 1px solid #ccc;
  display: flex;
  justify-content: space-between;
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu-container .menu .menu-item {
  flex: 1;
}

.menu-container .menu .menu-item a {
  background: #fff;
  border-right: 1px solid #ccc;
  color: #333;
  display: block;
  padding: 0.6em 0.4em;
  text-align: center;
  text-decoration: none;
}

.menu-container .menu .menu-item a:hover {
  background: #ccc;
  color: #ffffff;
}

.menu-container .menu .menu-item:last-child a {
  border-right: none;
}

#modal-overlay {
  background-color: rgba(0, 0, 0, 0.6);
  display: none;
  height: 120%;
  left: 0;
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 99;
}

@media screen and (max-width: 768px) {
  .menu-container .menu {
    -webkit-transform: translate(-50%, -50%);
    background: #fff;
    display: none;
    height: auto;
    left: 50%;
    position: fixed;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 80%;
    z-index: 100;
  }
  .menu-container .menu .menu-item a {
    border-bottom: 1px solid #ccc;
    border-right: none;
  }
  .menu-container .menu .menu-item:last-child a {
    border-bottom: none;
  }
}
jQuery('.icon-hamburger').on('click', function() {
	jQuery('body').append('<div id="modal-overlay"></div>');
	jQuery('#modal-overlay').fadeIn('1500');
	jQuery('.menu-container .menu').fadeIn('1500');
});

jQuery(document).on('click', '#modal-overlay', function() {
	jQuery('#modal-overlay').fadeOut('1500');
	jQuery('.menu-container .menu').fadeOut('1500');
});

モーダルはメニューに限定せずに、様々なコンテンツを配置することが可能です。

作り方としては、

  • 透明黒背景の#modal-overlayを用意すること
  • コンテンツエリアを用意すること
  • クリックイベントで上記の表示・非表示を切り替えること

文字だけで簡単に説明すると、これだけです。
今回はコンテンツエリアをメニューにしましたが、もっと拡大してメニュー以外も含めたエリアを用意するなど、やれる可能性は無限大です。

スマホの限られたスペースでモーダルを使えば、実質2画面あるような感じに表現できるので、コンテンツ量が多い方はモーダルを上手く使うといいでしょう。

水平スクロール

メニューの横並びは変更せずに水平スクロールにするパターンです。

<nav class="menu-container">
	<ul class="menu">
		<li class="menu-item"><a href="#">ホーム</a></li>
		<li class="menu-item"><a href="#">ページ A</a></li>
		<li class="menu-item"><a href="#">ページ B</a></li>
		<li class="menu-item"><a href="#">ページ C</a></li>
		<li class="menu-item"><a href="#">ページ D</a></li>
		<li class="menu-item"><a href="#">ページ E</a></li>
	</ul>
</nav>
.menu-container {
  margin: 0;
  overflow-x: auto;
}

.menu-container .menu {
  display: flex;
  justify-content: space-between;
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu-container .menu::after {
  clear: both;
  content: "";
  display: block;
}

.menu-container .menu .menu-item {
  flex: 1;
  white-space: nowrap;
}

.menu-container .menu .menu-item a {
  background: #fff;
  border: 1px solid #ccc;
  border-right: none;
  color: #333;
  display: block;
  min-width: 150px;
  padding: 0.6em 0.4em;
  text-align: center;
  text-decoration: none;
}

.menu-container .menu .menu-item a:hover {
  background: #ccc;
  color: #ffffff;
}

.menu-container .menu .menu-item:last-child a {
  border-right: 1px solid #ccc;
}

white-space: nowrap;を加えることで文字が改行されずに横にはみ出すようになります。aタグに幅を固定させることでも幅を維持できます(今回のサンプルではmin-width: 150px;)

メニューを囲むコンテナーにoverflow-x: auto;を設置して水平スクロールを実現しています。

いろんなサイトを見ていると、この水平スクロールだけでメニューを代替しているという感じではなく、水平スクロールメニュー + ドロワーメニューみたいに、組み合わせて使うケースが多いように感じます。
(たしかに水平スクロールはそれほどユーザビリティがいいようには思いません…)

おわり

具体例とともにスマホでグローバルメニューを表現する5パターンを紹介しました。

この5パターンがスマホでメニューを表現する際の基本だと思います。コピペするだけじゃなく、内容を理解して柔軟に使いこなせるようにしておくとレスポンシブ化が楽になりますよ!

WordPressでお悩みの方はお気軽にご相談ください。

ちょっとしたお困り事からサイト全体のリニューアルのようなご依頼まで、お悩みに応じて柔軟に対応いたします。

この記事を書いた人

はにわまん

HPcode代表。300件以上のWordPress案件を対応してきました。ちょっとしたWordPressのカスタマイズからブロックテーマでのリニューアルまで。更新できるWordPressサイトが好きです。