仕組みを理解しながら、SPメニュー(バンバーガーメニュー)をHTML・CSS・Javascriptで作成する
やりたいこと
PCの場合は、サイドバーにウィジェットを表示していたが、SP(スマートフォン)の場合は、サイドバーが邪魔になるので非表示にした
参考:WordPressレスポンシブデザインでのサイドバーの作り方(SPではサイドバーを非表示とする)
その代わりに、SPでは、ボタンを押すと、サイドメニューが表示されるようにしたい
実装方針:ハンバーガーメニュー
まずは、左上にハンバーガーアイコンを設置する
このアイコンは、「position: fixed;」を使って、スクロールしても、同じ位置に固定されるようにする
三本の線は、細い長方形。CSSで作成する
このアイコンはクリックすると、バツ印になる
クリックすると、真ん中の線が消え、残りの線が回転することによってバツ印となる
実装方針:SPメニュー表示・非表示
SPメニューは、デフォルトは画面の外に隠れていて、ハンバーガーアイコンをクリックすると表示される
CSSで、「spmenu-open」というクラスが無い時は、隠れた状態のポジション、「spmenu-open」というクラスありでは、表示された状態のポジションを定義しておく
JavaScriptでハンバーガーアイコンをクリックしたら、「spmenu-open」というクラスを付与するようにすれば、クリックに連動して、表示非表示が切り替えられる
SP用サイドバーの作成
やりたいことと、実装方針が決まったので、実際に実装していく
以下記事を参考に、SP用サイドバーを作成しておく
(idが被るため、PC用に呼び出しているサイドバーを呼び出すことはできない)
参考:WordPressでオリジナルテンプレートを作る時にSidebarにWidgetsを追加できるようにする(サイドバーの有効化)
HTMLの作成
長くなるので、SP用メニュー部分は別ファイル(spmenu.php)に外出しして、呼び出すようにする
$ cat spmenu.php <div id="spmenu-wrapper"> <!-- ハンバーガーアイコン --> <div id="hamburger"> <span class="hamburger-line" id="hamburger-line-1"></span> <span class="hamburger-line" id="hamburger-line-2"></span> <span class="hamburger-line" id="hamburger-line-3"></span> </div> <!-- SP用メニュー --> <div id="sp-menu"> <div id="sp-menu-widget-area"> <?php dynamic_sidebar( 'Sidebar-SP' ); ?> </div> </div> </div> <script> window.onload = function () { var wrapper = document.getElementById('spmenu-wrapper'); var hamburger = document.getElementById('hamburger'); hamburger.addEventListener('click', function () { wrapper.classList.toggle('spmenu-open'); // クリックされたら'spmenu-open'クラスを付与 }); }; </script>
$ cat index.php <!DOCTYPE html> <html <?php language_attributes( ); ?>> <!-- multi-language supports --> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="<?php bloginfo( 'charset' ); ?>"> <link rel="stylesheet" href="<?php echo get_stylesheet_uri( ); ?>"> <?php wp_head(); ?> </head> <body <?php body_class( ); ?>> <?php get_template_part('spmenu'); ?> <!-- SP用メニューの呼び出し --> <div id="wrapper"> <aside> <?php dynamic_sidebar( 'Sidebar' ); ?> </aside> <div id="contents"> contentsだよ </div> </div> <?php wp_footer(); ?> </body> </html>
CSSの作成
CSSは以下の通り
/* spmenu ========================================================================== */ @media screen and (min-width:751px) { #spmenu-wrapper { display: none; } } @media screen and (max-width:750px) { #hamburger { position: fixed; left: 10px; top: 10px; z-index: 102; /* sp-menuより前 */ height: 50px; width: 50px; border-radius: 50%; background: #ffffff; opacity: 0.8; } .hamburger-line { position: absolute; height: 2px; left: 10px; width: 30px; background: #616161; transition: 0.5s; /* transformで動かす時のスピード */ } #hamburger-line-1 { top: 12px; } #hamburger-line-2 { top: 24px; } #hamburger-line-3 { top: 36px; } .spmenu-open #hamburger-line-1 { transform: rotate(-45deg); /* クリックされたら回転 */ top: 24px; } .spmenu-open #hamburger-line-2 { opacity: 0; /* クリックされたら真ん中の線は見えないようにする */ } .spmenu-open #hamburger-line-3 { transform: rotate(45deg); /* クリックされたら回転 */ top: 24px; } #sp-menu { position: fixed; left: -250px; /* クリックされる前は画面の外左側に隠す */ top: 0; width: 250px; height: 100vh; /* 画面いっぱい */ z-index: 101; /* hamburgerより後ろ */ overflow-y: auto; /* メニューが多くなったらスクロールできるように */ transition: 0.5s; /* transformで動かす時のスピード */ background: #ffffff; opacity: 0.9; } .spmenu-open #sp-menu { transform: translateX(250px) /* クリックされたら画面の中へ */ } #sp-menu-widget-area { margin-top: 60px; /* ハンバーガーに被らないように下げる */ padding: 10px; } }
これで完成。問題なく動作するはず