ドロップダウンメニューとは

メニュー項目にマウスを重ねる・クリックすると、下に一覧が開くサブメニュー。

概要

メニューの項目にマウスを重ねる(ホバー)か、クリック・タップすると、その下にさらに詳しいリンクの一覧が開く仕組みです。 限られたスペースの中に多くのリンクを収める目的で使われます。マウス操作だけでなく、キーボードでフォーカスしたときにも開くようにしておくと、誰でも操作できるようになります。

別名

表記ゆれ:プルダウンメニュー、サブメニュー、ドロップダウン、dropdown menu、pulldown menu

「プルダウンメニュー」とほぼ同じ意味で使われますが、厳密には「プルダウン」はフォームの選択肢(セレクトボックス)を指すことも多い言葉です。

AI への伝え方

「ドロップダウンメニューを実装して」で通じます。開くきっかけを「ホバー」にするか「クリック」にするかで挙動が大きく変わるので、明示すると狙った動きになります。スマホではホバーが効かないため、クリックでも開くようにしてほしい場合はその旨も伝えます。

似たパーツとの違い

ドロップダウンメニューは 1 列のシンプルな一覧が開く形式で、複数の列やバナー画像まで含む大きな一覧が開くものは「メガメニュー」と呼びます。 フォームの部品として値を選ばせるものは「セレクトボックス」で、こちらはリンク集ではなく入力欄の一種という違いがあります。

デモ

コード

HTML
<nav class="dropdown-menu-demo" aria-label="サンプルメニュー">
  <div class="dropdown-menu-demo__item">
    <button
      class="dropdown-menu-demo__trigger"
      type="button"
      aria-expanded="false"
      aria-controls="dropdown-menu-demo-list"
    >
      サービス
    </button>
    <ul class="dropdown-menu-demo__list" id="dropdown-menu-demo-list">
      <li><a href="#">Web制作</a></li>
      <li><a href="#">SEO対策</a></li>
      <li><a href="#">広告運用</a></li>
    </ul>
  </div>
</nav>
CSS
.dropdown-menu-demo {
  font-family: sans-serif;
}

.dropdown-menu-demo__item {
  position: relative;
  display: inline-block;
}

.dropdown-menu-demo__trigger {
  padding: 10px 16px;
  border: 1px solid #ddd;
  border-radius: 8px;
  background: #fff;
  font-size: 14px;
  cursor: pointer;
}

.dropdown-menu-demo__trigger:hover {
  background: #f2f2f2;
}

.dropdown-menu-demo__list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  min-width: 160px;
  margin: 0;
  padding: 8px;
  list-style: none;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 8px;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.12);
  display: none;
  z-index: 10;
}

.dropdown-menu-demo__item:hover .dropdown-menu-demo__list,
.dropdown-menu-demo__item:focus-within .dropdown-menu-demo__list,
.dropdown-menu-demo__trigger[aria-expanded="true"] + .dropdown-menu-demo__list {
  display: block;
}

.dropdown-menu-demo__list a {
  display: block;
  padding: 8px 10px;
  border-radius: 6px;
  color: #212121;
  text-decoration: none;
  font-size: 14px;
}

.dropdown-menu-demo__list a:hover {
  background: #f2f2f2;
}
JS
document.querySelectorAll(".dropdown-menu-demo__trigger").forEach((trigger) => {
  trigger.addEventListener("click", () => {
    const isOpen = trigger.getAttribute("aria-expanded") === "true";
    trigger.setAttribute("aria-expanded", String(!isOpen));
  });
});

document.addEventListener("click", (event) => {
  document.querySelectorAll(".dropdown-menu-demo__item").forEach((item) => {
    if (!item.contains(event.target)) {
      item.querySelector(".dropdown-menu-demo__trigger")?.setAttribute("aria-expanded", "false");
    }
  });
});

document.addEventListener("keydown", (event) => {
  if (event.key === "Escape") {
    document.querySelectorAll(".dropdown-menu-demo__trigger").forEach((trigger) => {
      trigger.setAttribute("aria-expanded", "false");
    });
  }
});