Home
Menu
Side
Twitter
Top

【 シンプル・レスポンシブ対応・ドロップダウン 】 ナビゲーションバー 【 決定版 】

2020/10/28

Blog Blogger

シンプルでレスポンシブ対応、ドロップダウンメニューも実装したナビゲーションバーの作成方法です。

私は Blogger のテンプレート QooQ に実装していますが、どんなテンプレート、ブログサービスでもコピペで使えると思います。

過去に作成したものよりも CSS が少なくなり、メンテナンス性も上がりました。また、ドロップダウンメニューは自動で閉じるようにしてあります!

こんにちは、HARU( @HARU )です。

今回は過去に作成したナビゲーションバーの改良をしたので、そのことについてまとめておきます。

趣味とは言え、毎日のように HTML とか CSS とにらめっこしていると、「 あれ?もっと良くなるんじゃね? 」と思うようになり……

同じような記事が量産されてしまいますが、あくまで備忘録としてのブログ。好きなように書いていこうと思います。

とは言っても、ナビゲーションバーに関しては、これが決定版としています。

もう変更するところが無いくらい、使い勝手のよいものが出来たと思います。

過去に作成したものとの違い

過去に作成したナビゲーションバーとの違いは以下の通りです。

  • ナビゲーションバーのひな型を見直し
  • ドロップダウンリスト( 個別メニュー )が自動で閉じる

ナビゲーションバーのひな型を見直し

ドロップダウンリスト( 個別メニュー )を親要素内に入れることにより、CSS を削減することができました。

また、ナビゲーションバーの調整作業が簡単になりました。

ナビゲーションバーのひな型を見直したイメージ

ドロップダウンリスト( 個別メニュー )が自動で閉じる

ナビゲーションバーからマウスカーソルが離れたとき、自動で個別メニューが閉じるように調整しました。

もう一度、ボタンをクリックする必要が無くなるので、ユーザビリティ的にはいいのではないでしょうか。

ナビゲーションバーからマウスカーソルが離れたとき、自動で個別メニューが閉じるイメージ

ちなみにスマホ表示においても、メニューを閉じるとすべて初期状態( 個別メニューは閉じた状態 )になります。

実装イメージや導入方法

実装イメージや導入方法については、過去に作成したナビゲーションバーの記事を参考にしてください。

背景色やホバーアニメーションなど、細かい変更点はありますが、基本的には同じように導入できます。

詳しくは以下の記事をご覧ください。

ナビゲーションバー CSS

ナビゲーションバーの基本的な CSS になります。

スマホ表示用 CSS も一緒に記載してあります。


  /* ナビゲーションバーメニュー */
  /* 全体設定 */
  #top-navi{
    background-color: #fff;
    padding:0 10px;
    opacity: .9;
    position: sticky;
    top: 0;
    z-index: 19;
  }
  #menu-container {
    max-width: 1200px;
    margin: 0 auto;
    position: relative;
  }
  #menu-wrapper {
    display: none;
  }
  /* メニュー内容 */
  #menu-container ul.menu-list {
    font-size: 0; /* 横方向隙間を埋める */
  }
  #menu-container ul {
    list-style: none;
  }
  #menu-container li {
    text-decoration: none;
    text-align: center;
    padding: 0 !important;
    transition: all 0.3s ease;
    display: inline-block; /* リスト横並び */
    width: 12%; /* リストサイズ */
    font-size: 16px;
    position: relative;
  }
  #menu-container li a {
    padding: 1em 10px;
    display: block;
    transition: all 0.3s ease;
    color: #000;
  }
  #menu-container li a:hover {
    color : #ff7043;
  }
  #menu-container .menu-link{
    color: #000;
    display: block;
    padding:1em 10px;
  }
  .menu-link:after {
    font-family: FontAwesome;
    content: '\f107';
  }
  #menu-container li .menu-link:hover {
    color : #ff7043;
    transition: all 0.3s ease;
  }
  .accordion-toggle, .accordion-content {
    cursor: pointer;
    font-size: 16px;
    position: relative;
    letter-spacing: 1px;
  }
  .accordion-content {
    display: none;
    background-color: #fff;
  }
  #menu-container .accordion-content li{
    width:200px;
  }
  #menu-container ul.menu-submenu {
    position: absolute;
  }
  /* open時ボタン文字 */
  .menu-link.active{
    font-weight: bold;
    transition: all 0.3s ease;
  }
  /* ブログ内検索 */
  #menu-container li.serach{
    position: absolute;
    right: 0;
    top: 10px;
    width: 200px;
  }
  #search-box-form {
    background: #fff;
    position: relative;
  border: 1px solid #dbdcd2;
  }
  #search-box-form::placeholder {
    color: #aaa;
  }
  #search-box-text {
    border: none;
    outline: none;
    margin: .5em 0;
  }
  #search-box-submit {
    color: #888;
    font-size: 1em;
    background: transparent;
    position: absolute;
    top:0;
    right: 0;
    border: none;
    outline: 0;
    padding: .4em;
  }
  #search-box-submit:hover {
    cursor: pointer;
  }

  /* スマホ画面用 */
  @media screen and (max-width: 800px) {
  #top-navi{
    opacity: 1;
    z-index: 21;
  }
  /* メニューアイコン */
  #menu-wrapper {
    width: 60px;
    height: 60px;
    background: #696969;
    color:#fff;
    text-align: center;
    position: fixed;
    right: 0;
    top: 0;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    transition: all 0.3s ease;
    z-index: 20;
  }
  #menu-wrapper:hover {
    background-color: #808080;
  }
  #hamburger-menu {
    font-size: 30px;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  #menu-button span {
    display:block;
  }
  /* メニューリスト */
  #menu-container .menu-list {
    padding-left: 0;
    display: block;
    position: fixed;
    top:60px;
    width: 100%;
    max-width: 450px;
    background: #ffffff;
    box-shadow: rgba(100,100,100,0.2) 6px 2px 10px;
    z-index: 20;
    overflow-y: auto;
    overflow-x: hidden;
    right: -100%;
  }
  #menu-container li,#menu-container li.serach {
    display: block; /* リスト縦並び */
    width: 100%; /* リストサイズ */
    font-size: 16px;
    border-top: 1px solid #dbdcd2;
  }
  #menu-container li a {
    color:#000;
  }
  #menu-container li a,#menu-container .menu-link,#search-box-form {
    padding: 15px;
    border: none;
  }
  .accordion-content {
    background-color: #fff;
  }
  #menu-container ul.menu-submenu {
    position: static;
    width:100%;
  }
  #menu-container ul {
    overflow: hidden;
  }
  #menu-container .accordion-content li {
    width:50%;
    float:left;
    border: none;
  }
  #menu-container .menu-link{
    color:#000;
  }
  #menu-container .menu-list li.accordion-toggle, #menu-container .menu-list, li.serach {
    border-top: 1px solid #dbdcd2;
  }
  /* 背景を黒くする */
  #menu-container .menu-back.active{
    background-color: #000000;
    opacity: .7;
    z-index: 19;
    height: 100%;
    width: 100%;
    position: fixed;
    transition: all 1s ease;
    top: 0;
    left: 0;
  }
  #menu-container li.serach{
    position: static;
  }
  #search-box-submit{
    position: static;
  }
  #search-box-text{
    width:90%;
  }
  }

ナビゲーションバーのひな型

ナビゲーションバーのひな型になります。


  <!-- ナビゲーションバー -->
  <div id='top-navi'>
  <div id='menu-container'>
    <div id='menu-wrapper'>
      <div id='hamburger-menu'/>
      <div id='menu-button'>
      <i class='fa fa-bars fa-2x'/>
      <span>Menu</span>
      </div>
    </div>
    <ul class='menu-list accordion'>
      <!-- submenuなし-->
      <li><a href=''>Menu1</a></li>
      <!-- submenuあり-->
      <li class='toggle accordion-toggle'>
        <span class='menu-link'>Menu2</span>
        <ul class='menu-submenu accordion-content'>
          <li><a href=''>Submenu1</a></li>
          <li><a href=''>Submenu2</a></li>
          <li><a href=''>Submenu3</a></li>
        </ul>
      </li>
      <!-- submenuあり-->
      <li class='toggle accordion-toggle'>
        <span class='menu-link'>Menu3</span>
        <ul class='menu-submenu accordion-content'>
          <li><a href=''>Submenu1</a></li>
          <li><a href=''>Submenu2</a></li>
        </ul>
      </li>
      <!-- submenuあり-->
      <li class='toggle accordion-toggle'>
        <span class='menu-link'>Menu4</span>
        <ul class='menu-submenu accordion-content'>
          <li><a href=''>Submenu1</a></li>
          <li><a href=''>Submenu2</a></li>
          <li><a href=''>Submenu3</a></li>
          <li><a href=''>Submenu4</a></li>
        </ul>
      </li>
      <!-- submenuあり-->
      <li class='toggle accordion-toggle'>
        <span class='menu-link'>Menu5</span>
        <ul class='menu-submenu accordion-content'>
          <li><a href=''>Submenu1</a></li>
          <li><a href=''>Submenu2</a></li>
          <li><a href=''>Submenu3</a></li>
          <li><a href=''>Submenu4</a></li>
        </ul>
      </li>
      <!--検索ボックス-->
      <li class='serach'>
        <form action='/search' id='search-box-form' method='get'>
        <input data-placeholder-end='' expr:value='data:view.isSearch ? data:view.search.query.escaped : &quot;&quot;' id='search-box-text' name='q' placeholder='ブログ内検索' type='text'/>
        <button id='search-box-submit' title='検索' type='submit'><i class='fa fa-search'/></button>
        </form>
      </li>
    </ul>
    <div class='menu-back'/>
  </div>
  </div>

Script

ドロップダウンリスト( 個別メニュー )が自動で閉じる機能を追加、今回のひな型に合わせた Script になります。

過去にこのブログで紹介したナビゲーションバーを実装している場合、Script を置き換えてください。


  <!-- ナビゲーションバー ver.2 -->
  <script>
  $(function() {
    function slideMenu() {
      var activeState = $("#menu-container .menu-list").hasClass("active");
      $("#menu-container .menu-list").animate({right: activeState ? "0%" : "-100%"}, 400);
    }
    $("#menu-wrapper,.menu-back").click(function(event) {
      event.stopPropagation();
      $("#hamburger-menu").toggleClass("open");
      $("#menu-container .menu-list,.menu-back").toggleClass("active");


      slideMenu();

      $("body").toggleClass("overflow-hidden");
    });


    $(".menu-list").find(".accordion-toggle").click(function() {
      $(this).children("ul").toggleClass("open").slideToggle("fast");
      $(this).toggleClass("active-tab").find(".menu-link").toggleClass("active");

      $(".menu-list .accordion-content").not($(this).children("ul")).slideUp("fast").removeClass("open");
      $(".menu-list .accordion-toggle").not(jQuery(this)).removeClass("active-tab").find(".menu-link").removeClass("active");
    });

    $("#menu-container").mouseleave(function() {
      $(".menu-list .accordion-content").not($(this).children("ul")).slideUp("fast").removeClass("open");
      $(".menu-list .accordion-toggle").not(jQuery(this)).removeClass("active-tab").find(".menu-link").removeClass("active");
    });

  }); // jQuery load
  </script>

メニューの編集

ul タグや li タグを追加していくことで、メニューの編集を行うことができます。

階層メニューを必要としない場合


  <!-- submenuなし-->
  <li><a href=''>Menu1</a></li>

階層メニューが必要な場合

以前のものは階層メニューを追加するとき、個別メニューの表示位置を調整するためにクラス指定をしたり、CSS を変更するなど面倒な作業を必要としました。

しかし、今回のものは決まったひな型を追加するだけで対応できます。

階層メニューを必要としない場合と同じように、以下のようなコードを追加するだけで OK です。


  <!-- submenuあり-->
  <li class='toggle accordion-toggle'>
    <span class='menu-link'>Menu</span>
    <ul class='menu-submenu accordion-content'>
      <li><a href=''>Submenu1</a></li>
      <li><a href=''>Submenu2</a></li>
    </ul>
  </li>

QooQ