ComponentPorchlight CSS

Dropdown

Button-triggered option menu using Popover API + anchor positioning. Supports icons, descriptions, and custom rendering.

51 components9 patterns46 stable5 experimental

Command

Search Porchlight

Dropdown

The .pl-c-dropdown is a button-triggered option menu using the Popover API + CSS Anchor Positioning. Use it for sort menus, filter pickers, and action choices that need icons or richer rows.

For ordinary forms, prefer a native <select>. If an app uses .pl-c-dropdown as a select-like control, app JavaScript must sync aria-expanded, the checked or selected option, and a hidden input or other submitted value.

Semantic HTML

<div class="pl-c-dropdown">
  <button
    class="pl-c-dropdown__trigger"
    id="project-trigger"
    popovertarget="dd-1"
    aria-haspopup="menu"
    aria-controls="dd-1"
    aria-expanded="false"
  >
    <span class="pl-c-dropdown__label">Project Alpha</span>
    <svg class="pl-c-dropdown__chevron">...</svg>
  </button>
  <div
    popover
    class="pl-c-dropdown__menu"
    id="dd-1"
    role="menu"
    aria-labelledby="project-trigger"
  >
    <button
      class="pl-c-dropdown__option"
      type="button"
      role="menuitemradio"
      tabindex="-1"
      aria-checked="true"
    >
      Project Alpha
    </button>
    <button
      class="pl-c-dropdown__option"
      type="button"
      role="menuitemradio"
      tabindex="-1"
      aria-checked="false"
    >
      Project Beta
    </button>
  </div>
</div>

Update aria-expanded when the popover opens or closes. For single-choice menus, use role="menuitemradio" plus aria-checked; for command/action menus, use role="menuitem" and do not present the component as a submitted form value unless you sync one.

Unlike the simpler Popover menu disclosure, using role="menu" opts into the complete ARIA menu-button contract. Application JavaScript must:

  • open the menu and move focus to its first enabled item (or the checked item for a single-choice menu);
  • support ArrowDown/ArrowUp with wrapping plus Home/End;
  • close on Escape and return focus to the trigger;
  • keep aria-expanded, aria-checked, the visible label, and any submitted value synchronized.

Menu items use tabindex="-1" because arrow keys, rather than Tab, move focus within an open ARIA menu. Porchlight ships the visual contract only; the preview provides a framework-neutral reference implementation.

Class contract

Selector Role
.pl-c-dropdown Container (inline-block).
.pl-c-dropdown__trigger The button that opens the menu. Sync aria-expanded.
.pl-c-dropdown__chevron Arrow icon (rotates when open).
.pl-c-dropdown__menu The popover menu (anchored); app owns interaction JS.
.pl-c-dropdown__option A menu item (button or link).
[aria-selected] Highlighted option.
[aria-checked] Checked menuitemradio option.