🕌

ハンバーガーメニュー実装時に理解できなかった2つのこと

2024/04/26に公開

ヘッダーにハンバーガーメニューを実装しようとした時のお話です。
悩んだことが2つありました。
1、ナビの右側に謎の余白が生まれて意図したレイアウトにならなかった。
2、3本線をエックスマークに可変させる動きがよくわからなかった。
それぞれ解決&理解できたので、忘備録として綴ります。

1、ナビの右側に謎の余白が生まれて意図したレイアウトにならない。

子要素のヘッダーロゴとナビが両端に配置されるはずだったのですが、
なぜかナビが中央寄りになっていました。

修正前のレイアウト

example.css
.p-header {
	max-width: 1280px;
	display: flex;
	justify-content: space-between;  // ロゴとナビを両端に寄せる
	align-items: center;
	height: 60px;
}
index.html
  <header class="l-header">
    <div class="p-header">
      <div class="p-header__logo">Designer's blog</div>
      <nav class="p-header__nav">
        <ul class="p-header__nav-lists">
          <li class="p-header__nav-item">Home</li>
          <li class="p-header__nav-item">About</li>
          <li class="p-header__nav-item">Blog</li>
        </ul>
      </nav>
      <div class="p-header__hamburger">
        <span class="p-header__hamburger-line"></span>
        <span class="p-header__hamburger-line"></span>
        <span class="p-header__hamburger-line"></span>
      </div>
    </div>
  </header>

これで解決

PCで使わない要素をdisplay: none;で消しておかないとレイアウトの邪魔になります。
なので下記を追記。

style.css
.p-header__hamburger {
  display: none;
}

解決しました🎵

3本線をエックスマークに可変させる動きがよくわからなかった

可変させる仕組み

結論から言うと、こんな流れです。

  1. 上下の線をそれぞれ中央に移動。親要素の高さに対して50%移動。
top: 50%; 
  1. 上下の線がそれぞれ回転。要素の真ん中が軸になります。
transform: rotate(45deg);
transform: rotate(-45deg); 
  1. 真ん中の線は消す
opacity: 0;

分解してみると理解できそうですね!

図にするとこんな感じでしょうか

ソースコード

example.css
/* PC */
.p-header__nav {
  display: block;
}

.p-header__nav-lists {
  display: flex;
  gap: 40px;
}

.p-header__hamburger {  /* PCでは表示不要のため */
  display: none; 
}

/* SP */
@media screen and (max-width:375px) {  
/* ------------
   ハンバーガーの本体
   ------------ */
  .p-header__hamburger {  
    display: block;     /* SPでは表示するため */
    position: relative;  /* 親要素にrelative指定 */
    width: 28px;
    height: 22px;
  }
/* ---------------
   3本線
   --------------- */
  .p-header__hamburger-line { 
    position: absolute; /* 子要素にabsolute指定 */
    width: 28px;
    height: 2px;
    border-radius: 1px;
    background-color: #fff;
  }

/* ---------------
   3本線の位置をそれぞれ調整
   --------------- */
  .p-header__hamburger-line:nth-child(1) {
    top: 0;
  }

  .p-header__hamburger-line:nth-child(2) {
    top: 8px;
  }

  .p-header__hamburger-line:nth-child(3) {
    top: 16px;
  }
}

/* ---------------
   エックスマークを動的に生成
   --------------- */
.p-header__hamburger-line.cross:nth-child(1) {
  transform: rotate(45deg); 
  top: 50%;
  transition: .3s;  /* 秒数 */
}

.p-header__hamburger-line.cross:nth-child(2) {
  opacity: 0; /* 非表示ではなく透明になる */
}

.p-header__hamburger-line.cross:nth-child(3) {
  transform: rotate(-45deg);
  top: 50%;
  transition: .3s;
}

誰かの参考になれば嬉しいです!

Discussion