ESCキーで閉じられるドロワーメニューの作り方
ESCキーで閉じられるドロワーメニューの作り方を紹介します。ドロワーメニューは、ボタンをクリックしてメニューを表示し、画面を広く使いながらナビゲーションを提供できる定番UIです。本記事では、HTML・CSS・JavaScriptだけを使い、開閉ボタンによる操作に加えて、キーボードのESCキーを押すことでドロワーメニューを閉じられる基本的な実装方法を紹介します。
サンプルコードでは、「メニューを開く」ボタンをクリックするとドロワーメニューが表示され、「閉じる」ボタンまたはESCキーでメニューを閉じられます。ESCキーによる操作を追加することで、キーボード操作にも対応しやすくなり、シンプルな構成のまま扱いやすいドロワーメニューを実装できます。
管理画面や会員サイト、企業サイト、ECサイトなど、メニューを画面の横から表示したい場面で利用できます。メニュー項目やボタンの文字はHTMLで変更でき、色・幅・余白・アニメーションなどはCSSで調整できます。また、JavaScriptを編集すれば開閉処理も自由にカスタマイズできるため、自分のWebサイトに合わせたドロワーメニューへ発展させる際のベースとしても活用できます。
コードについて
本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。
免責事項
本コードの利用により発生した損害について、当サイトは一切の責任を負いません。
デモ
「メニューを開く」をクリックするとドロワーメニューが表示されます。ESCキーまたは「閉じる」ボタンで閉じる動作を確認できます。
コードをコピーして使おう!
html
css
js
このタブをコピー
サンプル一式をダウンロード
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- 文字コード -->
<meta charset="UTF-8">
<!-- スマートフォン表示対応 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ページタイトル -->
<title>ESCキーで閉じられるドロワーメニュー</title>
<!-- CSSファイルを読み込み -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- デモ全体 -->
<div class="drawer-menu-close-esc_wrap">
<!-- タイトル -->
<h1 class="drawer-menu-close-esc_title">
ESCキーで閉じられるドロワーメニュー
</h1>
<!-- 説明文 -->
<p class="drawer-menu-close-esc_text">
「メニューを開く」をクリックすると、画面左側からドロワーメニューが表示されます。
</p>
<!-- ドロワーメニューを開くボタン -->
<button
class="drawer-menu-close-esc_open"
type="button"
data-drawer-open>
メニューを開く
</button>
</div>
<!-- ドロワーメニュー表示時の背景 -->
<div
class="drawer-menu-close-esc_overlay"
data-drawer-overlay>
</div>
<!-- ドロワーメニュー本体 -->
<aside
class="drawer-menu-close-esc_panel"
data-drawer-panel
aria-hidden="true">
<!-- メニュータイトル -->
<div class="drawer-menu-close-esc_heading">
メニュー
</div>
<!-- メニュー項目 -->
<ul class="drawer-menu-close-esc_list">
<li><a href="#">ホーム</a></li>
<li><a href="#">サービス</a></li>
<li><a href="#">お問い合わせ</a></li>
</ul>
<!-- ドロワーメニューを閉じるボタン -->
<button
class="drawer-menu-close-esc_close"
type="button"
data-drawer-close>
閉じる
</button>
</aside>
<!-- JavaScriptファイルを読み込み -->
<script src="script.js"></script>
</body>
</html>
/* ページ全体 */
body{
margin:0; /* 外側の余白 */
padding:40px 20px; /* 内側の余白 */
background:#ffffff; /* 背景色 */
font-family:sans-serif; /* フォント */
}
/* デモ全体 */
.drawer-menu-close-esc_wrap{
max-width:720px; /* 最大横幅:変更するとデモ全体の幅が変わる */
margin:40px auto; /* 上下余白・中央配置 */
padding:32px; /* 内側余白 */
border:1px solid #e5e7eb; /* 枠線 */
border-radius:18px; /* 角丸 */
background:#f8fafc; /* 背景色 */
text-align:center; /* 中央揃え */
box-sizing:border-box; /* paddingを幅に含める */
}
/* タイトル */
.drawer-menu-close-esc_title{
margin:0 0 12px; /* 下余白 */
font-size:22px; /* 文字サイズ */
font-weight:700; /* 太字 */
}
/* 説明文 */
.drawer-menu-close-esc_text{
margin:0 0 24px; /* 下余白 */
color:#4b5563; /* 文字色 */
line-height:1.8; /* 行間:値を大きくすると行間が広がる */
}
/* メニューを開くボタン */
.drawer-menu-close-esc_open{
padding:12px 24px; /* 内側余白 */
border:none; /* 枠線なし */
border-radius:8px; /* 角丸 */
background:#2563eb; /* 背景色 */
color:#ffffff; /* 文字色 */
font-size:16px; /* 文字サイズ */
font-weight:700; /* 太字 */
cursor:pointer; /* マウスカーソル */
}
/* ドロワーメニュー表示時の背景 */
.drawer-menu-close-esc_overlay{
position:fixed; /* 画面全体へ固定 */
inset:0; /* 全画面表示 */
z-index:9998; /* ドロワーメニューより背面へ配置 */
visibility:hidden; /* 初期状態は非表示 */
opacity:0; /* 初期状態は透明 */
background:rgba(15,23,42,.45); /* 背景の暗さ:.45を大きくすると濃くなる */
transition:opacity .3s,visibility .3s; /* 0.3秒で背景を表示・非表示 */
}
/* 背景表示時 */
.drawer-menu-close-esc_overlay.is-active{
visibility:visible; /* 背景を表示 */
opacity:1; /* 背景を不透明にする */
}
/* ドロワーメニュー本体 */
.drawer-menu-close-esc_panel{
position:fixed; /* 画面左側へ固定 */
top:0; /* 画面上端へ配置 */
left:0; /* 画面左端へ配置 */
z-index:9999; /* 背景より前面へ配置 */
width:280px; /* 横幅:変更するとメニューの幅が変わる */
max-width:85%; /* 小さい画面で画面幅を超えないようにする */
height:100%; /* 画面の高さに合わせる */
padding:24px; /* 内側余白 */
background:#ffffff; /* 背景色 */
box-shadow:4px 0 20px rgba(0,0,0,.15); /* 右側の影 */
box-sizing:border-box; /* paddingを幅に含める */
transform:translateX(-100%); /* 初期状態は画面左側へ隠す */
transition:transform .3s; /* 0.3秒で開閉する。値を大きくするとゆっくり動く */
}
/* ドロワーメニュー表示時 */
.drawer-menu-close-esc_panel.is-active{
transform:translateX(0); /* 画面内へ移動 */
}
/* メニュータイトル */
.drawer-menu-close-esc_heading{
margin:0 0 20px; /* 下余白 */
font-size:22px; /* 文字サイズ */
font-weight:700; /* 太字 */
}
/* メニュー一覧 */
.drawer-menu-close-esc_list{
margin:0 0 24px; /* 下余白 */
padding:0; /* 内側余白を削除 */
list-style:none; /* リスト記号を非表示 */
}
/* メニュー項目 */
.drawer-menu-close-esc_list li{
border-bottom:1px solid #e5e7eb; /* 項目間の枠線 */
}
/* メニューリンク */
.drawer-menu-close-esc_list a{
display:block; /* 項目全体をクリック可能にする */
padding:14px 4px; /* 内側余白 */
color:#111827; /* 文字色 */
text-decoration:none; /* 下線を非表示 */
}
/* メニューを閉じるボタン */
.drawer-menu-close-esc_close{
width:100%; /* 横幅いっぱい */
padding:12px; /* 内側余白 */
border:none; /* 枠線なし */
border-radius:8px; /* 角丸 */
background:#111827; /* 背景色 */
color:#ffffff; /* 文字色 */
font-size:15px; /* 文字サイズ */
font-weight:700; /* 太字 */
cursor:pointer; /* マウスカーソル */
}
/* 640px以下の画面 */
@media (max-width:640px){
/* デモ全体 */
.drawer-menu-close-esc_wrap{
padding:24px 18px; /* 小さい画面で内側余白を狭くする */
}
}
// ドロワーメニューを開くボタンを取得
const drawerOpenButton=document.querySelector("[data-drawer-open]");
// ドロワーメニューを閉じるボタンを取得
const drawerCloseButton=document.querySelector("[data-drawer-close]");
// ドロワーメニュー本体を取得
const drawerPanel=document.querySelector("[data-drawer-panel]");
// ドロワーメニュー表示時の背景を取得
const drawerOverlay=document.querySelector("[data-drawer-overlay]");
// ドロワーメニューを開く処理
function openDrawerMenu(){
// ドロワーメニューを表示
drawerPanel.classList.add("is-active");
// 背景を表示
drawerOverlay.classList.add("is-active");
// 支援技術へ表示状態を伝える
drawerPanel.setAttribute("aria-hidden","false");
}
// ドロワーメニューを閉じる処理
function closeDrawerMenu(){
// ドロワーメニューを非表示
drawerPanel.classList.remove("is-active");
// 背景を非表示
drawerOverlay.classList.remove("is-active");
// 支援技術へ非表示状態を伝える
drawerPanel.setAttribute("aria-hidden","true");
}
// 開くボタンをクリックした時
drawerOpenButton.addEventListener("click",openDrawerMenu);
// 閉じるボタンをクリックした時
drawerCloseButton.addEventListener("click",closeDrawerMenu);
// キーボードのキーを押した時
document.addEventListener("keydown",function(event){
// ESCキーが押され、ドロワーメニューが開いている場合
if(
event.key==="Escape" &&
drawerPanel.classList.contains("is-active")
){
// ドロワーメニューを閉じる
closeDrawerMenu();
}
});
ファイル構成と設置方法
このサンプルはHTML・CSS・JavaScriptの3ファイルで構成されています。HTMLでドロワーメニューとボタンの構造を作成し、CSSでメニューのレイアウトやスライド表示、背景オーバーレイのデザインを設定しています。JavaScriptではドロワーメニューの開閉処理に加え、ESCキーを押したときにメニューを閉じる処理を実装しています。ファイルごとに役割を分けているため、デザインと動作を個別に編集しやすく、初心者でも構成を理解しやすいサンプルです。
sample/
├── index.html
├── style.css
└── script.js
各ファイルの役割
・index.html:ドロワーメニュー本体、メニュー項目、開くボタン、閉じるボタンなど画面に表示するHTMLを記述します。
・style.css:ドロワーメニューの幅、背景色、文字サイズ、余白、背景オーバーレイ、スライドアニメーションなど見た目全体を設定します。
・script.js:ドロワーメニューの開閉処理と、ESCキーを押したときにメニューを閉じる処理を実装しています。
設置方法・使い方
① sampleフォルダを作成します。
② index.html・style.css・script.jsの3ファイルを配置します。
③ index.htmlをブラウザで開きます。
④ 「メニューを開く」ボタンをクリックするとドロワーメニューが表示されます。
⑤ 「閉じる」ボタンまたはESCキーを押すとドロワーメニューを閉じることができます。
カスタマイズできる内容
・index.htmlでは、メニュー項目やタイトル、ボタンの文字などを自由に変更できます。
・style.cssでは、メニューの幅、背景色、文字色、余白、角丸、影、背景オーバーレイの色などを変更できます。
・style.cssの「width:280px;」を変更するとドロワーメニューの横幅を調整できます。
・style.cssの「background:rgba(15,23,42,.45);」の「.45」を変更すると背景の暗さを調整できます。値を大きくすると暗く、小さくすると明るく表示されます。
・script.jsでは、ドロワーメニューを開閉する処理やESCキーで閉じる動作を変更できます。
数値調整
・style.cssの「transition:transform .3s;」の「0.3」は0.3秒でスライドアニメーションすることを表します。値を大きくするとゆっくり、小さくすると速く開閉します。
・style.cssの「transition:opacity .3s,visibility .3s;」の「0.3」は背景の表示・非表示にかかる時間です。値を変更するとフェード速度を調整できます。
レスポンシブ対応
このサンプルはレスポンシブ対応です。style.cssで「max-width:85%;」を指定しているため、小さい画面でもドロワーメニューが画面幅を超えません。また、メディアクエリで余白を調整しているため、スマートフォン・タブレット・PCでもレイアウトが崩れにくく、そのまま利用できます。
コメント