画面の左側からスライドして表示される、基本的なドロワーメニューの作り方を紹介します。「メニューを開く」ボタンをクリックすると、画面の外に隠れていたメニューが左から滑らかに現れ、同時に背景が半透明の暗いオーバーレイで覆われます。
メニューには「ホーム」「サービス」「お知らせ」「お問い合わせ」の4項目を配置しています。開いたメニューは、右上の「×」ボタンをクリックするほか、暗くなった背景をクリックするか、キーボードのEscキーを押すことでも閉じられます。閉じるときはメニューが左側へスライドして戻り、背景の暗さも解除されます。
メニューを開くと操作対象がドロワー内の「×」ボタンへ移り、閉じると元の開閉ボタンへ戻る仕組みも備えています。今回のデモでは、左側からの開閉アニメーション、背景オーバーレイ、3種類の閉じ方を実際に確認できます。
デモ
「メニューを開く」をクリックすると、画面左側からドロワーメニューがスライドして表示され、背景が暗くなります。メニュー右上の「×」ボタン、暗くなった背景のクリック、Escキーのいずれかで閉じられます。
コードをコピーして使おう!
<!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>
<!-- メニューを開くボタン -->
<button
class="basic-drawer-menu_open"
type="button"
aria-expanded="false"
aria-controls="basic-drawer-menu-panel"
>
メニューを開く
</button>
<!-- 背景を暗くするオーバーレイ -->
<div class="basic-drawer-menu_overlay" aria-hidden="true"></div>
<!-- 左側から表示するドロワーメニュー -->
<div
class="basic-drawer-menu_drawer"
id="basic-drawer-menu-panel"
aria-hidden="true"
inert
>
<!-- ドロワー上部 -->
<div class="basic-drawer-menu_header">
<div class="basic-drawer-menu_heading">
メニュー
</div>
<!-- × 閉じるボタン -->
<button
class="basic-drawer-menu_close"
type="button"
aria-label="メニューを閉じる"
>
×
</button>
</div>
<!-- メニュー項目。href="#"は設置先のURLへ変更してください -->
<nav class="basic-drawer-menu_nav" aria-label="ドロワーメニュー">
<a class="basic-drawer-menu_link" href="#">
ホーム
</a>
<a class="basic-drawer-menu_link" href="#">
サービス
</a>
<a class="basic-drawer-menu_link" href="#">
お知らせ
</a>
<a class="basic-drawer-menu_link" href="#">
お問い合わせ
</a>
</nav>
</div>
<!-- ドロワーメニューの開閉処理を読み込む -->
<script src="script.js"></script>
</body>
</html>
コードをコピーする場合 使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。 サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
Googleアカウントがあれば、InfinityFreeで無料サーバーを作成して、ダウンロードしたサンプルをネット上で動かせます。
InfinityFreeを初めて利用する場合は①から、すでにサーバーを作成している場合は②へ進んでください。
ファイル構成と設置方法
今回のドロワーメニューは、HTML・CSS・JavaScriptの3つのファイルで構成されています。HTMLで開閉ボタン・背景オーバーレイ・メニュー項目を配置し、CSSで左側からのスライド表示を設定しています。JavaScriptでは、ボタン操作・背景クリック・Escキーによる開閉と、開閉時のフォーカス移動を制御しています。
sample/
├── index.html
├── style.css
└── script.js
各ファイルの役割
index.htmlには、「メニューを開く」ボタン、背景オーバーレイ、ドロワー本体、右上の「×」ボタン、4つのメニューリンクを記述しています。
style.cssでは、ドロワーの横幅・配置位置・背景色・スライドアニメーションや、オーバーレイの透明度を設定しています。
script.jsでは、is-activeクラスの追加・削除による表示切り替えと、閉じる操作の判定を行っています。
設置方法・使い方
「サンプル一式をダウンロード」をクリックしてZIPファイルを保存し、展開してください。sampleフォルダ内のindex.html・style.css・script.jsを同じ階層に配置します。
index.htmlをブラウザで開くと、「メニューを開く」ボタンが表示されます。クリックすると画面左側からドロワーが開き、背景が暗くなります。
メニューを閉じる場合は、右上の「×」ボタン、暗くなった背景のクリック、Escキーのいずれかを使用します。
ドロワーメニューを左側から表示する仕組み
style.cssの.basic-drawer-menu_drawerでは、position: fixed;でドロワーを画面に固定し、top: 0;とleft: 0;で左上を基準に配置しています。
閉じた状態ではtransform: translateX(calc(-100% - 40px));によって、ドロワー自身の横幅より40px余分に左へ移動させ、画面外へ隠しています。
/* =========================================
左側から開くドロワーメニュー
========================================= */
.basic-drawer-menu_drawer {
position: fixed; /* スクロール位置に関係なく画面に固定する */
top: 0; /* 画面上端に配置する */
left: 0; /* 画面左端に配置する */
z-index: 9999; /* オーバーレイより前面に表示する */
width: 320px; /* ドロワーの横幅。大きくすると横に広がる */
max-width: 85%; /* 画面幅の85%を上限にする */
height: 100vh; /* 古いブラウザ向けの画面高 */
height: 100dvh; /* ブラウザの表示領域に合わせた高さ */
padding: 32px 24px; /* 上下32px・左右24pxの内側余白 */
background: #ffffff; /* ドロワーの背景色 */
box-shadow: none; /* 閉じた状態では影を表示しない */
transform: translateX(calc(-100% - 40px)); /* 自身の横幅と40px分だけ左へ移動して画面外に隠す */
visibility: hidden; /* 閉じた状態では非表示にする */
pointer-events: none; /* 閉じた状態ではクリックを受け付けない */
transition: transform 0.3s ease, visibility 0.3s ease; /* 0.3秒で左からスライドして開閉する */
box-sizing: border-box; /* 余白を横幅・高さに含める */
font-family: sans-serif; /* ドロワー内のフォント */
overflow-y: auto; /* 内容が縦に収まらない場合はスクロールできるようにする */
}
width: 320px;を400pxに変更するとドロワーが広くなり、260pxにすると狭くなります。ただし、max-width: 85%;が指定されているため、画面が狭い場合は画面幅の85%以内に収まります。
スライド速度はtransitionの0.3sで指定しています。0.5sにするとゆっくり開閉し、0.2sにすると速くなります。
メニューを開いた状態へ切り替える方法
.basic-drawer-menu_drawer.is-activeでは、transform: translateX(0);を指定しています。JavaScriptでis-activeクラスが追加されると、画面外に隠れていたドロワーが左端の表示位置まで移動します。
/* メニューを開いたときのドロワー */
.basic-drawer-menu_drawer.is-active {
transform: translateX(0); /* 画面左端の表示位置まで移動する */
visibility: visible; /* ドロワーを表示する */
pointer-events: auto; /* メニュー内の操作を受け付ける */
box-shadow: 12px 0 30px rgba(15, 23, 42, 0.18); /* 右側へ12px・ぼかし30pxの影を付ける */
}
visibility: visible;で表示状態に変更し、pointer-events: auto;によってメニュー内のリンクやボタンをクリックできるようにしています。
box-shadowはドロワー右側の影です。影をなくしたい場合はbox-shadow: none;に変更してください。
背景オーバーレイの表示と透明度
背景オーバーレイにはposition: fixed;とinset: 0;を指定し、画面全体を覆うように配置しています。z-index: 9998;はドロワーの9999より小さいため、暗い背景がメニューの後ろに表示されます。
/* =========================================
背景オーバーレイ
========================================= */
.basic-drawer-menu_overlay {
position: fixed; /* 画面に固定する */
inset: 0; /* 画面の上下左右いっぱいに広げる */
z-index: 9998; /* 通常のページ内容より前面に表示する */
background: rgba(15, 23, 42, 0.45); /* 暗い背景。0.45を大きくすると暗くなる */
opacity: 0; /* 閉じた状態では透明にする */
visibility: hidden; /* 閉じた状態では非表示にする */
pointer-events: none; /* 閉じた状態ではクリックを受け付けない */
transition: opacity 0.3s ease, visibility 0.3s ease; /* 0.3秒で背景を滑らかに表示・非表示にする */
}
/* メニューを開いたときのオーバーレイ */
.basic-drawer-menu_overlay.is-active {
opacity: 1; /* 背景を表示する */
visibility: visible; /* オーバーレイを表示状態にする */
pointer-events: auto; /* 背景クリックを受け付ける */
}
background: rgba(15, 23, 42, 0.45);の最後の数値は背景色の透明度です。0.65にすると暗くなり、0.2にすると薄くなります。
オーバーレイもis-activeクラスで表示を切り替え、opacityの変化によって滑らかに表示・非表示にしています。
JavaScriptでメニューを開閉する仕組み
script.jsのopenMenu()では、ドロワーとオーバーレイにis-activeクラスを追加します。closeMenu()では、そのクラスを削除して閉じた状態に戻します。
// ドロワーメニューを開く処理
function openMenu() {
// ドロワー内のボタンやリンクを操作可能にする
drawer.inert = false;
// ドロワーと背景オーバーレイを表示する
drawer.classList.add("is-active");
overlay.classList.add("is-active");
// メニューの開閉状態をアクセシビリティ属性へ反映する
drawer.setAttribute("aria-hidden", "false");
openButton.setAttribute("aria-expanded", "true");
// × 閉じるボタンへキーボードのフォーカスを移動する
closeButton.focus();
}
// ドロワーメニューを閉じる処理
function closeMenu() {
// フォーカスを元の開くボタンへ戻す
openButton.focus();
// ドロワーと背景オーバーレイを非表示にする
drawer.classList.remove("is-active");
overlay.classList.remove("is-active");
// メニューの開閉状態をアクセシビリティ属性へ反映する
drawer.setAttribute("aria-hidden", "true");
openButton.setAttribute("aria-expanded", "false");
// 閉じたドロワー内のボタンやリンクを操作できないようにする
drawer.inert = true;
}
drawer.inert = false;は、メニューを開くときに内部のリンクやボタンを操作可能にする処理です。閉じるときはdrawer.inert = true;に変更し、画面外に隠れたメニュー内の要素がキーボード操作の対象にならないようにしています。
また、aria-expandedとaria-hiddenを更新して、メニューの開閉状態を属性にも反映しています。開くときは「×」ボタンへフォーカスを移し、閉じると元の「メニューを開く」ボタンへ戻します。
× ボタン・背景クリック・Escキーで閉じる方法
3種類の閉じる操作には、共通のcloseMenu()関数を使用しています。「×」ボタンと背景オーバーレイにはclickイベントを登録し、Escキーはkeydownイベントで判定します。
// 開くボタンをクリックするとメニューを表示する
openButton.addEventListener("click", openMenu);
// × ボタンをクリックするとメニューを閉じる
closeButton.addEventListener("click", closeMenu);
// 暗くなった背景をクリックするとメニューを閉じる
overlay.addEventListener("click", closeMenu);
// Escキーでメニューを閉じる
document.addEventListener("keydown", function(event) {
// メニューが開いている場合だけEscキーで閉じる
if (
event.key === "Escape" &&
drawer.classList.contains("is-active")
) {
closeMenu();
}
});
Escキーの処理では、event.key === "Escape"で押されたキーを確認し、drawer.classList.contains("is-active")でメニューが開いているか判定しています。両方の条件を満たした場合だけcloseMenu()を実行します。
そのため、メニューが閉じている状態でEscキーを押しても、開閉処理は実行されません。
メニュー項目とリンク先の変更方法
index.htmlの.basic-drawer-menu_nav内には、4つのリンクを配置しています。項目名はa要素内の文字を変更し、移動先はhref属性に指定します。
<!-- メニュー項目。href="#"は設置先のURLへ変更してください -->
<nav class="basic-drawer-menu_nav" aria-label="ドロワーメニュー">
<a class="basic-drawer-menu_link" href="#">
ホーム
</a>
<a class="basic-drawer-menu_link" href="#">
サービス
</a>
<a class="basic-drawer-menu_link" href="#">
お知らせ
</a>
<a class="basic-drawer-menu_link" href="#">
お問い合わせ
</a>
</nav>
現在のhref="#"は仮の指定です。実際に設置する場合は、それぞれのリンク先URLへ変更してください。
項目を追加する場合は、同じa要素を増やします。メニュー項目はflex-direction: column;で縦方向に並ぶため、項目数に応じて下へ追加されます。
レスポンシブ対応
ドロワーにはwidth: 320px;とmax-width: 85%;を指定しているため、画面が狭くなってもドロワーが画面幅を超えないようにしています。
また、画面幅が640px以下の場合は、ドロワー内の余白を小さくしています。
/* =========================================
スマートフォン対応
========================================= */
@media (max-width: 640px) {
/* 画面幅640px以下ではドロワー内の余白を小さくする */
.basic-drawer-menu_drawer {
padding: 24px 18px; /* 上下24px・左右18pxの内側余白 */
}
}
通常時の内側余白は上下32px・左右24pxですが、画面幅640px以下では上下24px・左右18pxに変更されます。
スマートフォンでメニュー内の余白をさらに狭くしたい場合は、paddingの数値を小さくしてください。
コメント