見出し1
  • メニューメニュー
  • メニュー
  • メニュー
  • メニュー
見出し2
  • メニュー
  • メニュー
  • メニュー
  • メニュー
見出し3
  • メニュー
  • メニュー
  • メニュー
  • メニュー
見出し4
  • メニュー
  • メニュー
  • メニュー
  • メニュー

画面全体に表示するメニューを作る(HTML/CSS/JS)

前書き

画面全体に表示するメニューの作り方を掲載しています。

目次

  1. 見本
  2. 参考

見本

当ページに実装しています。
ページの右上にあるボタンをクリックして下さい。

仕様

  1. はみ出た分はスクロールして見れる
  2. 後ろのコンテンツはスクロールしない
  3. 表示前後で、見た目上の位置は変わらない
  4. 表示する時にガタつかない

工夫したこと

  1. bodyのY軸にスクロールバーを常に出す
  2. 全画面メニューのY軸にスクロールバーを出す
  3. 全画面メニューのの横幅を100vwにして、bodyのスクロールバーの下に入れ込む

<!-- 全画面表示のメニュー -->
<div class="fs" data-fsaction>
  <div class="fs-inner">
    <!-- 中略 -->
  </div>
</div>
<!-- メニュー表示ボタン -->
<div class="mn" data-menubtn>
  <div class="mn-bar" data-fsaction></div>
  <div class="mn-bar" data-fsaction></div>
  <div class="mn-bar" data-fsaction></div>
  <p class="mn-text" data-fsaction></p>
</div>

body{
  overflow-y: scroll;
  &.fs-active{ //全画面メニュー表示時は、bodyにfixedを指定する
    position: fixed; top: 0; left: 0; width: 100%; height: 100%;
  }
}

//全画面 fixedにする
.fs{
  //配置、装飾
  position: fixed; top: 0; left: 0; width: 100%; height: 100%;
  color: #fff; background: rgba(#000,0.9);
  min-width: 100vw; overflow-y: scroll; //bodyのスクロールバーの下に入れ込む
  //動き
  opacity: 0; z-index: -1; transition: 0.2s;
  &.fs-active{
    opacity: 1; z-index:1001;
  }
}
.fs-inner{
  @media screen and (min-width: 768px) {
    display: flex; align-items: center; min-height: 100%; //上下中央に寄せる 
  }
}

//メニューボタン 画面右上に固定
.mn{
  position: fixed; top: 0; right: 0; z-index: 1002;
  width: 60px; height: 60px; color: #fff; background: #845080; cursor: pointer;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  @media screen and (min-width: 768px) {
    width: 80px; height: 80px;
  }
}
.mn-bar{
  width: 30px; height: 1px; background: #fff; margin: 6px 0 0; transition: .2s;
  &:nth-child(1){ margin-top: 0; }
  &:nth-child(1).fs-active{ transform: translateY(7px) rotate(-45deg); }
  &:nth-child(2).fs-active{ opacity: 0; }
  &:nth-child(3).fs-active{ transform: translateY(-7px) rotate(45deg); }
}
.mn-text{
  letter-spacing: 0; line-height: 1; text-align: center; margin: 10px 0 0;
  &::before{ content: "MENU"; }
  &.fs-active::before{ content: "CLOSE"; }
}

const body = document.querySelector('body');
const menuBtn = document.querySelectorAll('[data-menubtn]'); //メニューボタン
const fsAction = document.querySelectorAll('[data-fsaction]'); //全画面メニュー表示時にクラスを追加
let fsIsActive = false;
let windowTop = 0;

//表示
const menuOpen = () => {
  fsAction.forEach((item) => {
    item.classList.add("fs-active");
  });
  //bodyの位置をずらすことで、見た目上は、コンテンツの位置を変えない
  windowTop = window.scrollY;
  body.style.top = - windowTop + "px";
  body.classList.add("fs-active");
  fsIsActive = true;
}

//非表示
const menuClose = (id) => {
  fsAction.forEach((item) => {
    item.classList.remove("fs-active");
  });
  //fixedを解除して、元の位置に戻す。
  body.classList.remove("fs-active");
  body.style.top = "";
  window.scrollTo({
    top: windowTop,
  });
  fsIsActive = false;
}

//メニューボタン クリック
menuBtn.forEach((item) => {
  item.addEventListener('click', () => {
    if( fsIsActive ){
      menuClose();
    }else{
      menuOpen();
    }
  });
});

参考

レスポンシブデザインでスマホだけアコーディオン

jquery ハンバーガーメニューを作ってみよう(基本〜応用の入り口まで)

関連記事

大きさの異なる要素を隙間なく配置する(HTML/CSS)

フォトギャラリーを作る(HTML/CSS/JS)

開閉するボックスを作る(HTML/CSS/JS)

CSSを使って自動で番号を振る

WEBページの部品作り

先頭に戻る
ページの先頭に戻る