jQuery – サイドメニュー開閉タイプの作り方

jQueryを使ってサイドメニューの作り方について解説します。動作使用はボタンだけの開閉ではなく、ボタン外の箇所をクリックしてもサイドメニューが閉じる仕様となっています。サンプルコードの次に解説もあるので詳しくはそちらをご覧ください。

サンプルコード

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style>
		*{
			margin:0;
			padding:0;
		}
		.side_menu{
			position:fixed;
			width:300px;
			height:100%;
			top:0;
			left:0;
			bottom:0;
			background:#111;
			opacity:0;
			visibility:hidden;
			color:#fff;
			padding:30px 40px;
			transform: translateX(-400px);
  			transition: all 0.7s cubic-bezier(0.8, 0, 0.1, 1);
		}
		.side_menu.opensesame{
			opacity:1;
			visibility:visible;
			transform: translateX(0);
		}
		.side_menu_desc{
			margin:10px 0;
			color:#e8e8e8;
			font-size:15px;
		}
		ul.nav_links{
			margin-top:50px;
			list-style:none;
		}
		ul.nav_links li{
			padding:10px 0;
		}
		ul.nav_links li a{
			color:#a8a8a8;
			font-weight:bold;
			text-decoration:none;
		}
		.filter_box{
			position:fixed;
			top:0;
			right:0;
			width:calc(100% - 380px);
			height:100%;
			background:rgba(0, 0, 0, 0.3);
			transition:all 0.7s cubic-bezier(0.8, 0, 0.1, 1);
			opacity:0;
			visibility:hidden;
		}
		.filter_box.opensesame{
			opacity:1;
			visibility:visible;
		}
		.menu_btn{
			position:fixed;
			z-index:100;
			top:30px;
			right:30px;
			bottom:0;
			width:30px;
			height:30px;
			padding:7px;
			background:#111;
			cursor:pointer;
		}
		.menu_btn > span{
			position:relative;
			width:100%;
			height:1px;
			background:#fff;
			display:block;
			transform: rotate(0deg);
			transition: .25s ease-in-out;
		}
		.menu_btn > span:nth-child(1){
			top:6px;
		}
		.menu_btn > span:nth-child(2){
			top:15px;
		}
		.menu_btn > span:nth-child(3){
			top:24px;
		}
		.menu_btn.opensesame > span:nth-child(1){
			transform: rotate(45deg);
			top: 14px;
    		left: 0px;
		}
		.menu_btn.opensesame > span:nth-child(2){
			width: 0%;
  			opacity: 0;
		}
		.menu_btn.opensesame > span:nth-child(3){
			transform: rotate(-45deg);
			top: 12px;
    		left: 0px;
		}
	</style>
</head>
<body>
	<div class="side_menu">
		<h1>Site Title</h1>
		<p class="side_menu_desc">Web × UI Developer</p>
		<ul class="nav_links">
			<li><a href="">Home</a></li>
			<li><a href="">Blog</a></li>
			<li><a href="">About</a></li>
			<li><a href="">Privacy Policy</a></li>
			<li><a href="">Contact</a></li>
		</ul>
	</div>
	<div class="menu_btn">
		<span></span>
		<span></span>
		<span></span>
	</div>
	<div class="filter_box"></div>



<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
	$(".menu_btn").on("click", function(){
		if($('div').hasClass('opensesame')){
			$(".side_menu, .filter_box, .menu_btn").removeClass("opensesame");
		}else{
			$(".side_menu, .filter_box, .menu_btn").addClass("opensesame");
		}
	});
	$(".filter_box").on("click", function(){
		$(".filter_box, .side_menu, .menu_btn").removeClass("opensesame");
	});
</script>
</body>
</html>

解説

メニューボタンの作り方(jQueryを使用)

俗に言うハンバーガーメニューを実装していきます。

まずはじめに右上にボタンを配置しスクロールしても固定されるようなCSSが下記になります。

<style>
.menu_btn{
	position:fixed;
	z-index:100;
	top:30px;
	right:30px;
	bottom:0;
	width:30px;
	height:30px;
	padding:7px;
	background:#111;
	cursor:pointer;
}
</style>
<body>
	<div class="menu_btn">
		<span></span>
		<span></span>
		<span></span>
	</div>
</body>

次にバーガーメニューの横線3本を実装します。この3本の線は<span>タグを使用し:nth-child(x)で位置をズラして3本の線を作っています。

<style>
.menu_btn{
	position:fixed;
	z-index:100;
	top:30px;
	right:30px;
	bottom:0;
	width:30px;
	height:30px;
	padding:7px;
	background:#111;
	cursor:pointer;
}
.menu_btn > span:nth-child(1){
	top:6px;
}
.menu_btn > span:nth-child(2){
	top:15px;
}
.menu_btn > span:nth-child(3){
	top:24px;
}
</style>
<body>
	<div class="menu_btn">
		<span></span>
		<span></span>
		<span></span>
	</div>
</body>

最後に、jQueryを使って開閉ボタンを作成します。この仕様としては.menu_btnをクリックすると.opensesameクラスが.menu_btnに追加され、ボタンが開かれたときのCSSが展開されます。

つまり下記のコードの.menu_btn.opensesame > span:nth-child(x)などはボタンが開かれた状態のCSSになっています。

次に、jQueryなので<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script></body>の前に追加します。

下記の内容としては.menu_btnをクリックし、もし.opensesameがなければ指定したクラスに追加して、もし.opensesameがある状態であれば指定しているクラスから削除するようになっています。

<style>
.menu_btn{
	position:fixed;
	z-index:100;
	top:30px;
	right:30px;
	bottom:0;
	width:30px;
	height:30px;
	padding:7px;
	background:#111;
	cursor:pointer;
}
.menu_btn > span:nth-child(1){
	top:6px;
}
.menu_btn > span:nth-child(2){
	top:15px;
}
.menu_btn > span:nth-child(3){
	top:24px;
}
.menu_btn.opensesame > span:nth-child(1){
	transform: rotate(45deg);
	top: 14px;
	left: 0px;
}
.menu_btn.opensesame > span:nth-child(2){
	width: 0%;
	opacity: 0;
}
.menu_btn.opensesame > span:nth-child(3){
	transform: rotate(-45deg);
	top: 12px;
	left: 0px;
}
</style>
<body>
	<div class="menu_btn">
		<span></span>
		<span></span>
		<span></span>
	</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
	$(".menu_btn").on("click", function(){
		if($('div').hasClass('opensesame')){
			$(".menu_btn").removeClass("opensesame");
		}else{
			$(".menu_btn").addClass("opensesame");
		}
	});
</script>
</body>

サイドメニューの作り方

左に固定表示するサイドメニューになります。.opensesameが追加、削除されると開閉するようなアニメーションを入れています。

<style>
.menu_btn{
	position:fixed;
	z-index:100;
	top:30px;
	right:30px;
	bottom:0;
	width:30px;
	height:30px;
	padding:7px;
	background:#111;
	cursor:pointer;
}
.menu_btn > span:nth-child(1){
	top:6px;
}
.menu_btn > span:nth-child(2){
	top:15px;
}
.menu_btn > span:nth-child(3){
	top:24px;
}
.menu_btn.opensesame > span:nth-child(1){
	transform: rotate(45deg);
	top: 14px;
	left: 0px;
}
.menu_btn.opensesame > span:nth-child(2){
	width: 0%;
	opacity: 0;
}
.menu_btn.opensesame > span:nth-child(3){
	transform: rotate(-45deg);
	top: 12px;
	left: 0px;
}
.side_menu{
	position:fixed;
	width:300px;
	height:100%;
	top:0;
	left:0;
	bottom:0;
	background:#111;
	opacity:0;
	visibility:hidden;
	color:#fff;
	padding:30px 40px;
	transform: translateX(-400px);
	transition: all 0.7s cubic-bezier(0.8, 0, 0.1, 1);
}
.side_menu.opensesame{
	opacity:1;
	visibility:visible;
	transform: translateX(0);
}
.side_menu_desc{
	margin:10px 0;
	color:#e8e8e8;
	font-size:15px;
}
ul.nav_links{
	margin-top:50px;
	list-style:none;
}
ul.nav_links li{
	padding:10px 0;
}
ul.nav_links li a{
	color:#a8a8a8;
	font-weight:bold;
	text-decoration:none;
}
</style>
<body>
	<div class="menu_btn">
		<span></span>
		<span></span>
		<span></span>
	</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
	$(".menu_btn").on("click", function(){
		if($('div').hasClass('opensesame')){
			$(".side_menu, .menu_btn").removeClass("opensesame");
		}else{
			$(".side_menu, .menu_btn").addClass("opensesame");
		}
	});
</script>
</body>

ボタン外でも閉じる設定

ボタンで開閉するのが一般的ですが、閉じると言う手間を減らすためボタン外でも閉じる仕様にしたいと思います。

そこで用意するのが.filter_box要素でこれをクリックしてもボタンやメニューが閉じるようにします。それが下記のコードになります。

jQueryには.filter_boxをクリックしたら.opensesameを削除する仕様になっています。

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style>
		*{
			margin:0;
			padding:0;
		}
		.side_menu{
			position:fixed;
			width:300px;
			height:100%;
			top:0;
			left:0;
			bottom:0;
			background:#111;
			opacity:0;
			visibility:hidden;
			color:#fff;
			padding:30px 40px;
			transform: translateX(-400px);
  			transition: all 0.7s cubic-bezier(0.8, 0, 0.1, 1);
		}
		.side_menu.opensesame{
			opacity:1;
			visibility:visible;
			transform: translateX(0);
		}
		.side_menu_desc{
			margin:10px 0;
			color:#e8e8e8;
			font-size:15px;
		}
		ul.nav_links{
			margin-top:50px;
			list-style:none;
		}
		ul.nav_links li{
			padding:10px 0;
		}
		ul.nav_links li a{
			color:#a8a8a8;
			font-weight:bold;
			text-decoration:none;
		}
		.filter_box{
			position:fixed;
			top:0;
			right:0;
			width:calc(100% - 380px);
			height:100%;
			background:rgba(0, 0, 0, 0.3);
			transition:all 0.7s cubic-bezier(0.8, 0, 0.1, 1);
			opacity:0;
			visibility:hidden;
		}
		.filter_box.opensesame{
			opacity:1;
			visibility:visible;
		}
		.menu_btn{
			position:fixed;
			z-index:100;
			top:30px;
			right:30px;
			bottom:0;
			width:30px;
			height:30px;
			padding:7px;
			background:#111;
			cursor:pointer;
		}
		.menu_btn > span{
			position:relative;
			width:100%;
			height:1px;
			background:#fff;
			display:block;
			transform: rotate(0deg);
			transition: .25s ease-in-out;
		}
		.menu_btn > span:nth-child(1){
			top:6px;
		}
		.menu_btn > span:nth-child(2){
			top:15px;
		}
		.menu_btn > span:nth-child(3){
			top:24px;
		}
		.menu_btn.opensesame > span:nth-child(1){
			transform: rotate(45deg);
			top: 14px;
    		left: 0px;
		}
		.menu_btn.opensesame > span:nth-child(2){
			width: 0%;
  			opacity: 0;
		}
		.menu_btn.opensesame > span:nth-child(3){
			transform: rotate(-45deg);
			top: 12px;
    		left: 0px;
		}
	</style>
</head>
<body>
	<div class="side_menu">
		<h1>Site Title</h1>
		<p class="side_menu_desc">Web × UI Developer</p>
		<ul class="nav_links">
			<li><a href="">Home</a></li>
			<li><a href="">Blog</a></li>
			<li><a href="">About</a></li>
			<li><a href="">Privacy Policy</a></li>
			<li><a href="">Contact</a></li>
		</ul>
	</div>
	<div class="menu_btn">
		<span></span>
		<span></span>
		<span></span>
	</div>
	<div class="filter_box"></div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
	$(".menu_btn").on("click", function(){
		if($('div').hasClass('opensesame')){
			$(".side_menu, .filter_box, .menu_btn").removeClass("opensesame");
		}else{
			$(".side_menu, .filter_box, .menu_btn").addClass("opensesame");
		}
	});
	$(".filter_box").on("click", function(){
		$(".filter_box, .side_menu, .menu_btn").removeClass("opensesame");
	});
</script>
</body>
</html>