CSS

【よくある】ヘッダーテンプレ(レスポンシブ対応図解付き)について解説

※ 当サイトではアフィリエイト広告を利用しています

【よくある】ヘッダーテンプレ(レスポンシブ対応図解付き)について解説

この記事では「よくあるヘッダーテンプレ(レスポンシブ対応図解付き)」について解説していきます。

今回は、

  • 王道的なヘッダー
  • ミニマルなヘッダー
  • プルダウンメニューがあるヘッダー

の3パターンについて解説します。

この記事を読むと...
  • ヘッダーテンプレの作り方が分かる
  • 3種類のレスポンシブ対応ヘッダーパターンをコピペで作成できる

3日間限定でNotionスニペットコーディング実践集を「半額」にて販売中です↓

Notionスニペットコーディング実践集▶︎▶︎

返金申請もできる様にしてあります。

もし思った内容と違う。 内容が薄い等あれば返金申請可能です。

王道的なヘッダーデザイン(ヘッダーパターン1)

よくある王道的なデザインのヘッダーになります。

コードは以下になります。

  <header class="l-header p-header">
    <div class="p-header__inner">
      <h1 class="p-header__title">
        ロゴ
      </h1>
      <div class="p-header__hamburger">
        <button class="c-hamburger">
          <span></span>
          <span></span>
          <span></span>
        </button>
      </div>
      <nav class="p-header__nav p-nav">
        <div class="p-nav__inner">
          <ul class="p-nav__list">
            <li class="p-nav__item">
              <a href="" class="p-nav__link">
                メニュー
              </a>
            </li>
            <li class="p-nav__item">
              <a href="" class="p-nav__link">
                メニュー
              </a>
            </li>
            <li class="p-nav__item">
              <a href="" class="p-nav__link">
                メニュー
              </a>
            </li>
          </ul>
        </div>
      </nav>
    </div>
  </header>
  <main>
    メインコンテンツ
  </main>
  <footer>フッター</footer>
body,
p,
ul,
li,
div,
h1 {
  margin: 0;
  padding: 0;
}

ul,
ol {
  list-style: none;
}


a {
  text-decoration: none;

}

main {
  background-color: orange;
  width: 100%;
  height: 1000px;
}

footer {
  width: 100%;
  height: 100px;
  background-color: rgb(249, 205, 121);
}

/* パターン1 */
.l-header {
  display: block;
  z-index: 999;
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  width: 100%;
  background: #fff;
}


.c-hamburger {
  position: relative;
  width: inherit;
  height: inherit;
  margin: 0;
  border: transparent;
  background-color: transparent;
  cursor: pointer;
}



.c-hamburger span {
  display: block;
  position: relative;
  left: 50%;
  width: 24px;
  height: 2px;
  transform: translateX(-50%);
  background: black;
  transition: all 0.4s;
}

.c-hamburger span:nth-of-type(1) {
  top: -4px;
}

.c-hamburger span:nth-of-type(2) {
  top: 1px;

  transform: translateX(-0.45deg);
}

.c-hamburger span:nth-of-type(3) {
  top: 6px;
  transform: translateX(-0.45deg);
}



.c-hamburger.is-active span:nth-of-type(1) {
  top: 0;
  transform: translateX(-50%) rotate(225deg);
}

.c-hamburger.is-active span:nth-of-type(2) {
  opacity: 0;
}

.c-hamburger.is-active span:nth-of-type(3) {
  top: -4px;
  transform: translateX(-50%) rotate(-225deg);
}




.p-header__nav {
  display: flex;
  z-index: 10;
  position: absolute;
  top: 0;
  right: -100%;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100vh;
  background: transparent;
  opacity: 0;
  transition: top 0.6s, right 0.6s, opacity 0.6s;
}

.p-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: inherit;
  padding: 0 20px;

}

.p-header__hamburger {
  z-index: 100;
  position: absolute;
  top: 0;
  right: 0;
  width: 95px;
  height: 100%;
}

.p-header__nav.is-active {
  position: fixed;
  top: 0;
  right: 0;
  opacity: 1;
  background-color: #fff;
}

.p-nav__list {
  display: block;
  padding-right: 20px;
  padding-left: 20px;
}

.p-nav__item {
  position: relative;
  width: 100%;
}


.p-nav__link {
  color: black;
  display: block;
  padding: 20px;
  width: 100%;
}



@media screen and (min-width: 768px) {

  .p-header__hamburger {
    display: none;
  }

  .p-nav__inner {
    margin-right: auto;
    margin-left: auto;
    max-width: initial;
    width: 100%;
  }

  .p-header__nav {
    position: static;
    opacity: 1;
    height: inherit;
    width: initial;
  }

  .p-nav__list {
    padding-right: 0;
    padding-left: 0;
    display: flex;
  }
}
document.addEventListener('DOMContentLoaded', function () {
  const hamburger = document.querySelector('.c-hamburger');
  const headNav = document.querySelector('.p-header__nav');


  if (!hamburger) {
    return false;
  }

  hamburger.addEventListener('click', () => {
    if (hamburger.classList.contains("is-active")) {
      hamburger.classList.remove('is-active');
      headNav.classList.remove('is-active')
    } else {
      hamburger.classList.add('is-active');
      headNav.classList.add('is-active')
    }

  });

  headNav.addEventListener('click', () => {
    hamburger.classList.remove('is-active');
    headNav.classList.remove('is-active')
  });
});

〇 PC画面サイズ

PC画面サイズヘッダー1

〇 モバイル画面サイズ

王道的なヘッダーパターン

See the Pen 王道的なヘッダーパターン by 山中滉大 (@tips-web) on CodePen.

ロゴとヘッダーナビが横並びになっている王道的な配置になります。

モバイル画面サイズになったらハンバーガーメニューが表示されます。ハンバーガーメニューをクリックすると右側からメニューが展開されます。

HTMLの解説

ハンバーガーメニューはボタンタグで作成しています。三本線はspanタグで作成していきます。

<button class="c-hamburger">
  <span></span>
  <span></span>
  <span></span>
</button>

ナビメニューは以下のようにnavタグで作成していきます。

<nav class="p-header__nav p-nav">
  <div class="p-nav__inner">
   <ul class="p-nav__list">
      <li class="p-nav__item">
        <a href="" class="p-nav__link">
          メニュー
        </a>
      </li>
      <li class="p-nav__item">
        <a href="" class="p-nav__link">
          メニュー
        </a>
      </li>
      <li class="p-nav__item">
        <a href="" class="p-nav__link">
          メニュー
        </a>
      </li>
    </ul>
  </div>
</nav>

CSSの解説

ハンバーガーメニューの開閉前と開閉後はそれぞれ以下のように作成します。メニュー展開時は、後述するJavaScriptでis-activeクラスが付与されたときにスタイルを×になるように変更しています。

.c-hamburger {
  position: relative;
  width: inherit;
  height: inherit;
  margin: 0;
  border: transparent;
  background-color: transparent;
  cursor: pointer;
}


/* ハンバーガーメニューの三本線 */
.c-hamburger span {
  display: block;
  position: relative;
  left: 50%;
  width: 24px;
  height: 2px;
  transform: translateX(-50%);
  background: black;
  transition: all 0.4s;
}


.c-hamburger span:nth-of-type(1) {
  top: -4px;
}

.c-hamburger span:nth-of-type(2) {
  top: 1px;
  transform: translateX(-0.45deg);
}


.c-hamburger span:nth-of-type(3) {
  top: 6px;
  transform: translateX(-0.45deg);
}


/* メニュー展開時*/
.c-hamburger.is-active span:nth-of-type(1) {
  top: 0;
  transform: translateX(-50%) rotate(225deg);
}

.c-hamburger.is-active span:nth-of-type(2) {
  opacity: 0;
}

.c-hamburger.is-active span:nth-of-type(3) {
  top: -4px;
  transform: translateX(-50%) rotate(-225deg);
}

モバイル画面サイズではヘッダーメニューはハンバーガーメニューに格納し、配置は縦並び、初期表示はposition:absolute;とright:-100%;で画面外の右側に配置します。

/* SP時 */
.p-header__nav {
  z-index: 10;
 
  /* メニューを画面外右側に配置 */
  position: absolute;
  top: 0;
  right: -100%;

 /* メニューは上下左右中央寄せ */
  display: flex;
  align-items: center;
  justify-content: center;


  width: 100%;
  height: 100vh;
  background: transparent;
  opacity: 0;
  transition: top 0.6s, right 0.6s, opacity 0.6s;
}

ハンバーガーメニューがクリックされてis-activeクラスが付与されたら、画面外右側にあったメニューを画面内に表示させます。

.p-header__nav.is-active {
  position: fixed;
  top: 0;
  right: 0;
  opacity: 1;
  background-color: #fff;
}

PC画面サイズでは、ハンバーガーメニューは非表示。

またナビメニューに指定していたpositionプロパティを解除し、縦並びにしていたメニューを横並びにします。

@media screen and (min-width: 768px) {
  /* PC時 非表示 */
  .p-header__hamburger {
    display: none;
  }

  .p-header__nav {
  / positionプロパティを解除 /
    position: static;
    opacity: 1;
    height: inherit;
    width: initial;
  }
  .p-nav__list {
    padding-right: 0;
    padding-left: 0;

  / *メニューは横並びにする* /
    display: flex;
  
  }

}

モバイル画面時、PC画面時によって、CSSでハンバーガーメニュー表示・非表示を切り替え、ナビメニューも縦並びから横並びに配置していきます。

王道的なヘッダーパターン

JavaScriptの解説

コードは以下になります。

まず、以下のようにそれぞれ処理に必要な要素を取得していきます。

  // ハンバーガーメニューの要素を取得
  const hamburger = document.querySelector('.c-hamburger');
  // ヘッダーナビゲーションの要素を取得
  const headNav = document.querySelector('.p-header__nav');

ハンバーガーメニューをクリックしたときの処理を書いていきます。

ハンバーガーメニューにis-activeクラスがない場合とある場合とで処理をif文で出しわけます。

is-activeがある場合はis-activeを削除、is-activeがない場合はis-activeを付与します。

  // ハンバーガーメニューがクリックされた時の処理
  hamburger.addEventListener('click', () => {
    // ハンバーガーメニューにis-activeがある場合はis-activeを消す
    if (hamburger.classList.contains("is-active")) {
      hamburger.classList.remove('is-active');
      headNav.classList.remove('is-active')
    } else {
      // ハンバーガーメニューにis-activeがない場合がis-activeを付与する
      hamburger.classList.add('is-active');
      headNav.classList.add('is-active')
    }
  });

また、ヘッダーのナビゲーションをクリックしたときもハンバーガーメニューを閉じるように処理を記述します。

  // ヘッダーナビゲーションがクリックされた時の処理
  headNav.addEventListener('click', () => {
    // ハンバーガーメニューのアクティブ状態を解除する
    hamburger.classList.remove('is-active');
    headNav.classList.remove('is-active')
  });

JavaScriptで処理ができれば、ハンバーガーメニュークリック時に以下のように動作するようになります。

王道的なヘッダーパターン

ホームページの印象を変えるヘッダー、フッターは実装が少し難しいですがコピペでできればありがたいですね。

フッターの実装も3パターンテンプレでご紹介しているので合わせて読んでみてください。

あわせて読む

ミニマルなヘッダー(ヘッダーパターン2)

モバイルサイズもPCサイズもハンバーガーメニューが表示されているヘッダーになります。

コードは以下になります。

  <!-- ヘッダーパターン2 -->
  <header class="l-header p-header">
    <div class="p-header__inner">
      <h1 class="p-header__title">
        ロゴ
      </h1>
      <div class="p-header__hamburger">
        <button class="c-hamburger">
          <span></span>
          <span></span>
          <span></span>
        </button>
      </div>
      <nav class="p-header__nav p-nav">
        <div class="p-nav__inner">
          <ul class="p-nav__list">
            <li class="p-nav__item">
              <a href="" class="p-nav__link">
                メニュー
              </a>
            </li>
            <li class="p-nav__item">
              <a href="" class="p-nav__link">
                メニュー
              </a>
            </li>
            <li class="p-nav__item">
              <a href="" class="p-nav__link">
                メニュー
              </a>
            </li>
          </ul>
        </div>
      </nav>
    </div>
  </header>
body,
p,
ul,
li,
div,
h1 {
  margin: 0;
  padding: 0;
}

ul,
ol {
  list-style: none;
}


a {
  text-decoration: none;

}

main {
  background-color: orange;
  width: 100%;
  height: 1000px;
}

footer {
  width: 100%;
  height: 100px;
  background-color: rgb(249, 205, 121);
}



/* パターン2 */

.l-header {
  display: block;
  z-index: 999;
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  width: 100%;
  height: 72px;
  background: #fff;
}


.c-hamburger {
  position: relative;
  width: inherit;
  height: inherit;
  margin: 0;
  border: 1px solid skyblue;
  background: skyblue;
  cursor: pointer;
}



.c-hamburger span {
  display: block;
  position: relative;
  left: 50%;
  width: 24px;
  height: 2px;
  transform: translateX(-50%);
  background: #fff;
  transition: all 0.4s;
}

.c-hamburger span:nth-of-type(1) {
  top: -4px;
}

.c-hamburger span:nth-of-type(2) {
  top: 1px;

  transform: translateX(-0.45deg);
}

.c-hamburger span:nth-of-type(3) {
  top: 6px;
  transform: translateX(-0.45deg);
}



.c-hamburger.is-active span:nth-of-type(1) {
  top: 0;
  transform: translateX(-50%) rotate(225deg);
}

.c-hamburger.is-active span:nth-of-type(2) {
  opacity: 0;
}

.c-hamburger.is-active span:nth-of-type(3) {
  top: -4px;
  transform: translateX(-50%) rotate(-225deg);
}




.p-header__nav {
  display: flex;
  z-index: 10;
  position: absolute;
  top: 0;
  right: -100%;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100vh;
  background: transparent;
  opacity: 0;
  transition: top 0.6s, right 0.6s, opacity 0.6s;
}

.p-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: inherit;
  padding: 0 20px;
}



.p-header__hamburger {
  z-index: 100;
  position: absolute;
  top: 0;
  right: 0;
  width: 95px;
  height: 100%;
}

.p-header__nav.is-active {
  position: fixed;
  top: 0;
  right: 0;
  background: skyblue;
  opacity: 1;

}


.p-nav__list {
  display: block;
  padding-right: 20px;
  padding-left: 20px;

}

.p-nav__item {
  position: relative;
  width: 100%;

}

.p-nav__link {
  color: #fff;
  display: block;
  padding: 20px;
  width: 100%;
}


@media screen and (min-width: 768px) {
  .p-nav__inner {
    max-width: 1100px;
    margin-right: auto;
    margin-left: auto;
  }

  .p-nav__list {
    padding-right: 0;
    padding-left: 0;
  }


}
document.addEventListener('DOMContentLoaded', function () {
  const hamburger = document.querySelector('.c-hamburger');
  const headNav = document.querySelector('.p-header__nav');


  if (!hamburger) {
    return false;
  }

  hamburger.addEventListener('click', () => {
    if (hamburger.classList.contains("is-active")) {
      hamburger.classList.remove('is-active');
      headNav.classList.remove('is-active')
    } else {
      hamburger.classList.add('is-active');
      headNav.classList.add('is-active')
    }

  });

  headNav.addEventListener('click', () => {
    hamburger.classList.remove('is-active');
    headNav.classList.remove('is-active')
  });
});

See the Pen ミニマルなヘッダーパターン by 山中滉大 (@tips-web) on CodePen.

〇 PC画面サイズ

PC画面サイズミニマルなヘッダー

〇 モバイル画面サイズ

ミニマルなヘッダーパターン

ヘッダーパターン1と違って、PC時でもハンバーガーメニューが表示されるシンプルなヘッダーパターンとなります。

HTMLの解説

HTMLに関しては、ヘッダーパターン1と同様なので解説は割愛します。

CSSの解説

ほとんどはヘッダーパターン1と同様です。

ヘッダーパターン1と異なるのは、PC画面サイズのときもハンバーガーメニューが表示されている点です。

JavaScriptの解説

JavaScriptに関しては、ヘッダーパターン1と同様なので解説は割愛します。

見た目が異なるだけで処理はヘッダーパターン1と同様のイメージになります。

ミニマルなヘッダーパターン

プルダウンメニューがあるヘッダー(ヘッダーパターン3)

ヘッダーメニューの一部がプルダウンメニューになっているヘッダーになります。

コードは以下になります。

  <!-- ヘッダーパターン3 -->
  <header class="l-header p-header">
    <div class="p-header__inner">
      <h1 class="p-header__title">
        ロゴ
      </h1>
      <div class="p-header__hamburger">
        <button class="c-hamburger">
          <span></span>
          <span></span>
          <span></span>
        </button>
      </div>
      <nav class="p-header__nav p-nav">
        <div class="p-nav__inner">
          <ul class="p-nav__list">
            <li class="p-nav__item">
              <a href="" class="p-nav__link">
                メニュー
              </a>
            </li>
            <li class="p-nav__item">
              <a href="" class="p-nav__link">
                メニュー
              </a>
            </li>
            <li class="p-nav__item p-nav__item--acMenu">
              <p class="p-nav__link">
                メニュー
              </p>
              <ul class="p-nav__middle">
                <li class="p-nav__middleItem">
                  <a href="" class="p-nav__link p-nav__middleLink">メニュー</a>
                </li>
                <li class="p-nav__middleItem">
                  <a href="" class="p-nav__link p-nav__middleLink">メニュー</a>
                </li>
                <li class="p-nav__middleItem">
                  <a href="" class="p-nav__link p-nav__middleLink">メニュー</a>
                </li>
              </ul>
            </li>
          </ul>
        </div>
      </nav>
    </div>
  </header>

  <main>
    メインコンテンツ
  </main>
  <footer>フッター</footer>
body,
p,
ul,
li,
div,
h1 {
  margin: 0;
  padding: 0;
}

ul,
ol {
  list-style: none;
}


a {
  text-decoration: none;

}

main {
  background-color: orange;
  width: 100%;
  height: 1000px;
}

footer {
  width: 100%;
  height: 100px;
  background-color: rgb(249, 205, 121);
}
/* パターン3 */
.l-header {
  display: block;
  z-index: 999;
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  width: 100%;
  background: #fff;
}


.c-hamburger {
  position: relative;
  width: inherit;
  height: inherit;
  margin: 0;
  border: transparent;
  background-color: transparent;
  cursor: pointer;
}


.c-hamburger span {
  display: block;
  position: relative;
  left: 50%;
  width: 24px;
  height: 2px;
  transform: translateX(-50%);
  background: black;
  transition: all 0.4s;
}

.c-hamburger span:nth-of-type(1) {
  top: -4px;
}

.c-hamburger span:nth-of-type(2) {
  top: 1px;

  transform: translateX(-0.45deg);
}

.c-hamburger span:nth-of-type(3) {
  top: 6px;
  transform: translateX(-0.45deg);
}



.c-hamburger.is-active span:nth-of-type(1) {
  top: 0;
  transform: translateX(-50%) rotate(225deg);
}

.c-hamburger.is-active span:nth-of-type(2) {
  opacity: 0;
}

.c-hamburger.is-active span:nth-of-type(3) {
  top: -4px;
  transform: translateX(-50%) rotate(-225deg);
}




.p-header__nav {
  display: flex;
  z-index: 10;
  position: absolute;
  top: 0;
  right: -100%;

  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100vh;
  background: transparent;
  opacity: 0;
  transition: top 0.6s, right 0.6s, opacity 0.6s;
}

.p-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: inherit;
  padding: 0 20px;

}




.p-header__hamburger {
  z-index: 100;
  position: absolute;
  top: 0;
  right: 0;
  width: 95px;
  height: 100%;
}

.p-header__nav.is-active {
  position: fixed;
  top: 0;
  right: 0;
  opacity: 1;
  background-color: #fff;
}



.p-nav__list {
  display: block;
  padding-right: 20px;
  padding-left: 20px;


}

.p-nav__item {
  display: inline-block;
  position: relative;
  width: 100%;

}


.p-nav__link {
  color: black;
  display: block;
  padding: 20px;
  cursor: pointer;

}

.p-nav__item.p-nav__item--acMenu>.p-nav__link {
  position: relative;
}

.p-nav__item.p-nav__item--acMenu>.p-nav__link::after {
  position: absolute;
  content: "▼";
  right: 0;
  top: 50%;
  transform: translateY(-50%);

}


.p-nav__middle {
  display: none;
}

.p-nav__middleItem a::before {
  margin-right: 8px;
  margin-left: 8px;
  content: "-";
}


.p-nav__item.is-open .p-nav__middle {
  display: block;
}

@media screen and (min-width: 768px) {

  .p-header__hamburger {
    display: none;
  }

  .p-nav__inner {
    margin-right: auto;
    margin-left: auto;
    max-width: initial;
    width: 100%;

  }

  .p-header__nav {
    position: static;
    opacity: 1;
    height: inherit;
    width: initial;
    width: 100%;
    max-width: fit-content;
  }

  .p-nav__list {
    padding-right: 0;
    padding-left: 0;
    display: flex;
    flex-direction: row;

  }

  .p-nav__item ul {
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 130px;
    margin: 0;
    padding: 0;
  }



  .p-nav__item ul li {
    width: 100%;
    height: 0;
    overflow: hidden;
    transition: all 0.1s;
  }

  .p-nav__item ul li a {

    display: flex;
    align-items: center;
    padding: 13px 20px 13px 10px;
    color: #fff;
  }

  .p-nav__item:hover>ul>li {
    height: 48px;
    overflow: visible;
    background-color: rgb(242, 195, 107);
  }

  .p-nav__item:hover>ul>li:not(:first-child) {
    border-top: 1px solid #fff;
  }

  .p-nav__item:hover>ul>li.p-nav__middleItem:hover {
    background-color: #fff;
  }

  .p-nav__item:hover>ul>li.p-nav__middleItem:hover a {
    color: #2C2C2C;
  }

  .p-nav__middle {
    display: block;
    text-align: left;
  }

  .p-nav__middleItem {
    position: relative;
  }

  .p-nav__middleItem a {
    position: relative;
    white-space: nowrap;
  }

}
document.addEventListener('DOMContentLoaded', function () {
  const hamburger = document.querySelector('.c-hamburger');
  const headNav = document.querySelector('.p-header__nav');


  if (!hamburger) {
    return false;
  }

  hamburger.addEventListener('click', () => {
    if (hamburger.classList.contains("is-active")) {
      hamburger.classList.remove('is-active');
      headNav.classList.remove('is-active')
    } else {
      hamburger.classList.add('is-active');
      headNav.classList.add('is-active')
    }

  });

  headNav.addEventListener('click', () => {
    hamburger.classList.remove('is-active');
    headNav.classList.remove('is-active')
  });
});




document.addEventListener('DOMContentLoaded', function() {

  const acMenuItems = document.querySelectorAll('.p-nav__item--acMenu');

  acMenuItems.forEach(item => {

    item.addEventListener('click', function(event) {

      event.stopPropagation();

      item.classList.toggle('is-open');
    });
  });

  document.addEventListener('click', function(event) {

    acMenuItems.forEach(item => {

      if (!item.contains(event.target)) {
        item.classList.remove('is-open');
      }
    });
  });
});

See the Pen プルダウンメニューがあるヘッダーパターン by 山中滉大 (@tips-web) on CodePen.

〇 PC画面サイズ

PC画面サイズプルダウンメニューがあるヘッダーパターン

〇 モバイル画面サイズ

モバイル画面サイズプルダウンメニューがあるヘッダーパターン

プルダウンメニューをホバーもしくはクリックすると、プルダウンメニューが表示されます。

HTMLの解説

HTMLはほとんどヘッダーパターン1と同様ですが、プルダウンメニューの部分だけ構造が異なります。

<nav class="p-header__nav p-nav">
  <div class="p-nav__inner">
      <ul class="p-nav__list">
            <li class="p-nav__item">
              <a href="" class="p-nav__link">
                メニュー
              </a>
            </li>
            <li class="p-nav__item">
              <a href="" class="p-nav__link">
                メニュー
              </a>
            </li>
       <!-- プルダウンメニュー -->
               <li class="p-nav__item p-nav__item--acMenu">
              <p class="p-nav__link">
              メニュー
              </p>
              <ul class="p-nav__middle">
                <li class="p-nav__middleItem">
                  <a href="" class="p-nav__link p-nav__middleLink">メニュー</a>
                </li>
                <li class="p-nav__middleItem">
                  <a href="" class="p-nav__link p-nav__middleLink">メニュー</a>
                </li>
                <li class="p-nav__middleItem">
                  <a href="" class="p-nav__link p-nav__middleLink">メニュー</a>
                </li>
              </ul>
            </li>
       </ul>
   </div>
</nav>

CSSの解説

ヘッダーパターン1と同様の記述は割愛します。プルダウンメニュー部分だけ解説していきます。

プルダウンメニュー部分のCSSは以下になります。初期状態では非表示で、該当のメニューがクリックされたらis-openが付与されてプルダウンメニューが展開されるように記述します。

プルダウンメニューはulタグで作成しています。

構造的には、ulタグの中のliタグの中に、プルダウンメニュー用のulタグが格納されているイメージです。

.p-nav__item.p-nav__item--acMenu>.p-nav__link {
  position: relative;
}

.p-nav__item.p-nav__item--acMenu>.p-nav__link::after {
  position: absolute;
  content: "▼";
  right: 0;
  top: 50%;
  transform: translateY(-50%);

}


/* プルダウンメニュー 初期状態は非表示*/
.p-nav__middle {
  display: none;
}

.p-nav__middleItem a::before {
  margin-right: 8px;
  margin-left: 8px;
  content: "-";
}

.p-nav__item.is-open .p-nav__middle {
  display: block;
}

PC画面でのプルダウンメニューのCSSは以下になります。

プルダウンメニューはposition: absolute;で位置を調整しています。

@media screen and (min-width: 768px) {

  /* プルダウンメニューの位置指定 */
  .p-nav__item ul {
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 130px;
    margin: 0;
    padding: 0;
  }

  .p-nav__item ul li {
    width: 100%;
    height: 0;
    overflow: hidden;
    transition: all 0.1s;
  }

  .p-nav__item ul li a {
    display: flex;
    align-items: center;
    padding: 13px 20px 13px 10px;
    color: #fff;
  }
}
プルダウンメニューがあるヘッダーパターン

プルダウンメニューをホバーした場合のスタイルは以下になります。

@media screen and (min-width: 768px) {

  /* ホバー時 */
  .p-nav__item:hover>ul>li {
    height: 48px;
    overflow: visible;
    background-color: rgb(242, 195, 107);
  }

  .p-nav__item:hover>ul>li:not(:first-child) {
    border-top: 1px solid #fff;
  }

  .p-nav__item:hover>ul>li.p-nav__middleItem:hover {
    background-color: #fff;
  }

  .p-nav__item:hover>ul>li.p-nav__middleItem:hover a {
    color: #2C2C2C;
  }

}

JavaScriptの解説

ハンバーガーメニュークリック時の処理はヘッダーパターン1と同様なので割愛します。

プルダウンメニュー部分の処理は以下になります。
以下のコードで、p-nav__item--acMenuの要素を全て取得し、変数に格納します。

const acMenuItems = document.querySelectorAll('.p-nav__item--acMenu');

変数acMenuItemsに対して、要素ごとに処理を実行するのでforEach文を使用していきます。プルダウンメニュー(p-nav__item--acMenu)をクリックしたら、toggleメソッドを使ってis-openクラスをつけ外しできるようにします。

  acMenuItems.forEach(item => {
    // acMenuItemsの要素ごとに処理を実行する
    item.addEventListener('click', function(event) {
      
      event.stopPropagation();
      // イベントの伝播を停止する


      item.classList.toggle('is-open');
      // クリックされた要素に 'is-open' クラスを追加または削除
    });
  });

またプルダウンメニューを開いた後、プルダウンメニュー以外の部分をクリックした場合、is-openクラスを外す処理を記述します。

 document.addEventListener('click', function(event) {

    acMenuItems.forEach(item => {
      // acMenuItemsの要素ごとに処理を実行する

      if (!item.contains(event.target)) {
        // クリックされた要素がitem要素でない場合

        item.classList.remove('is-open');
        // item要素から 'is-open' クラスを削除する
      }
    });
  });

まとめ

よくあるヘッダーテンプレについて解説しました。

王道的なヘッダー、ミニマルなヘッダー、プルダウンメニューがあるヘッダーについて解説しましたが、その他にもさまざまなヘッダーデザインがあります。

ヘッダーは作成に時間がかかるものなので、あらかじめいくつかのテンプレートを用意しておくといいでしょう。

コーディングの効率化を行なって時給単価を上げる施策を見につけましょう!

Notionを活用することでコード保管ができ、過去におこなった実装を瞬時にコピペで再現することができます。

まだNotionを活用してコードストックを体験していない方はぜひこちらを参考にしてみてください。

Notionスニペット集サンプルのプレゼントもご用意しています♪

あわせて読む

  • この記事を書いた人
アバター画像

こうだい

兼業でWeb制作事業|31歳|本業畑違いで知識0から学習開始→1年目で初案件獲得→2年で月の兼業受注金額70万円達成|4年目で100万円達成|兼業でも稼げることを確信|Web制作メンター|制作費無料のホームページ制作事業運営|コーディング・ホームページ制作についてお気軽にお問い合わせください

-CSS
-, , ,