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