画面全体に表示するメニューを作る(HTML/CSS/JS)
前書き
画面全体に表示するメニューの作り方を掲載しています。
目次
- 見本
- HTML
- CSS
- jQuery
- 参考
見本
当ページに実装しています。ページの右上にあるボタンをクリックして下さい。
仕様
- はみ出た分はスクロールして見れる
- 後ろのコンテンツはスクロールしない
- 表示前後で、見た目上の位置は変わらない
- 表示する時にガタつかない
HTML
<!-- 全画面表示のメニュー -->
<div class="fs hidden" data-fs-wrap>
<div class="fs-wrap">
<div class="fs-inner">
<!-- fs-block 一つ目 -->
<div class="fs-block">
<div class="fs-parent" data-fs-parent>見出し1</div>
<ul class="fs-child-ul" data-fs-child>
<li class="fs-child-li">メニューメニュー</li>
<li class="fs-child-li">メニュー</li>
<li class="fs-child-li">メニュー</li>
<li class="fs-child-li">メニュー</li>
</ul>
</div>
<!-- fs-block 二つ目 -->
<!-- 中略 -->
</div>
</div>
</div>
<!-- メニュー表示ボタン -->
<div class="mn" data-mn-wrap>
<div class="mn-in">
<div class="mn-bar mn-bar01"></div>
<div class="mn-bar mn-bar02"></div>
<div class="mn-bar mn-bar03"></div>
</div>
<p class="mn-text"></p>
</div>
CSS
工夫したこと
- bodyのY軸にスクロールバーを出す
- .fsのY軸にスクロールバーを出す
- .fsの横幅を100vwにして、bodyのスクロールバーの下に入れ込む
全画面表示に関連するSCSS
html{
// 当サイト用の設定
// height: 100%;
// @media screen and (min-width: 768px) {
// min-width: 〇〇
// }
}
body{
overflow-y: scroll;
//メニューが表示している時は、bodyにfixedを指定する。
&.js-fixed{
position: fixed; width: 100%; height: 100%;
}
}
.hidden{
//非表示1
display: none;
}
.fs{
//fixedにする
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
//スクロールバーを、bodyのスクロールバーの下に入れ込む
overflow-y: scroll; min-width: 100vw;
//色
color: #fff; background: rgba(#000,0.9);
//非表示2
opacity: 0; z-index: -10; transition: 0.2s;
//表示
&.active{
opacity: 1; z-index:1001;
}
}
.fs-wrap{
@media screen and (min-width: 768px) {
//上下左右中央に寄せる
display: flex; align-items: center; min-height: 100%;
}
}
リストに関連するSCSS
.fs-inner{
padding: 70px 20px 20px;
@media screen and (min-width: 768px) {
display: flex; flex-wrap: wrap; justify-content: center; width: 100%; padding: 20px 20px;
}
}
.fs-block{
margin: 20px 0 0;
&:nth-of-type(1){
margin-top: 0;
}
@media screen and (min-width: 768px) {
width: 50%; max-width: 400px; padding: 20px 20px; margin: 0;
}
}
.fs-parent{
position: relative; padding: 0 2em 0 0; cursor: pointer;
&::after{
content: "+"; position: absolute; top: 0; right: 0;
}
&.active{
&::after{
content: "-";
}
}
@media screen and (min-width: 768px) {
cursor: auto;
&::after{
display: none;
}
}
}
.fs-child-ul{
display: none;
@media screen and (min-width: 768px) {
display: block;
}
}
.fs-child-li{
padding: 0.5em 0;
&:nth-of-type(1){
border-top: 1px solid #aaa; margin: 10px 0 0;
}
}
ボタンに関連するSCSS
.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-in{
width: 30px;
}
.mn-bar{
height: 1px; background: #fff; margin: 6px 0 0; transition: .2s;
&:nth-of-type(1){
margin-top: 0;
}
}
.mn-text{
font-size: 10px; line-height: 1; text-align: center; margin: 10px 0 0;
&::before{
content: "MENU";
}
}
// アクティブ
.mn.active{
.mn-bar01{
transform: translateY(7px) rotate(-45deg);
}
.mn-bar02{
opacity: 0;
}
.mn-bar03{
transform: translateY(-7px) rotate(45deg);
}
.mn-text{
&::before{
content: "CLOSE";
}
}
}
jQuery
工夫したこと
- bodyの位置をずらすことで、見た目上は、コンテンツの位置を変えない
const btn = $('[data-mn-wrap]');
const fullscreen = $('[data-fs-wrap]');
let isActive = false;
let wTop = 0;
let wLeft = 0;
//初め
fullscreen.removeClass("hidden");
//メニューボタン クリック
btn.on("click",function(){
if( isActive ){
menuClose();
}else{
menuOpen();
}
});
//全画面表示
function menuOpen(){
btn.addClass("active");
fullscreen.addClass("active");
//bodyの位置をずらすことで、見た目上は、コンテンツの位置を変えない
wTop = $(window).scrollTop();
wLeft = $(window).scrollLeft();
$("body").css({'top': -(wTop), 'left' : -(wLeft)}).addClass("js-fixed");
isActive = true;
}
//非表示
function menuClose(){
btn.removeClass("active");
fullscreen.removeClass("active");
//fixedを解除して、元の位置に戻す。
$("body").removeClass("js-fixed").css({'top': '', 'left' : ''});
$("html, body").animate({scrollTop: wTop},0);
isActive = false;
}
// スマホの時だけサブメニューを開閉させる
$("[data-fs-parent]").on("click",function(){
const ww = window.innerWidth;
const parent = $(this);
const child = $(this).next();
if(ww < 768){
if( parent.hasClass("active")){
parent.removeClass("active");
child.slideUp(200,function(){
//スライドアップしたら、style属性のdisplay:noneを消す
child.css({'display':''});
});
}else{
parent.addClass("active");
child.slideDown(200);
}
}
});
参考
jquery ハンバーガーメニューを作ってみよう(基本〜応用の入り口まで)