【CSSだけで作る】高性能ドロワーメニューの決定版(2021/5/8追記)

CSS
CSS HTML jQuery

CSSだけでクォリティの高いドロワーメニューの作り方!

前回の定番のスライダーのコードに続き、自分用の備忘録として。

サイト作ってると、これも毎回必要になってくる「ドロワーメニュー」(ハンバーガーメニューとかとも言われます)。

いろんなドロワーメニューが巷にあふれていて、これも玉石混交で、前にどのコード拝借したか忘れて前と違うところ参照したら全然使えなくて。
とか毎回やって工数かかって自分に嫌気がさしていましたが、以下のやつが一番しっくりきたのでもうこれを毎回使うことにしました。

ドロワーやモーダルをCSSだけで実現する方法
ドロワーやモーダルといった、いかにもクリックアクションをJavaScriptで操作している系の動きも実はCSS…

上記サイトから摘出した必要部分のコード

HTML

<input id="drawer-checkbox" type="checkbox">
<label id="drawer-icon" for="drawer-checkbox"><span></span></label>
<label id="drawer-close" for="drawer-checkbox"></label>
<div id="drawer-content">ここがドロワーとして出てくる部分です。</div>

CSS

#drawer-content {
  overflow: auto;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 40;
  width: 250px;
  max-width: 90%;
  height: 100%;
  background: #fff;
  transition: all 0.3s ease-in-out 0s;
  transform: translateX(-100%);
}
#drawer-checkbox:checked ~ #drawer-content {
  transform: translateX(0);
  box-shadow: 6px 0 24px rgba(0, 0, 0, 0.16);
}

#drawer-close {
  display: none;
  position: fixed;
  z-index: 39;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #000;
  opacity: 0;
  transition: all 0.3s ease-in-out 0s;
}
#drawer-checkbox:checked ~ #drawer-close {
  display: block;
  opacity: 0.3;
}

#drawer-checkbox {
  display: none;
}
#drawer-icon {
  cursor: pointer;
  display: inline-block;
  height: 50px;
  position: relative;
  width: 50px;
}

#drawer-icon span {
  background:  #333;
  border-radius: 4px;
  display: block;
  height: 16%;
  left: 50%;
  margin: -8% 0 0 -42%;
  position: absolute;
  top: 50%;
  transition: all 0.3s ease-in-out 0s;
  width: 84%;
}
#drawer-icon span::before,
#drawer-icon span::after {
  -webkit-transform: rotate(0);
  background: #333;
  border-radius: 4px;
  content: "";
  display: block;
  height: 100%;
  left: 50%;
  margin: -8% 0 0 -50%;
  position: absolute;
  top: 50%;
  transform: rotate(0);
  transition: all 0.3s ease-in-out;
  width: 100%;
}
#drawer-icon span::before {
  margin-top: -38%;
}
#drawer-icon span::after {
  margin-top: 19%;
}
#drawer-checkbox:checked ~ #drawer-icon span {
  background: rgba(51, 51, 51, 0);
}
#drawer-checkbox:checked ~ #drawer-icon span::before,
#drawer-checkbox:checked ~ #drawer-icon span::after {
  content: "";
  display: block;
  height: 100%;
  left: 50%;
  margin: -8% 0 0 -42%;
  position: absolute;
  top: 50%;
  width: 100%;
}
#drawer-checkbox:checked ~ #drawer-icon span::before {
  -webkit-transform: rotate(-45deg);
          transform: rotate(-45deg);
}
#drawer-checkbox:checked ~ #drawer-icon span::after {
  -webkit-transform: rotate(45deg);
          transform: rotate(45deg);
}

上記コードを設置した例

あとはこっから自分好みにカスタマイズ!

これがHTMLとCSSを調整したあとのドロワーメニューです。
僕の感覚ではスマホのハンバーガーボタンは右にあるほうがしっくりくるので、右から出るようにしました。
あと、なんですかね、こういうサンプル系のハンバーガーボタンって、線が太くてもっさりしてるの多いので、それもシャープに改善して、このサイトは年齢層的に、ボタンの下に”MENU”って表示もしてユーザビリティーをアップさせました。

カスタマイズで使用したコードも公開します。

HTML

<div class="drawer-wrap">
<input id="drawer-checkbox" type="checkbox">
<label id="drawer-icon" for="drawer-checkbox"><span></span></label>
<label id="drawer-close" for="drawer-checkbox"></label>
<span class="drawer-label">メニュー</span>
<div id="drawer-content">ここがドロワーとして出てくる部分です。</div>
</div>

CSS

.drawer-wrap{
    position: absolute;
    top: 0;
    right: 0;	
}
.drawer-label{
    position: fixed;
    top: 50px;
    right: 19px;
    font-size: 10px;
    z-index: 100;
}
#drawer-content {
	overflow: auto;
    position: fixed;
    top: 0;
    right: 0;
    padding: 30px;
    z-index: 40;
    width: 40vw;
    min-width: 40vw;
    height: 100%;
    background: #fff;
    transition: all 0.3s ease-in-out 0s;
  transform: translateX(100%);
}
#drawer-checkbox:checked ~ #drawer-content {
  transform: translateX(0);
  box-shadow: 6px 0 24px rgba(0, 0, 0, 0.16);
}

#drawer-close {
  display: none;
  position: fixed;
  z-index: 39;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #000;
  opacity: 0;
  transition: all 0.3s ease-in-out 0s;
}
#drawer-checkbox:checked ~ #drawer-close {
  display: block;
  opacity: 0.3;
}

#drawer-checkbox {
  display: none;
}
#drawer-icon {
	cursor: pointer;
	display: inline-block;
	height: 50px;
	position: fixed;
	width: 50px;
	right: 17px;
	top: 14px;
    z-index: 100;	
}

#drawer-icon span {
    background: #333;
    display: block;
    height: 1px;
    left: 50%;
    margin: -8% 0 0 -42%;
    position: absolute;
    top: 46%;
    transition: all 0.3s ease-in-out 0s;
    width: 84%;
}
#drawer-icon span::before,
#drawer-icon span::after {
  -webkit-transform: rotate(0);
    background: #333;
    content: "";
    display: block;
    height: 100%;
    left: 50%;
    margin: -8% 0 0 -50%;
    position: absolute;
    top: 50%;
    transform: rotate(0);
    transition: all 0.3s ease-in-out;
    width: 100%;
}
#drawer-icon span::before {
  margin-top: -13px;
}
#drawer-icon span::after {
  margin-top: 10px;
}
#drawer-checkbox:checked ~ #drawer-icon span {
  background: rgba(51, 51, 51, 0);
}
#drawer-checkbox:checked ~ #drawer-icon span::before,
#drawer-checkbox:checked ~ #drawer-icon span::after {
  content: "";
  display: block;
  height: 100%;
  left: 50%;
  margin: -8% 0 0 -42%;
  position: absolute;
  top: 50%;
  width: 100%;
}
#drawer-checkbox:checked ~ #drawer-icon span::before {
  -webkit-transform: rotate(-45deg);
          transform: rotate(-45deg);
}
#drawer-checkbox:checked ~ #drawer-icon span::after {
  -webkit-transform: rotate(45deg);
          transform: rotate(45deg);
}

追記:ページ内ジャンプした際に、ドロワーを閉じる方法と、スムーススクロールさせるjs!

上記で紹介したドロワーメニュー内のリンクがページ内リンクだった際に、以下の処理をjsで追加することで、ジャンプとともにドロワーを閉じさせることができる。

//ドロワーメニュー内のページ内リンクを押したらcssの:checkを外す
$(function() {
  $('#drawer-content a').click(function() {
    $('#drawer-checkbox').removeAttr('checked').prop('checked', false).change();
  });
});

続いて、スムーススクロールは以下を追記すればできる。

$(function(){
  $('a[href^="#"]').click(function(){
    let speed = 500;
    let href= $(this).attr("href");
    let target = $(href == "#" || href == "" ? 'html' : href);
    let position = target.offset().top;
    $("html, body").animate({scrollTop:position}, speed, "swing");
    return false;
  });
});  

さらに補足をすると、追従ヘッダーなどあった際に、スムーススクロースをすると、追従したヘッダーとリンク先が重なってしまうこともあるかと思うので、
その回避策も記載する。しかも追従ヘッダーの縦幅(高さ)がPCとスマホで違う!なんてこともあるので、それも以下の分岐でカバー!

$(window).on('load resize', function(){
  var winW = $(window).width();
  var devW = 480;
  if (winW <= devW) {
    //480px以下の時の処理(スマホ版でPCのときと追従ヘッダーの高さが違うとき)
	$(function(){
	  $('a[href^="#"]').click(function(){
	    let speed = 500;
	    let href= $(this).attr("href");
	    let target = $(href == "#" || href == "" ? 'html' : href);
	    let position = target.offset().top - 100;
	    $("html, body").animate({scrollTop:position}, speed, "swing");
	    return false;
	  });
	});      
  } else {
    //480pxより大きい時の処理(PC版でスマホのときと追従ヘッダーの高さが違うとき)
	$(function(){
	  $('a[href^="#"]').click(function(){
	    let speed = 500;
	    let href= $(this).attr("href");
	    let target = $(href == "#" || href == "" ? 'html' : href);
	    let position = target.offset().top - 150;
	    $("html, body").animate({scrollTop:position}, speed, "swing");
	    return false;
	  });
	});      
  }
});

動作は本サイトのTOPページで確認できます!

今回作業しながら聞いていた曲はこちらです♪

タイトルとURLをコピーしました