Learning site for website creation

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

  • 投稿日:2019年07月25日

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

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

/*---------------------------------
  スマホ用ヘッダー:ハンバーガーメニュー付き
---------------------------------*/
@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(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-content .menu {
    list-style-type: none;
    padding: 0 10px;
  }
  .sp-header .nav-content li {
    border-top: dotted 1px;
  }
  .sp-header .nav-content li:last-child {
    border-bottom: dotted 1px;
  }
  .sp-header .nav-content a {
    display: block;
    color: #fff;
    font-size: 4vw;
  }
}

解説

パーツの重なり順

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 -->