Learning site for website creation

S04:スマホ用ヘッダーを追加

  • 投稿日:2019年07月25日
  • 更新日:2020年02月05日

ハンバーガーメニュー付きスマホヘッダー

HTML

    <div class="sp-header sp">
      <input id="nav-input" type="checkbox">
      <div class="nav-box">
        <div class="logo-box">
          <a href="#"><img class="logo" src="img/logo_white.png" alt="ロゴ"></a>
        </div><!-- .logo-box -->
        <div class="nav-drawer">
          <label class="nav-icon" for="nav-input">
            <span></span>
            <span></span>
            <span></span>
          </label>
        </div><!-- .nav-drawer -->
      </div><!-- .nav-box -->
      <div class="nav-content">
        <ul class="menu">
          <li><a href="#">メニュー</a></li>
          <li><a href="#">メニュー</a></li>
          <li><a href="#">メニュー</a></li>
          <li><a href="#">メニュー</a></li>
        </ul>
      </div><!-- .nav-content -->
    </div><!-- .sp-header -->

CSS

/*---------------------------------
  スマホ用ヘッダー:ハンバーガーメニュー付き
---------------------------------*/
@media screen and (max-width:480px) {
  /* ヘッダー固定時の画面上部余白 */
  body {
    margin-top: 45px;
  }
  /* チェックボックス非表示 */
  .sp-header #nav-input {
    display: none;
  }
  /* 上部固定ヘッダー */
  .sp-header .nav-box {
    position: fixed;
    top: 0;
    z-index: 1000;
    display: flex;
    justify-content: space-between;
    background: #000;
    color: #fff;
    padding:10px;
    width: 100%;
    height: 45px;
  }
  /* ロゴ */
  .sp-header .logo-box {
    width: 50vw;
  }
  /* ハンバーガーアイコン:通常時 */
  .sp-header .nav-icon {
    position: relative;
    display: block;
    width: 30px;
    height: 30px;
    cursor: pointer;
  }
  .sp-header .nav-icon span {
    position: absolute;
    left: 0px;
    display: block;
    width: 100%;
    border-bottom: solid 3px #555;
    transition: 0.5s ease-in-out;
  }
  .sp-header .nav-icon span:nth-child(1) {
    top: 2px;
  }
  .sp-header .nav-icon span:nth-child(2) {
    top: 10px;
  }
  .sp-header .nav-icon span:nth-child(3) {
    top: 18px;
  }
  /* ハンバーガーアイコン:クリック時 */
  .sp-header #nav-input:checked ~ .nav-box .nav-icon span:nth-child(1) {
    top: 10px;
    left: 0px;
    transform: rotate(-45deg);
  }
  .sp-header #nav-input:checked ~ .nav-box .nav-icon span:nth-child(2),
  .sp-header #nav-input:checked ~ .nav-box .nav-icon span:nth-child(3) {
    top: 10px;
    transform: rotate(45deg);
  }
  /* ナビゲーションエリア */
  .sp-header .nav-content {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 100;
    width: 100vw;
    height: 100vh;
    background: rgba(39, 72, 6, 0.9);
    color: #fff;
    transition: 0.5s;
    transform: translateY(-100%);
  }
  /* ナビゲーションエリア:ハンバーガーアイコンクリック時 */
  .sp-header #nav-input:checked ~ .nav-content {
    transform: translateY(0%);
    top: 45px;
  }
  /* ナビゲーションリスト */
  .sp-header .nav-content .menu {
    list-style-type: none;
    padding: 0 10px;
  }
  .sp-header .nav-content a {
    display: block;
    background-color: rgba(255, 255, 255, 0.5);
    border-radius: 25px;
    color: #fff;
    font-size: 4vw;
    padding: 10px;
    margin: 10px 0;
  }
}

解説

パーツの重なり順

HTML

<!-- ▼▼▼ スマホ用ヘッダー ▼▼▼ -->
<div class="sp-header">
  <input id="nav-input" type="checkbox">

  <div class="nav-box">
    <div class="logo-box">
      <a href="#"><img class="logo" src="img/logo_white.png" alt="ロゴ"></a>
    </div><!-- .logo-box -->
    <div class="nav-drawer">
      <label class="nav-icon" for="nav-input">
        <span></span>
        <span></span>
        <span></span>
      </label>
    </div><!-- .nav-drawer -->
  </div><!-- .nav-box -->

  <div class="nav-content">
    <ul class="menu">
      <li><a href="#">メニュー</a></li>
      <li><a href="#">メニュー</a></li>
      <li><a href="#">メニュー</a></li>
      <li><a href="#">メニュー</a></li>
    </ul>
  </div><!-- .nav-content -->

</div><!-- .sp-header -->
<!-- ▲▲▲ スマホ用ヘッダー ▲▲▲ -->

CSS

  /* 上部固定ヘッダー */
  .sp-header .nav-box {
           :
    z-index: 1000;
           :
  }

  /* ナビゲーションエリア */
  .sp-header .nav-content {
           :
    z-index: 100;
           :
  }

ハンバーガーの表示

基準枠

  .sp-header .nav-icon {
    position: relative;
    display: block;
    width: 30px;
    height: 30px;
    cursor: pointer;
  }

ハンバーガーの棒を絶対配置

  .sp-header .nav-icon span {
    position: absolute;
    left: 0px;
    display: block;
    width: 100%;
    border-bottom: solid 3px #555;
    transition: 0.5s ease-in-out;
  }
  .sp-header .nav-icon span:nth-child(1) {
    top: 2px;
  }
  .sp-header .nav-icon span:nth-child(2) {
    top: 10px;
  }
  .sp-header .nav-icon span:nth-child(3) {
    top: 18px;
  }

ハンバーガークリック時の「×」表示

「45度」「-45度」回転させて「×」表示

  .sp-header #nav-input:checked ~ .nav-box .nav-icon span:nth-child(1) {
    top: 10px;
    left: 0px;
    transform: rotate(-45deg);
  }
  .sp-header #nav-input:checked ~ .nav-box .nav-icon span:nth-child(2),
  .sp-header #nav-input:checked ~ .nav-box .nav-icon span:nth-child(3) {
    top: 10px;
    transform: rotate(45deg);
  }

メニューが表示される仕組み

メニュー非表示時

  /* ナビゲーションエリア */
  .sp-header .nav-content {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 100;
    width: 100vw;
    height: 100vh;
    background: rgba(55, 0, 0, 0.9);
    color: #fff;
    transition: 0.5s;
    transform: translateY(-100%);
  }

メニュー表示時

  /* ナビゲーションエリア:ハンバーガーアイコンクリック時 */
  .sp-header #nav-input:checked ~ .nav-content {
    transform: translateY(0%);
    top: 45px;
  }

兄弟セレクタ

.sp-header #nav-input:checked ~ .nav-content

CSSセレクタ「~」は「兄弟要素」を指定するセレクタです。

指定した要素より後にでてくる同じ階層の要素が対象になります。

CSSセレクタチートシート:Weblikerさん

<div class="sp-header">
  <input id="nav-input" type="checkbox">
  <div class="nav-box">
           :
  </div><!-- .nav-box -->
  <div class="nav-content">
           :
  </div><!-- .nav-content -->
</div><!-- .sp-header -->