Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как сделать выпадающее меню

Короткий ответ

details открывается и закрывается сам, а список под кнопкой ставим через position: absolute:

<style>
  .dd { position: relative; display: inline-block; }
  .dd summary { list-style: none; cursor: pointer; padding: 6px 12px; background: royalblue; color: white; border-radius: 6px; }
  .dd ul { position: absolute; top: 100%; left: 0; z-index: 1; margin: 4px 0 0; padding: 6px 0; list-style: none; min-width: 140px; background: white; border: 1px solid gainsboro; border-radius: 6px; box-shadow: 0 6px 16px rgb(0 0 0 / 15%); }
  .dd a { display: block; padding: 6px 12px; color: inherit; text-decoration: none; }
  .dd a:hover { background: aliceblue; }
</style>
 
<details class="dd">
  <summary>Account ▾</summary>
  <ul><li><a href="https://example.com">Profile</a></li><li><a href="https://example.com">Orders</a></li><li><a href="https://example.com">Log out</a></li></ul>
</details>
<p>Content below the menu</p>

Меню на popover

Атрибут popover выводит меню в верхний слой поверх всего, закрывает его кликом снаружи и по Esc. Кнопка связывается с ним через popovertarget:

<button popovertarget="menu">Sort by ▾</button>
<div id="menu" popover style="padding: 8px; border: 1px solid gainsboro; border-radius: 6px;">
  <p style="margin: 4px;">Price</p><p style="margin: 4px;">Rating</p><p style="margin: 4px;">Newest</p>
</div>

По умолчанию popover стоит в центре экрана. Привязать его к кнопке помогает CSS-позиционирование по якорю (position-anchor), а там, где его нет, — небольшой скрипт.

Частая ошибка

Меню только на :hover: на телефоне наведения нет, а с клавиатуры такое меню не открыть. Если меню всё же раскрывается по наведению, добавьте :focus-within, чтобы оно открывалось и по Tab.

Функции из этого ответа

  • <details>, <summary> — Раскрывающийся блок без JavaScript: `<summary>` — видимый заголовок, остальное скрыто до клика.
  • position — Как позиционируется элемент: в обычном потоке или по смещениям.
  • :has() — Выбирает элемент, внутри которого есть что-то подходящее под селектор в скобках, — «селектор родителя».
  • popover — Превращает элемент во всплывающий слой поверх страницы — без JavaScript.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.