Components

Dropdown

Built on the popover API. The browser handles the top layer, closing on an outside click, and closing on escape.

popovertarget on the trigger, popover on the panel. There is no script and no wiring.

Placement

The panel is placed under its trigger, aligned to its starting edge, and flips above when there is no room below.

Three classes move it elsewhere:

<div class="pui-dropdown pui-top" id="menu" popover>Above the trigger</div>
<div class="pui-dropdown pui-start" id="menu" popover>Before the trigger</div>
<div class="pui-dropdown pui-end" id="menu" popover>After the trigger</div>
ClassWhere it goes
(none)below
pui-topabove
pui-startto the left, or the right in RTL
pui-endto the right, or the left in RTL

Each one flips to the opposite side when the preferred one does not fit, so a menu never opens off screen.

Alignment

A panel that opens above or below lines up with the trigger's starting edge. Two classes move it along that axis:

<div class="pui-dropdown pui-align-center" id="menu" popover>Centered</div>
<div class="pui-dropdown pui-align-end" id="menu" popover>
  Aligned to the end
</div>
ClassWhere it lines up
(none)with the trigger's starting edge
pui-align-centercentered on the trigger
pui-align-endwith the trigger's ending edge

pui-align-end is what a menu at the end of a header wants, so it opens inward instead of running off the page.

Placement uses CSS anchor positioning. Browsers that do not have it yet get the same placement, including the direction classes, from the fallback in the script.

Anything can go inside

The panel is a container, not a menu. A list is the common case, but a form or a card work just as well:

<div class="pui-dropdown" id="filters" popover>
  <label class="pui-field-group">
    <span>Search</span>
    <input class="pui-input" />
  </label>
</div>

Closing from inside

<div class="pui-dropdown" id="menu" popover>
  <button
    class="pui-btn pui-link pui-theme"
    popovertarget="menu"
    popovertargetaction="hide"
  >
    Close
  </button>
</div>

From JavaScript

const menu = document.getElementById("menu");
menu.showPopover();
menu.hidePopover();
menu.togglePopover();