画面の上下から開く横並びドロワーメニューの作り方

ドロワーメニュー
無料ツール
ドロワーメニューを自由に作成

表示位置・メニュー項目・サイズ・色・余白・閉じ方などを設定して、HTML・CSS・JavaScriptを自動生成できます。

ドロワーメニュー作成ツールを使う
新しいタブで開きます

画面の上または下からスライドして表示される、横並びドロワーメニューの作り方を紹介します。メニュー項目を横一列に配置し、画面の端から滑らかに出し入れできる仕組みです。

今回のデモでは、「上から開く」と「下から開く」の2つのボタンを用意しています。上から開く場合は画面上端から下方向へ、下から開く場合は画面下端から上方向へメニューがスライドします。どちらも画面の横幅いっぱいに表示されます。

メニューには「ホーム」「サービス」「お知らせ」「お問い合わせ」の4項目を横並びで配置しています。画面幅が狭く、すべての項目が収まらない場合は、メニュー部分を横スクロールして確認できます。

メニューを開くと背景が暗くなり、右上の「×」ボタン、背景部分のクリック、Escキーで閉じられます。上下どちらの方向から開く場合も、閉じると開いた方向へ戻ります。

デモ

横並びドロワーメニュー

メニューを開くと、画面の上または下から横並びのメニューが表示されます。

「上から開く」「下から開く」のボタンをクリックすると、画面の上端または下端から横並びのドロワーメニューがスライドして表示されます。メニュー項目は横一列に配置され、画面幅が狭い場合は横スクロールで確認できます。右上の「×」ボタン、暗くなった背景のクリック、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="top-bottom-horizontal-drawer_trigger"
    type="button"
    aria-controls="top-bottom-horizontal-drawer-panel"
    aria-expanded="false"
  >
    メニューを開く
  </button>

  <!-- メニュー表示中に背景を暗くするオーバーレイ -->
  <div class="top-bottom-horizontal-drawer_overlay" aria-hidden="true"></div>

  <!-- ドロワーメニュー本体。初期設定では画面下から開く -->
  <div
    class="top-bottom-horizontal-drawer_panel"
    id="top-bottom-horizontal-drawer-panel"
    aria-hidden="true"
    inert
  >

    <!-- メニュー上部 -->
    <div class="top-bottom-horizontal-drawer_header">

      <div class="top-bottom-horizontal-drawer_heading">
        メニュー
      </div>

      <!-- メニューを閉じるボタン -->
      <button
        class="top-bottom-horizontal-drawer_close"
        type="button"
        aria-label="メニューを閉じる"
      >
        ×
      </button>

    </div>

    <!-- 横並びのメニューリンク。hrefは実際のリンク先に変更する -->
    <nav class="top-bottom-horizontal-drawer_nav" aria-label="ドロワーメニュー">

      <a class="top-bottom-horizontal-drawer_link" href="#">
        ホーム
      </a>

      <a class="top-bottom-horizontal-drawer_link" href="#">
        サービス
      </a>

      <a class="top-bottom-horizontal-drawer_link" href="#">
        お知らせ
      </a>

      <a class="top-bottom-horizontal-drawer_link" href="#">
        お問い合わせ
      </a>

    </nav>

  </div>

  <!-- ドロワーメニューの開閉処理を読み込む -->
  <script src="script.js"></script>

</body>
</html>
コードについて 本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。 免責事項 本コードの利用により発生した損害について、当サイトは一切の責任を負いません。

コードをコピーする場合 使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。 サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
A

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では、開閉状態を切り替えるopenMenu()とcloseMenu()を使い、ボタン操作やEscキーに対応しています。

設置方法・使い方
「サンプル一式をダウンロード」をクリックしてZIPファイルを保存し、展開してください。 sampleフォルダ内のindex.html・style.css・script.jsを同じ階層に配置します。 index.htmlをブラウザで開くと、「メニューを開く」ボタンが表示されます。
ボタンをクリックすると画面下から横並びのドロワーメニューがスライドして表示され、背景が暗くなります。 メニュー右上の「×」ボタン、暗くなった背景のクリック、Escキーで閉じられます。 画面上から開く形に変更したい場合は、後述するstyle.cssの方向設定を切り替えてください。

画面下から開くドロワーの仕組み
初期設定では、style.cssの次の部分でドロワーを画面下端に配置しています。 閉じているときは、メニュー自身の高さ分だけ下へ移動させ、画面外に隠しています。

/* =========================================
  下から開くドロワーメニュー(初期設定)
========================================= */

.top-bottom-horizontal-drawer_panel {
  left: 0; /* 画面の左端に合わせる */
  bottom: 0; /* 画面の下端に合わせる */
  transform: translateY(100%); /* メニュー自身の高さ分だけ下へ隠す */
}

bottom: 0;でメニューを画面下端に配置し、left: 0;で左端に合わせています。 translateY(100%)は、メニュー自身の高さの100%分だけ下へ移動する指定です。
共通設定のwidth: 100%;によって横幅いっぱいに表示され、 max-height: 70dvh;で高さの上限を表示領域の70%にしています。 高さの上限を小さくしたい場合は50dvh、大きくしたい場合は80dvhなどに変更できます。 max-height: 70vh;は、dvhに対応していないブラウザ向けの指定です。

画面上から開く方法
画面上から開く場合は、style.cssにある「下から開くドロワーメニュー(初期設定)」のCSSブロックを削除し、 続く「上から開く場合の設定」のコメントアウトを解除してください。

/* =========================================
  上から開く場合の設定(コメントアウト)
  上から開く場合は下方向の設定を削除し、
  次のCSSのコメントアウトを解除する
========================================= */

/*
.top-bottom-horizontal-drawer_panel {
  top: 0;
  left: 0;
  transform: translateY(-100%);
}
*/

有効にするには、先頭の/*と末尾の*/を削除します。 top: 0;でメニューを画面上端に配置し、translateY(-100%)でメニュー自身の高さ分だけ上へ隠します。 開くときは画面上から下方向へスライドし、閉じるときは上方向へ戻ります。
translateY(100%)とtranslateY(-100%)の違いは移動方向です。 正の値では下方向、負の値では上方向へ移動します。 どちらもメニュー自身の高さを基準とするため、メニューの高さを変更しても画面外へ移動できます。
下方向と上方向の設定は、どちらか一方だけを有効にしてください。

開閉アニメーションと表示状態
メニューを開くと、JavaScriptによってis-activeクラスが追加されます。 このクラスが付くと、下方向または上方向に隠れていたメニューが画面内へ移動します。

/* =========================================
  メニューを開いた状態
========================================= */

.top-bottom-horizontal-drawer_panel.is-active {
  transform: translateY(0); /* 画面内の表示位置へスライドする */
  visibility: visible; /* メニューを表示する */
  pointer-events: auto; /* メニュー内の操作を有効にする */
  box-shadow: 0 0 30px rgba(15, 23, 42, 0.18); /* メニューの周囲に影を表示する */
}

translateY(0)は縦方向の移動量を0に戻す指定です。 下から開く場合も上から開く場合も、共通のCSSで画面内へスライドさせています。
アニメーションの速度は、.top-bottom-horizontal-drawer_panelの共通設定にある transition: transform 0.3s ease, visibility 0.3s ease;で調整できます。 0.3sを0.5sにするとゆっくり、0.2sにすると速くなります。
box-shadowの30pxは影のぼかし範囲、0.18は影の不透明度です。 影を目立たせたい場合は不透明度を大きくし、薄くしたい場合は小さくしてください。

メニュー項目を横並びにする仕組み
横並びのメニューは、style.cssの.top-bottom-horizontal-drawer_navで設定しています。 display: flex;とflex-direction: row;によって、4つのリンクを横一列に配置しています。

/* =========================================
  横並びメニュー
========================================= */

.top-bottom-horizontal-drawer_nav {
  display: flex; /* メニュー項目を横並びにする */
  flex-direction: row; /* 横方向に並べる */
  gap: 12px; /* 項目間の余白 */
  overflow-x: auto; /* 横幅に収まらない場合は横スクロールを可能にする */
  padding-bottom: 4px; /* スクロールバーとの間隔 */
}

gap: 12px;はリンク同士の間隔です。 20pxに変更すると間隔が広くなり、8pxに変更すると狭くなります。
overflow-x: auto;を指定しているため、リンクが画面幅に収まらない場合はメニュー部分を横スクロールできます。 画面が狭くてもリンクを無理に折り返さず、横並びを維持する構成です。

横並びリンクの幅と高さ
各リンクには.top-bottom-horizontal-drawer_linkを設定しています。 文字を中央に配置し、リンク全体をクリックできる領域にしています。

/* 各メニューリンク */
.top-bottom-horizontal-drawer_link {
  display: flex; /* 文字を中央に配置する */
  align-items: center; /* 縦方向の中央に揃える */
  justify-content: center; /* 横方向の中央に揃える */
  flex: 1 0 120px; /* 均等に広げ、基本横幅を120pxにする */
  min-height: 52px; /* リンクの最小の高さ */
  padding: 14px 16px; /* 上下14px・左右16pxの内側余白 */
  border-radius: 8px; /* リンクの角丸 */
  background: #f1f5f9; /* リンクの背景色 */
  color: #111827; /* リンクの文字色 */
  font-size: 16px; /* 文字サイズ */
  font-weight: 700; /* 文字の太さ */
  text-align: center; /* 文字を中央揃えにする */
  text-decoration: none; /* 下線を表示しない */
  white-space: nowrap; /* リンク内の文字を折り返さない */
  box-sizing: border-box; /* 余白を横幅と高さに含める */
}

flex: 1 0 120px;は、各リンクの基本横幅を120pxとし、余裕がある場合は均等に広げ、狭い場合でも縮めない設定です。 基本横幅を広げたい場合は160px、狭くしたい場合は100pxなどに変更できます。
min-height: 52px;はリンクの最小の高さです。 60pxにすると縦に大きく、44pxにするとコンパクトになります。 white-space: nowrap;によってリンク内の文字を折り返さないため、長い項目名でも横並びを維持できます。
リンクの文字やリンク先はindex.htmlで変更します。 「ホーム」「サービス」「お知らせ」「お問い合わせ」の文字を変更でき、各a要素のhref="#"には実際の移動先URLを指定してください。 項目を増やしたい場合は、同じクラスを付けたa要素をnav内に追加します。

JavaScriptでメニューを開く処理
script.jsでは、「メニューを開く」ボタンがクリックされるとopenMenu()を実行します。 メニュー本体と背景オーバーレイにis-activeクラスを追加し、開いた状態へ切り替えています。

/* =========================================
  メニューを開く
========================================= */

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();

}

drawer.classList.add("is-active")によってドロワーがスライドして表示され、 overlay.classList.add("is-active")で背景が暗くなります。
drawer.inert = false;はメニュー内の操作を有効にする処理です。 aria-hiddenとaria-expandedも開いた状態に更新し、 最後にcloseButton.focus()で「×」ボタンへフォーカスを移動します。

閉じるボタン・背景クリック・Escキーによる操作
メニューを閉じるときはcloseMenu()を実行します。 メニューと背景オーバーレイからis-activeクラスを削除すると、CSSで設定した画面外の位置へ戻ります。

/* =========================================
  メニューを閉じる
========================================= */

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;

}

openButton.focus()でメニューを開いたボタンへフォーカスを戻し、 aria-hidden="true"とinertで閉じたメニューを操作対象から外します。
「×」ボタンと背景オーバーレイにはclickイベントを登録し、どちらもcloseMenu()を呼び出しています。 Escキーについては、メニューが開いているときだけ閉じる処理を実行します。

/* =========================================
  Escキーで閉じる
========================================= */

document.addEventListener("keydown", function(event) {

  // メニューが開いているときだけEscキーで閉じる
  if (
    event.key === "Escape" &&
    drawer.classList.contains("is-active")
  ) {
    closeMenu();
  }

});

event.key === "Escape"でEscキーが押されたことを確認し、 drawer.classList.contains("is-active")でメニューが開いているかを判定しています。 この2つの条件を満たした場合だけcloseMenu()を実行します。
背景の暗さは、style.cssの.top-bottom-horizontal-drawer_overlayにある background: rgba(15, 23, 42, 0.45);で調整できます。 最後の0.45を大きくすると背景が暗く、小さくすると薄くなります。

スマートフォンでの横並び表示
style.cssでは、画面幅640px以下で開くボタンとドロワー内部の余白、メニューリンクの文字サイズなどを調整しています。 横並びの配置は維持し、リンクが収まらない場合は横スクロールできるようにしています。

/* =========================================
  スマートフォン対応
========================================= */

@media (max-width: 640px) {

  /* スマートフォンで開くボタンを調整する */
  .top-bottom-horizontal-drawer_trigger {
    min-height: 48px; /* ボタンの最小の高さ */
    padding: 10px 12px; /* 上下10px・左右12pxの内側余白 */
    font-size: 14px; /* 文字サイズ */
  }

  /* スマートフォンでメニュー内の余白を調整する */
  .top-bottom-horizontal-drawer_panel {
    padding: 24px 18px; /* 上下24px・左右18pxの内側余白 */
  }

  /* メニュー上部とリンクの間隔を小さくする */
  .top-bottom-horizontal-drawer_header {
    margin-bottom: 20px; /* メニュー項目との間隔 */
  }

  /* メニュータイトルの文字サイズを調整する */
  .top-bottom-horizontal-drawer_heading {
    font-size: 22px; /* 文字サイズ */
  }

  /* スマートフォンでリンクの大きさを調整する */
  .top-bottom-horizontal-drawer_link {
    flex-basis: 120px; /* リンクの基本横幅 */
    min-height: 48px; /* リンクの最小の高さ */
    padding: 12px 14px; /* 上下12px・左右14pxの内側余白 */
    font-size: 14px; /* 文字サイズ */
  }

}

PCでは開くボタンの最小の高さを52px、文字サイズを16pxにしていますが、 画面幅640px以下では高さ48px、文字サイズ14pxに変更しています。 ドロワー内部の余白も上下32px・左右24pxから、上下24px・左右18pxへ縮小します。
メニューリンクの基本横幅はスマートフォンでも120pxを維持し、文字サイズを14pxにしています。 overflow-x: auto;によって、リンクが横幅に収まらない場合も横一列のままスクロールできます。
画面幅を切り替える基準はmax-width: 640pxです。 例えば768pxに変更すると、より広い画面幅からスマートフォン向けのスタイルが適用されます。


こちらもおすすめ


コメント