ESCキーで閉じられるドロワーメニューの作り方
ESCキーで閉じられるドロワーメニューを作る方法を紹介します。このサンプルでは、画面左側から表示されるドロワーメニューをJavaScriptで制御し、キーボードのESCキーを押すだけで閉じられるように実装します。マウス操作だけでなくキーボード操作にも対応するため、操作性やアクセシビリティを向上させたいWebサイトにも導入しやすい構成です。
管理画面、会員サイト、ECサイト、企業サイトなど、サイドメニューを利用するさまざまな場面で活用できます。メニューを開いたあと、ESCキーを押すだけで素早く閉じられるため、パソコンでの操作性が向上し、快適に画面を切り替えられます。ドロワーメニューは左側からスライド表示され、シンプルで分かりやすい動作を確認できます。
タイトル、説明文、メニュー項目はHTMLから変更でき、CSSでは横幅、余白、背景色、角丸、影、アニメーション速度などを自由に調整できます。JavaScriptではESCキーで閉じる処理のみを実装しているため、動作が分かりやすく、スマートフォン・タブレット・PCでも利用しやすいドロワーメニューのサンプルとして活用できます。
コードについて
本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。
免責事項
本コードの利用により発生した損害について、当サイトは一切の責任を負いません。
デモ
「メニューを開く」をクリックしたあと、キーボードのESCキーを押すとドロワーメニューが閉じます。
コードをコピーして使おう!
<!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="esc-close-drawer-menu_wrap">
<!-- タイトル -->
<div class="esc-close-drawer-menu_title">
ESCキーで閉じられるドロワーメニュー
</div>
<!-- 説明文 -->
<p class="esc-close-drawer-menu_text">
ボタンをクリックしたあと、ESCキーを押すとドロワーメニューを閉じられます。
</p>
<!-- ドロワーメニューを開くボタン -->
<button
class="esc-close-drawer-menu_button"
type="button"
data-esc-close-drawer-open>
メニューを開く
</button>
</div>
<!-- ドロワーメニュー表示時の背景 -->
<div
class="esc-close-drawer-menu_overlay"
data-esc-close-drawer-overlay
aria-hidden="true">
<!-- ドロワーメニュー本体 -->
<aside
class="esc-close-drawer-menu_drawer"
role="dialog"
aria-modal="true"
aria-labelledby="esc-close-drawer-menu-title">
<!-- ドロワーメニューのタイトル -->
<div
class="esc-close-drawer-menu_drawer-title"
id="esc-close-drawer-menu-title">
メニュー
</div>
<!-- 操作説明 -->
<p class="esc-close-drawer-menu_drawer-text">
ESCキーを押すとドロワーメニューを閉じられます。
</p>
<!-- ナビゲーション -->
<nav
class="esc-close-drawer-menu_nav"
aria-label="メニュー">
<a href="#">ホーム</a>
<a href="#">サービス</a>
<a href="#">お知らせ</a>
<a href="#">お問い合わせ</a>
</nav>
</aside>
</div>
<!-- JavaScriptファイル -->
<script src="script.js"></script>
</body>
</html>
/* ページ全体 */
body{
margin:0; /* ブラウザ標準の外側余白を削除 */
padding:40px 20px; /* 上下40px・左右20px。値を大きくすると画面端との間隔が広がる */
background:#ffffff; /* ページ全体の背景色 */
color:#111827; /* ページ全体の基本文字色 */
font-family:sans-serif; /* ページ全体で使用するフォント */
}
/* ドロワーメニューの案内エリア */
.esc-close-drawer-menu_wrap{
width:100%; /* 画面幅に合わせて横幅を縮小 */
max-width:700px; /* 最大横幅。値を大きくすると全体が横に広がる */
margin:40px auto; /* 上下40pxの余白を付けて左右中央へ配置 */
padding:32px; /* 内側の余白。値を大きくすると内容と枠線の間隔が広がる */
border:1px solid #e5e7eb; /* 案内エリアを囲む枠線 */
border-radius:18px; /* 全体の角丸。値を大きくすると丸みが強くなる */
background:#f8fafc; /* 案内エリアの背景色 */
text-align:center; /* 内容を中央揃えにする */
box-sizing:border-box; /* paddingとborderを横幅へ含める */
}
/* 案内エリアのタイトル */
.esc-close-drawer-menu_title{
margin:0 0 12px; /* 下側12pxの余白。値を大きくすると説明文との間隔が広がる */
font-size:22px; /* タイトルの文字サイズ。値を大きくすると文字が大きくなる */
font-weight:700; /* タイトルを太字にする */
line-height:1.5; /* タイトルの行間。値を大きくすると行間が広がる */
}
/* 案内エリアの説明文 */
.esc-close-drawer-menu_text{
margin:0 0 24px; /* 下側24pxの余白。値を大きくするとボタンとの間隔が広がる */
color:#4b5563; /* 説明文の文字色 */
line-height:1.8; /* 説明文の行間。値を大きくすると行間が広がる */
}
/* ドロワーメニューを開くボタン */
.esc-close-drawer-menu_button{
min-height:48px; /* ボタンの最小高さ。値を大きくすると縦方向へ大きくなる */
padding:12px 24px; /* 上下12px・左右24px。値を大きくするとボタンが大きくなる */
border:none; /* ブラウザ標準の枠線を削除 */
border-radius:8px; /* ボタンの角丸。値を大きくすると丸みが強くなる */
background:#2563eb; /* ボタンの背景色 */
color:#ffffff; /* ボタンの文字色 */
font:inherit; /* ページ全体と同じフォントを使用 */
font-weight:700; /* ボタンの文字を太字にする */
cursor:pointer; /* マウスを重ねたときに指の形へ変更 */
transition:
background-color .3s ease,
transform .3s ease;
/*
0.3秒で背景色と位置を切り替える。
値を大きくすると遅くなり、小さくすると速くなる。
*/
}
/* ボタンへマウスを重ねたとき */
.esc-close-drawer-menu_button:hover{
background:#1d4ed8; /* マウスを重ねたときの背景色 */
transform:translateY(-2px); /* 2px上へ移動。値を大きくすると移動量が増える */
}
/* キーボード操作でボタンを選択したとき */
.esc-close-drawer-menu_button:focus-visible{
outline:3px solid rgba(37,99,235,.35); /* 外側の強調線。3pxを変更すると太さが変わる */
outline-offset:3px; /* ボタンと強調線の間隔。値を大きくすると外側へ離れる */
}
/* ドロワーメニュー表示時の背景 */
.esc-close-drawer-menu_overlay{
position:fixed; /* スクロールしても画面全体へ固定 */
inset:0; /* 上下左右を0にして画面全体へ広げる */
z-index:9999; /* ページ内のほかの要素より手前へ表示 */
display:flex; /* ドロワーメニューを配置する */
align-items:stretch; /* ドロワーメニューを画面の高さに合わせる */
justify-content:flex-start; /* ドロワーメニューを画面左側へ配置 */
background:rgba(17,24,39,.55); /* 背景を半透明の黒色にする */
opacity:0; /* 閉じているときは背景を透明にする */
visibility:hidden; /* 閉じているときは操作できない状態にする */
pointer-events:none; /* 閉じているときはクリックを受け付けない */
transition:
opacity .3s ease,
visibility .3s ease;
/*
0.3秒で背景の表示状態を切り替える。
値を大きくするとゆっくり、小さくすると速く切り替わる。
*/
}
/* ドロワーメニューを開いている状態 */
.esc-close-drawer-menu_overlay.is-active{
opacity:1; /* 背景を表示する */
visibility:visible; /* ドロワーメニューを操作できる状態にする */
pointer-events:auto; /* クリック操作を受け付ける */
}
/* ドロワーメニュー本体 */
.esc-close-drawer-menu_drawer{
width:360px; /* ドロワーメニューの横幅。値を大きくすると横に広がる */
max-width:90%; /* 画面幅を超えないよう最大幅を90%に制限 */
height:100%; /* 画面の高さ全体へ表示 */
padding:32px; /* 内側の余白。値を大きくすると内容と画面端の間隔が広がる */
overflow-y:auto; /* 内容が画面の高さを超えた場合に縦スクロールを表示 */
background:#ffffff; /* ドロワーメニューの背景色 */
box-shadow:10px 0 40px rgba(17,24,39,.24); /* 右側へ表示する影。数値を変更すると位置や広がりが変わる */
box-sizing:border-box; /* paddingを横幅と高さへ含める */
transform:translateX(-100%); /* 閉じているときは画面左側へ隠す */
transition:transform .35s ease;
/*
0.35秒でドロワーメニューを横方向へ移動する。
値を大きくするとゆっくり、小さくすると速く開閉する。
*/
}
/* ドロワーメニューを開いているときの本体 */
.esc-close-drawer-menu_overlay.is-active .esc-close-drawer-menu_drawer{
transform:translateX(0); /* 画面左側から表示位置へ移動する */
}
/* ドロワーメニューのタイトル */
.esc-close-drawer-menu_drawer-title{
margin:0 0 16px; /* 下側16pxの余白。値を大きくすると説明文との間隔が広がる */
font-size:22px; /* タイトルの文字サイズ。値を大きくすると文字が大きくなる */
font-weight:700; /* タイトルを太字にする */
line-height:1.5; /* タイトルの行間。値を大きくすると行間が広がる */
}
/* ドロワーメニュー内の説明文 */
.esc-close-drawer-menu_drawer-text{
margin:0 0 24px; /* 下側24pxの余白。値を大きくするとリンク一覧との間隔が広がる */
color:#4b5563; /* 説明文の文字色 */
line-height:1.8; /* 説明文の行間。値を大きくすると行間が広がる */
}
/* ナビゲーション */
.esc-close-drawer-menu_nav{
display:flex; /* メニューリンクを並べる */
flex-direction:column; /* メニューリンクを縦方向へ配置 */
gap:12px; /* リンク同士の間隔。値を大きくすると間隔が広がる */
}
/* メニューリンク */
.esc-close-drawer-menu_nav a{
display:block; /* リンク全体をクリックできるようにする */
min-height:48px; /* タップしやすい最小高さ。値を大きくすると縦に広がる */
padding:14px 16px; /* 上下14px・左右16px。値を大きくすると内側余白が広がる */
border-radius:8px; /* リンクの角丸。値を大きくすると丸みが強くなる */
background:#f3f4f6; /* リンクの背景色 */
color:#111827; /* リンクの文字色 */
font-weight:700; /* リンクの文字を太字にする */
line-height:1.5; /* リンク文字の行間。値を大きくすると行間が広がる */
text-decoration:none; /* リンクの下線を削除 */
box-sizing:border-box; /* paddingを横幅と高さへ含める */
transition:
background-color .3s ease,
color .3s ease,
transform .3s ease;
/*
0.3秒で背景色・文字色・位置を切り替える。
値を大きくすると遅くなり、小さくすると速くなる。
*/
}
/* メニューリンクへマウスを重ねたとき */
.esc-close-drawer-menu_nav a:hover{
background:#2563eb; /* マウスを重ねたときの背景色 */
color:#ffffff; /* マウスを重ねたときの文字色 */
transform:translateX(4px); /* 4px右へ移動。値を大きくすると移動量が増える */
}
/* キーボード操作でメニューリンクを選択したとき */
.esc-close-drawer-menu_nav a:focus-visible{
outline:3px solid rgba(37,99,235,.35); /* 外側の強調線。3pxを変更すると太さが変わる */
outline-offset:3px; /* リンクと強調線の間隔。値を大きくすると外側へ離れる */
}
/* 画面幅640px以下 */
@media (max-width:640px){
/* ページ全体 */
body{
padding:24px 16px; /* スマートフォンでは画面端の余白を小さくする */
}
/* 案内エリア */
.esc-close-drawer-menu_wrap{
margin:24px auto; /* スマートフォンでは上下余白を24pxにする */
padding:24px 18px; /* スマートフォンでは内側余白を小さくする */
}
/* ドロワーメニューを開くボタン */
.esc-close-drawer-menu_button{
width:100%; /* スマートフォンでは横幅いっぱいに表示 */
}
/* ドロワーメニュー本体 */
.esc-close-drawer-menu_drawer{
width:100%; /* スマートフォンでは画面幅いっぱいに表示 */
max-width:100%; /* 最大横幅の制限を画面幅に合わせる */
padding:28px 20px; /* スマートフォンでは内側余白を調整 */
}
}
// ドロワーメニューを開くボタン
const openButton=document.querySelector("[data-esc-close-drawer-open]");
// オーバーレイ
const overlay=document.querySelector("[data-esc-close-drawer-overlay]");
// ドロワーメニューを開く
openButton.addEventListener("click",()=>{
// ドロワーメニューを表示
overlay.classList.add("is-active");
// aria-hiddenを更新
overlay.setAttribute("aria-hidden","false");
});
// ESCキーが押されたとき
document.addEventListener("keydown",(event)=>{
// ESCキーかどうか判定
if(event.key==="Escape"){
// ドロワーメニューを閉じる
overlay.classList.remove("is-active");
// aria-hiddenを更新
overlay.setAttribute("aria-hidden","true");
}
});
コードをコピーする場合
使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。
サンプル一式を取得する場合
HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
ファイル構成と設置方法
このサンプルはHTML・CSS・JavaScriptの3ファイルで構成されています。HTMLではドロワーメニューの案内エリア、開くボタン、メニュー本体、ナビゲーション項目を作成します。CSSでは画面左側から表示されるドロワーメニューの横幅、背景色、余白、影、開閉アニメーションなどを設定し、JavaScriptでは開くボタンのクリック処理とESCキーを押したときに閉じる処理を行います。
sample/
├── index.html
├── style.css
└── script.js
各ファイルの役割
index.htmlはドロワーメニュー全体の構造を作成するファイルです。案内エリアのタイトル、説明文、開くボタンの文字、ドロワーメニュー内のタイトル、操作説明、メニュー項目を変更できます。
style.cssはドロワーメニューのデザインを設定するファイルです。案内エリアやボタンの見た目、オーバーレイの背景色、ドロワーメニューの横幅、余白、影、リンクの配色、ホバー時の表示、開閉アニメーションなどを調整できます。
script.jsはドロワーメニューの開閉を制御するファイルです。「メニューを開く」ボタンをクリックすると表示用クラスを追加し、ESCキーが押されると表示用クラスを削除してドロワーメニューを閉じます。
設置方法・使い方
sampleフォルダへindex.html、style.css、script.jsを配置します。3つのファイルを同じ階層へ保存したあと、sample/index.htmlをブラウザで開いてください。「メニューを開く」ボタンをクリックすると画面左側からドロワーメニューが表示されます。メニューが開いている状態でキーボードのESCキーを押すと、ドロワーメニューが閉じます。
カスタマイズできる内容
index.htmlでは案内エリアのタイトルや説明文、ボタン名、ドロワーメニュー内のタイトル、説明文、各メニュー項目の文章とリンク先を変更できます。用途に合わせて、管理画面のナビゲーション、会員サイトのメニュー、ECサイトのカテゴリー一覧などへ変更できます。
style.cssでは案内エリアやドロワーメニューの横幅、背景色、文字色、余白、角丸、影、ボタンやリンクの色、ホバー時の移動量、開閉アニメーションの速度を変更できます。script.jsではESCキーを判定する処理と、表示用クラスを追加・削除する処理を確認できます。
数値調整
style.css
max-width:700px;
案内エリアの最大横幅です。値を大きくすると横に広がり、小さくするとコンパクトになります。
margin:40px auto;
案内エリアの上下余白です。40pxを大きくすると上下の間隔が広がり、小さくすると狭くなります。
padding:32px;
案内エリアとドロワーメニュー本体の内側余白です。値を大きくすると内容と端の間隔が広がり、小さくすると詰まった表示になります。
border-radius:18px;
案内エリアの角丸です。値を大きくすると丸みが強くなり、0にすると四角になります。
width:360px;
ドロワーメニュー本体の横幅です。値を大きくするとメニューが広くなり、小さくすると細く表示されます。
background:rgba(17,24,39,.55);
オーバーレイの透明度です。最後の0.55を大きくすると背景が濃くなり、小さくすると薄くなります。
transition:opacity .3s ease;
オーバーレイが切り替わる時間です。0.3秒で変化します。値を大きくするとゆっくり、小さくすると速く切り替わります。
transition:transform .35s ease;
ドロワーメニューがスライドする時間です。0.35秒で開閉します。値を大きくするとゆっくり、小さくすると速く動きます。
transform:translateY(-2px);
開くボタンへマウスを重ねたときの移動量です。2pxを大きくすると上方向への移動量が増えます。
transform:translateX(4px);
メニューリンクへマウスを重ねたときの移動量です。4pxを大きくすると右方向への移動量が増えます。
gap:12px;
メニューリンク同士の間隔です。値を大きくすると間隔が広がり、小さくすると狭くなります。
レスポンシブ対応
このサンプルはレスポンシブ対応です。style.cssのwidth:100%とmax-widthにより、案内エリアが画面幅に合わせて縮小されます。また、@media (max-width:640px)ではページ全体や案内エリアの余白を小さくし、開くボタンとドロワーメニュー本体を横幅いっぱいに表示します。スマートフォン・タブレット・PCで利用できます。
コメント