ドロワーメニューは、画面の端からスライドして表示されるメニューです。普段はメニューを隠しておけるため、画面を広く使えるのが特徴です。さらにアコーディオン機能を組み合わせると、親メニューをクリックして子メニューを開閉でき、項目が多い場合でもすっきりと整理できます。
今回は、画面の左側から表示されるアコーディオン付きドロワーメニューを作成します。「メニューを開く」ボタンをクリックするとドロワーが横方向にスライドし、内部の「サービス」や「お知らせ」をクリックすると子メニューが上下に開閉します。複数の親メニューを同時に開くことができ、閉じるボタンや背景部分をクリックするとドロワーを閉じられます。
ドロワーの横スライドにはCSSのtransformとtransitionを使用し、アコーディオンの縦スライドにはgrid-template-rowsを使用します。JavaScriptではクリックしたボタンに応じてクラスを切り替えるだけなので、複雑な処理を使わずに2種類のスライド動作を実装できます。
この記事では、HTML・CSS・JavaScriptを使ったアコーディオン付きドロワーメニューの作り方を紹介します。実際に操作できるデモと、コピーして使えるサンプルコードを用意しているので、メニューの項目やリンク先、色やサイズなどを変更して、自分のWebサイトに合わせてカスタマイズできます。
デモ
コードをコピーして使おう!
<!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">
<!-- 開閉処理用JavaScriptを読み込む -->
<script src="script.js" defer></script>
</head>
<body>
<!-- =========================================
ドロワーメニューを開くボタン
========================================= -->
<button class="accordion-drawer-menu_open" type="button" data-accordion-drawer-menu-open="">
メニューを開く
</button>
<!-- =========================================
背景オーバーレイ
========================================= -->
<div class="accordion-drawer-menu_overlay" data-accordion-drawer-menu-overlay="">
</div>
<!-- =========================================
ドロワーメニュー本体
========================================= -->
<aside class="accordion-drawer-menu_drawer" data-accordion-drawer-menu-drawer="" aria-hidden="true">
<!-- メニュー見出しと閉じるボタン -->
<div class="accordion-drawer-menu_header">
<div class="accordion-drawer-menu_heading">
メニュー
</div>
<button class="accordion-drawer-menu_close" type="button" data-accordion-drawer-menu-close="" aria-label="閉じる">
</button>
</div>
<!-- =========================================
アコーディオンメニュー
========================================= -->
<nav class="accordion-drawer-menu_nav" aria-label="メインメニュー">
<!-- 1つ目のアコーディオン -->
<div class="accordion-drawer-menu_group">
<button class="accordion-drawer-menu_parent" type="button" aria-expanded="false">
<span class="accordion-drawer-menu_label">
サービス
</span>
<!-- プラス・マイナスアイコン -->
<span class="accordion-drawer-menu_icon" aria-hidden="true">
<span class="accordion-drawer-menu_icon-closed">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M12 4v16 M4 12h16"></path>
</svg>
</span>
<span class="accordion-drawer-menu_icon-open">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 12h16"></path>
</svg>
</span>
</span>
</button>
<!-- 子メニュー -->
<div class="accordion-drawer-menu_child">
<div class="accordion-drawer-menu_child-inner">
<!--
href="#"を実際のリンク先URLに変更してください。
例:href="/service/web/"
-->
<a class="accordion-drawer-menu_link" href="#" data-accordion-drawer-menu-link="">
Web制作
</a>
<a class="accordion-drawer-menu_link" href="#" data-accordion-drawer-menu-link="">
システム開発
</a>
<a class="accordion-drawer-menu_link" href="#" data-accordion-drawer-menu-link="">
保守サポート
</a>
</div>
</div>
</div>
<!-- 2つ目のアコーディオン -->
<div class="accordion-drawer-menu_group">
<button class="accordion-drawer-menu_parent" type="button" aria-expanded="false">
<span class="accordion-drawer-menu_label">
お知らせ
</span>
<!-- プラス・マイナスアイコン -->
<span class="accordion-drawer-menu_icon" aria-hidden="true">
<span class="accordion-drawer-menu_icon-closed">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M12 4v16 M4 12h16"></path>
</svg>
</span>
<span class="accordion-drawer-menu_icon-open">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 12h16"></path>
</svg>
</span>
</span>
</button>
<!-- 子メニュー -->
<div class="accordion-drawer-menu_child">
<div class="accordion-drawer-menu_child-inner">
<a class="accordion-drawer-menu_link" href="#" data-accordion-drawer-menu-link="">
新着情報
</a>
<a class="accordion-drawer-menu_link" href="#" data-accordion-drawer-menu-link="">
イベント
</a>
<a class="accordion-drawer-menu_link" href="#" data-accordion-drawer-menu-link="">
更新履歴
</a>
</div>
</div>
</div>
</nav>
</aside>
</body>
</html>
コードをコピーする場合 使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。 サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
Googleアカウントがあれば、InfinityFreeで無料サーバーを作成して、ダウンロードしたサンプルをネット上で動かせます。
InfinityFreeを初めて利用する場合は①から、すでにサーバーを作成している場合は②へ進んでください。
ファイル構成と設置方法
アコーディオン付きドロワーメニューは、HTMLでメニューの項目を配置し、CSSで横方向・縦方向のスライドアニメーションを設定しています。JavaScriptでは、ドロワーとアコーディオンの開閉状態を切り替えます。サンプルは3つのファイルで構成され、外部ライブラリや画像ファイルを用意する必要はありません。
sample/
├── index.html
├── style.css
└── script.js
各ファイルの役割
index.htmlには、ドロワーを開くボタン、背景オーバーレイ、ドロワー本体、アコーディオンの親メニューと子メニューを配置しています。style.cssでは、ドロワーの表示位置やスライドアニメーション、アコーディオンの開閉時の高さ、メニューの色や余白などを設定しています。script.jsでは、クリックされたボタンに応じてクラスを切り替え、各メニューの開閉を制御しています。
設置方法・使い方
「サンプル一式をダウンロード」からZIPファイルを保存して解凍し、index.html・style.css・script.jsを同じフォルダに配置します。index.htmlをブラウザで開くと、「メニューを開く」ボタンからドロワーを表示できます。ドロワー内の「サービス」や「お知らせ」をクリックすると、それぞれの子メニューが開閉します。ドロワーは右上の閉じるボタン、または背景の暗い部分をクリックすると閉じられます。
ドロワーが横方向にスライドする仕組み
ドロワーは、CSSのtransformで画面の左側に隠しています。JavaScriptでis-activeクラスを追加すると、ドロワーの位置が切り替わり、画面内へスライドします。
/* ドロワーを画面内に表示する */
.accordion-drawer-menu_drawer.is-active {
transform: translateX(0);
}
script.jsのopenAccordionDrawerMenu()では、背景オーバーレイとドロワーの両方にis-activeクラスを追加しています。反対にcloseAccordionDrawerMenu()では、このクラスを削除して元の状態へ戻します。背景の暗転とドロワーのスライドを、同じクラス名で切り替える仕組みです。
function openAccordionDrawerMenu() {
/* 背景とドロワーを表示する */
accordionDrawerMenuOverlay.classList.add("is-active");
accordionDrawerMenuDrawer.classList.add("is-active");
/* 開いた状態を属性へ反映する */
accordionDrawerMenuDrawer.setAttribute("aria-hidden", "false");
}
アコーディオンが縦方向に開閉する仕組み
アコーディオンでは、CSSのgrid-template-rowsを使って子メニューの高さを変化させています。閉じているときは0fr、開いているときは1frに切り替わり、transitionによって滑らかに開閉します。
/* 初期状態では子メニューを閉じる */
.accordion-drawer-menu_child {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows .3s ease; /* 縦スライドの時間 */
background: #ffffff;
}
/* 開いたときに子メニューの高さを広げる */
.accordion-drawer-menu_group.is-open
.accordion-drawer-menu_child {
grid-template-rows: 1fr;
}
script.jsでは、クリックされた親メニューが属する.accordion-drawer-menu_groupを取得し、is-openクラスを切り替えています。操作したグループだけが開閉するため、「サービス」と「お知らせ」を同時に開くこともできます。プラス・マイナスアイコンの表示も、このis-openクラスに連動しています。
/* クリックした親メニューのグループを取得する */
const accordionGroup = parent.closest(
".accordion-drawer-menu_group"
);
/* クリックしたグループだけを開閉する */
const isOpen = accordionGroup.classList.toggle("is-open");
/* 開閉状態を属性へ反映する */
parent.setAttribute(
"aria-expanded",
String(isOpen)
);
カスタマイズできる内容
メニューの名前や項目はindex.htmlで変更できます。子メニューのリンク先は、各.accordion-drawer-menu_linkに設定されているhref="#"を、移動先のURLに置き換えてください。アコーディオンを追加する場合は、.accordion-drawer-menu_groupをひとまとまりとして複製し、親メニュー名と子メニューを変更します。JavaScriptは各親メニューに開閉処理を設定するため、同じ構造で追加できます。
数値調整
ドロワーの横幅はstyle.cssの.accordion-drawer-menu_drawerにあるwidth: 380px;で変更できます。横スライドの速度はtransition: transform .35s ease;、アコーディオンの開閉速度はtransition: grid-template-rows .3s ease;で調整します。時間の数値を小さくすると素早く、大きくするとゆっくり動きます。
レスポンシブ対応
style.cssでは、ドロワーにmax-width: 92%;を設定し、画面幅より大きくならないようにしています。また、@media (max-width: 640px)で画面幅640px以下のドロワー内側の余白を調整しています。
コメント