Bloggerテンプレート自作 #25:スマホ用のヘッダーナビを作る

前回の「ページトップアイコンを作る」に引き続き、今回は「スマホ用のヘッダーナビを作る」を実践してみようと思う。

ヘッダーナビはヘッダー付近に設置されるバー状のリンクリストのことだが、リンクを増やすにつれてサイズが大きくなっていくので、デザインが崩れる原因になりやすい。なので、基本はリンクを隠しておき、必要な時にボタンクリックでリストを展開できるようにされることが多く、こうした方がデザイン的にもスッキリして見やすくなる。

というわけで、今回は「レスポンシブ対応のヘッダーナビ」の実装方法をまとめることにする。


概要


ヘッダーナビをどのように切り替えるのか?


ヘッダーナビをレスポンシブにするには、元々設置したヘッダーナビをCSSでレスポンシブ対応に書き換えるのが基本だと思う。で、元々設置したヘッダーナビの要素はそのままにCSSだけでレスポンシブデザインにすることは可能なんだけど、これだとコードが煩わしくなってしまう。

そこで、HTMLでPC用のヘッダーナビとは別にスマホ用のヘッダーナビを作り、これをレスポンシブ設定のCSSでデザインするとコードも見やすくなり、作業が楽になる。で、これらを切り替える際にdisplay:none;でそれぞれの表示・非表示を切り替えればOK。

どんな感じのヘッダーナビを作るつもりなのか?


Bloggerテンプレート自作 #25:スマホ用のヘッダーナビを作る

目指しているヘッダーナビのデザインは、画像のようにメニューボタンでリンクリストを展開し、サイドボタンでサイドバーを呼び出すもの。これはWordPressで自作したデザインなのだが、今回はこれをBloggerで再現しようという主旨で作業を進めることにした。

作業工程


スマホ用ヘッダーナビのHTMLを作る


<!-- PC用ヘッダーナビの記述(省略) -->

<!-- スマホ用ヘッダーナビ -->
<div class="navbar-res">
  <div class="menu-area">
    <input type="checkbox" id="menu-open" class="toggle-button" />
    <label for="menu-open" class="menu-button">
      <div class="button-text"><i id="menu-icon" class="fas fa-bars" />MENU</div>
    </label>
    <label for="menu-open" class="menu-back"></label>
    <div class="nav-menu">
      <ul>
        <b:loop values='data:links' var='link'>
          <li>
            <a expr:href='data:link.href'>
              <data:link.title />
            </a>
          </li>
        </b:loop>
      </ul>
    </div>
  </div>
  <div class="side-area">
    <input type="button" onclick="location.href='#aside'" id="side-jump" class="toggle-button" />
    <label for="side-jump" class="side-button">
      <div class="button-text">SIDE<i id="side-icon" class="fa fa-angle-double-down" /></div>
    </label>
  </div>
</div>

<!-- 中略 -->

<!-- asideタグにid="aside"を追加 -->

上記がスマホ用のヘッダーナビのコード。これをPC用ヘッダーナビの下に記述する(ヘッダーナビガジェット内)。

コードを見てお気づきの方もおられるかもしれないが、結論から言えばサイドバーの呼び出しを諦めた結果、このようなコードとなった。

なお、サイドボタンはサイドバーへのページ内リンクになっているので、<aside>タグに「id="aside"」を追加する必要がある。

CSSの設定をする


Bloggerテンプレート自作 #25:スマホ用のヘッダーナビを作る

/* PCではスマホ用のヘッダーナビを消す */
.navbar-res {
  display: none;
}

/* スマホ用ヘッダーナビ
---------------------------------------------------------------------------- */

/* WEBフォント */

@import url('https://fonts.googleapis.com/css?family=M+PLUS+Rounded+1c');
@import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap');

/* チェックボックスを隠す */

.toggle-button {
  position: absolute;
  left: -50vw;
}

@media screen and (max-width: 560px) {
  /* スマホではPC用のヘッダーナビを消す */
  .navbar {
    display: none;
  }
  /* ヘッダーナビ */
  .navbar-res {
    display: flex;
    justify-content: space-between;
    background: #444;
  }
  /* ボタンデザイン */
  .menu-button, .side-button {
    display: block;
    cursor: pointer;
    user-select: none;
    color: #fff;
    padding: 8px 10px;
  }
  .menu-button:hover, .side-button:hover {
    background: #666;
  }
  /* ボタンの文字 */
     .button-text {
       font-size: 20px;
       font-family: 'Bebas Neue', sans-serif;
     }
     #menu-icon {
       font-size: 18px;
       font-weight: 600;
       margin-right: 8px;
     }
     #side-icon {
       font-size: 22px;
       font-weight: 600;
       margin-left: 8px;
     }
  /* リスト */
    .navbar-res ul {
      list-style: none;
      padding: 0;
      margin: 0;
    }
    .nav-menu {
      display: none;
      position: absolute;
      width: 100%;
      list-style: none;
      z-index: 99;
    }
    .nav-menu li {
      padding: 0;
    }
    /* リストリンクの設定 */
    .nav-menu a {
      display: block;
      color: #fff;
      background: #333;
      font-size: 15px;
      opacity: 0.9;
      text-decoration: none;
      font-family: 'Archivo Black', 'M PLUS Rounded 1c', sans-serif;
      font-weight: bold;
      padding: 10px 15px;
      margin: 0;
    }
    .nav-menu a:hover {
      background: #666;
      opacity: 1;
    }
    /* MENUボタンアクション */
    #menu-open:checked~.nav-menu {
      display: block;
    }
    #menu-open:checked~.menu-back {
      display: block;
      position: fixed;
      top: 0vw;
      left: 0vw;
      width: 100%;
      height: 100%;
      margin-bottom: 10px;
      overflow: hidden;
      z-index: 99;
    }
    /* メニューアニメ */
    #menu-open:checked~.nav-menu {
      animation-name: nav-menu;
      animation-duration: 0.3s;
      animation-iteration-count: 1;
      animation-fill-mode: both;
    }
    @keyframes nav-menu {
      0% {
        opacity: 0;
        transform: translateY(-5px);
      }
      100% {
        opacity: 1;
        transform: translateY(0);
      }
    }
  }

上記がスマホ用のヘッダーナビを構成するCSSになる。

ヘッダーナビのリンクリストはメニューボタンをタップすると下方向に展開する。その際にスライドダウンのような簡単なアニメーションが付くようにした。また、リスト外をタップすることで、リストを閉じられるようになっている。

サイドボタンは、本来サイドバーを表示させる目的だったのだが、無理だったのでタップすることでサイドバーにジャンプする設定になっている。サイドボタンには特にCSSを設定していないので、不要であればサイドボタン部分のHTMLを削除してしまえば消せる。

余談


サイドバー呼び出しが WordPressで出来て Bloggerで出来ない理由


WordPressはPHPで構成されているが、その中身はほぼHTMLで作られている。また、WordPressの機能で切り分けた処理をコードひとつで呼び出せるので、サイドバーを切り分けておいて、それをそのまま指定位置に呼び出すなんてことが容易にできる。

一方、Bloggerには そんな便利機能が無く、さらにサイドバーのコンテンツがsectionやwidgetと切り分けられているので、基本的に定位置から動かすことができないっぽい。なので、実現するのは難しいと思う(JavaScriptでサイドバーのポジションや要素の重なりなんかをいじれば実装は可能かもしれない)。