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

CSS
CSS HTML jQuery

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

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

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

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

ドロワーやモーダルをCSSだけで実現する方法 | HPcode(えいちぴーこーど)
ドロワーやモーダルといった、いかにもクリックアクションをJavaScriptで操作している系の動きも実はCSSだけで実現できたりします。 仕組みの大枠としては、以下の3つを組み合わせる感じです。 チェックボックにあるチェックされた時のスタイ

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

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ページで確認できます!

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

Webサイト制作を依頼したい方へ

PRYTHM WORKS(プリズムワークス)は、東京都墨田区、東京スカイツリーのふもとにあるWebコンテンツ制作事務所です。

華々しいおしゃれなECサイトをはじめ、アンダーグラウンドな案件まで幅広くご依頼をいただき、どんな案件でも真心・丁寧・楽しくを理念に掲げて制作しております!

作りたいサービスはあるけど、まずは費用感が知りたい!という方も、まずはお問い合わせください!

mail@prytymworks.tokyo

PRYTHM WORKSが手掛ける仕事の一部をご紹介します。

制作のご依頼者様用 費用かんたんお見積もりフォーム

おそらく本記事を読まれるのは、制作の現場の、法人またはフリーの、プロデューサーの方、ディレクターの方、エンジニアの方がほとんどかと存じます。
いつもおつかれさまです!そして本記事をお読みいただきありがとうございます。
紹介した記事の内容について、またはその他制作のご依頼について、以下のフォームより簡易お見積もりができます!
試算だけならフォーム送信しなくてもできますので、ぜひ試しにいかがでしょう?

お仕事をご希望の制作者様用 お問合せフォーム

また、まずはライトなご相談から…ということであれば、こちらのコンタクトフォームからお気軽にどうぞ!ご縁を大切にしてご返信いたします!

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