Skip to content

Latest commit

 

History

History
177 lines (133 loc) · 5.27 KB

File metadata and controls

177 lines (133 loc) · 5.27 KB

Dropdown

dropdown — Container

Wraps a toggle, menu, and items into a single dropdown unit. Uses the native Popover API for light-dismiss (clicking outside closes the menu automatically).

<!-- Basic dropdown -->
<div dropdown>
  <button dropdown-toggle>Options</button>
  <ul dropdown-menu>
    <li dropdown-item>Edit</li>
    <li dropdown-item>Duplicate</li>
    <li dropdown-item>Delete</li>
  </ul>
</div>

<!-- Positioned to the right, aligned to end -->
<div dropdown dropdown-position="right" dropdown-align="end">
  <button dropdown-toggle>More</button>
  <ul dropdown-menu>
    <li dropdown-item>Settings</li>
    <li dropdown-item>Logout</li>
  </ul>
</div>

Container Attributes

Attribute Type Default Description
dropdown boolean attr required Marks the wrapper element
dropdown-position "bottom" | "top" | "left" | "right" "bottom" Primary axis for menu placement
dropdown-align "start" | "end" "start" Cross-axis alignment of the menu relative to the toggle

The menu is positioned with position: fixed and automatically flips to the opposite side when it would overflow the viewport.

Note: Because dropdown menus use position: fixed with viewport-absolute coordinates, they escape parent overflow: hidden containers. This means dropdowns inside scrollable or clipped elements will still display correctly.


dropdown-toggle — Trigger Button

The element that opens/closes the dropdown menu on click. Must be inside a [dropdown] container.

<div dropdown>
  <button dropdown-toggle>Click me</button>
  <ul dropdown-menu>
    <li dropdown-item>Option A</li>
    <li dropdown-item>Option B</li>
  </ul>
</div>

The toggle automatically receives:

  • aria-haspopup="menu"
  • aria-expanded="true" / "false" (updated on open/close)
  • aria-controls linked to the menu's id

dropdown-menu — Popover Menu

The menu panel that appears when the toggle is activated. Uses popover="auto" for native light-dismiss behavior.

<div dropdown>
  <button dropdown-toggle>Actions</button>
  <ul dropdown-menu>
    <li dropdown-item>Cut</li>
    <li dropdown-item>Copy</li>
    <li dropdown-item>Paste</li>
  </ul>
</div>

The menu automatically receives:

  • popover="auto" (native Popover API)
  • role="menu"
  • A unique id (auto-generated if not provided)
  • Class .nojs-dropdown-menu

dropdown-item — Menu Item

An actionable item inside the dropdown menu. Supports keyboard navigation, disabled state, and automatic ARIA attributes.

<!-- With disabled items -->
<div dropdown>
  <button dropdown-toggle>File</button>
  <ul dropdown-menu>
    <li dropdown-item>New</li>
    <li dropdown-item>Open</li>
    <li dropdown-item disabled>Save (read-only)</li>
    <li dropdown-item>Export</li>
  </ul>
</div>

<!-- With links -->
<div dropdown>
  <button dropdown-toggle>Navigate</button>
  <ul dropdown-menu>
    <a dropdown-item href="/dashboard">Dashboard</a>
    <a dropdown-item href="/settings">Settings</a>
    <a dropdown-item href="/help">Help</a>
  </ul>
</div>

Item Attributes

Attribute Type Default Description
dropdown-item boolean attr required Marks the element as a menu item
disabled boolean attr Disables the item (skipped during keyboard navigation)

Each item automatically receives:

  • role="menuitem"
  • tabindex="-1"
  • Class .nojs-dropdown-item
  • aria-disabled="true" when disabled is present

Keyboard Navigation

Key On toggle On item
Enter / Space Opens menu, focuses first item Activates item (click)
Arrow Down Opens menu, focuses first item Moves focus to next item (wraps to first)
Arrow Up Opens menu, focuses last item Moves focus to previous item (wraps to last)
Home Moves focus to first item
End Moves focus to last item
Escape Closes menu, returns focus to toggle
Tab Closes menu, returns focus to toggle

Disabled items are skipped during arrow-key navigation.


CSS Classes

No.JS automatically injects these classes:

Class When applied
.nojs-dropdown-menu On the menu element ([dropdown-menu])
.nojs-dropdown-item On each item element ([dropdown-item])
.nojs-dropdown-item[aria-disabled="true"] On disabled items — pointer-events: none; opacity: 0.5
.nojs-dropdown-item:focus-visible On the currently focused item (for keyboard navigation styling)

The menu uses position: fixed with z-index: 9999 and min-width: max-content. It repositions on scroll and resize while open.


Accessibility

No.JS automatically adds:

  • aria-haspopup="menu" on the toggle
  • aria-expanded="true/false" on the toggle (reflects open state)
  • aria-controls linking the toggle to the menu
  • role="menu" on the menu
  • role="menuitem" on each item
  • tabindex="-1" on items (roving focus via keyboard)
  • aria-disabled="true" on disabled items
  • Focus is trapped within the menu while open — Escape or Tab returns focus to the toggle

Next: Toast Notifications →