スマホメニューがタップに応じて表示されたり消えたりする仕組み

WordPress個別サポート

タップすると開いたり閉じたりするスマホメニュー、その仕組みは理解しているようで、理解できていなかったりします。ここでは、Twenty Twelveの例でスマホ用のメニューが開閉する仕組みを紹介します。

スマホメニュー(Twenty Twelve)
スマホメニュー(Twenty Twelve)
以下のコードはTwenty Twelveバージョン1.6の例を紹介しています。行番号はズレる場合があります。あくまで参考にとどめてください。

メニューの構造

メニュー周辺のHTMLを抜粋すると、次のようになります。

<nav id="site-navigation" class="main-navigation" role="navigation">
    <button class="menu-toggle">メニュー</button>
    <a class="assistive-text" href="#content" title="コンテンツへ移動">コンテンツへ移動</a>
    <div class="menu-global-container">
        <ul id="menu-global" class="nav-menu">
            <li>…略…</li>
        </ul>
    </div>
</nav><!-- #site-navigation -->

スマホメニューもPC用のグローバルナビゲーションも一般的にはheader.phpに記述されています。基本的には「PC用」「スマホ用」のメニューがあるわけではなく同じメニューを「PC用に表示」「スマホ用に表示」のように切り替えているだけです。

「main-navigation」というclassのnavタグがメニュー全体です。このHTMLは3つのパーツで構成されます。

  • 「button class="menu-toggle"」(2行目) --- 「メニュー」ボタンです。
  • 「a class="assistive-text"」(3行目) --- 「コンテンツへ移動」のラベルです。
  • 「div class="menu-global-container"」(4行目~) --- メニューです。具体的なメニュー項目はheader.phpに書かれたwp_nav_menuによって動的に生成されます。
「menu-global-container」の「global」は「外観」-「メニュー」で付けたメニュー名です。「メニューは英語名にした方がカスタマイズしやすい」というのは、このように扱いやすいclass名が付くからです。

PC用メニューでは「メニュー」ボタンを消す

「メニュー」ボタンはPC用のメニューでは不要です。その対応がstyle.cssの1586行目に記述されています。

@media screen and (min-width: 600px) {
    .menu-toggle {
        display: none;
    }
}

画面幅が600px以上(min-width: 600px)の場合は、ボタン(menu-toggle)を非表示(display: none;)にしています。

スマホでは「メニュー」ボタンを表示する

スマホなど画面幅が600px未満のときは上記のCSSが適用されないので、ボタン(menu-toggle)をブロック表示(display: inline-block;)する指定によって「メニュー」ボタンが表示されます。

.menu-toggle {
    display: inline-block;
}

ただし、初回アクセス時はメニュー項目を隠しておく必要があるため、メニュー(nav-menu)を非表示にしています。

.main-navigation ul.nav-menu,
.main-navigation div.nav-menu > ul {
	display: none;
}

これにより、スマホの初回アクセス時は、

  • 「メニュー」ボタンを表示する
  • メニュー項目は非表示に

のようになります。

まずは、「メニュー」ボタンのみが表示される
まずは、「メニュー」ボタンのみが表示される

「メニュー」ボタンをタップするとメニューが表示される

「メニュー」ボタンをタップするとメニューのclass名が「nav-menu toggled-on」に設定されます。これは、js/navigation.jsに書いてあります。

この点がグローバルナビゲーションのカスタマイズでつまづくポイントかもしれません。style.cssだけを見ていても、「toggled-on」というclass名が付けられたタイミングがわかりません。

その場合、JavaScriptが記述されたjsファイルも探ってみましょう。

style.cssでは、この「メニュー」ボタンをタップしたときのメニュー(.main-navigation ul.nav-menu.toggled-on)をブロック表示するCSSが設定されているので、メニューが表示されます。

.main-navigation ul.nav-menu.toggled-on {
    display: inline-block;
}
スマホ用のメニューが表示される
スマホ用のメニューが表示される

もう一度「メニュー」ボタンをタップするとメニューが消える

もう一度「メニュー」ボタンをタップするとメニューのclass名(nav-menu)から「toggled-on」が消えるので、メニューが表示されなくなります。このあたりのコードもjs/navigation.jsに書いてあります。

つまり、

  • 「メニュー」ボタンのタップ時に「toggled-on」によってメニューが表示される
  • もう一度タップすると「toggled-on」が消えてメニューも非表示になる

ということです。

CSSでメニューの表示・非表示を切り替えるのは、見えたり見えなくなったりしているだけで、HTMLにはメニュー項目が常に出力されています。モバイルからのアクセスを判定して不要なHTMLコードをスッキリ取り除く場合はwp_is_mobileなどの命令を使ってPHPで処理する必要があります。