Navigation and overlays
Dropdown
A menu that opens below a trigger, built on <details> or on a popover for light dismiss. Opens on focus or hover for plain wrappers, with end, top, left and right placements.
Example
<div class="flex gap-2"><details class="dropdown"><summary class="inline-flex items-center justify-center gap-2 rounded-lg border border-border bg-surface px-4 py-2 text-sm font-medium hover:bg-muted">Options</summary><ul class="dropdown-content menu"><li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><path d="M14 3v6h6"/></svg>Rename</a></li><li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>Duplicate<kbd class="menu-shortcut">Ctrl D</kbd></a></li><li class="menu-divider"></li><li><a href="#" class="menu-danger"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6"/></svg>Delete</a></li></ul></details><button type="button" popovertarget="account-menu" class="inline-flex items-center justify-center gap-2 rounded-lg border border-border bg-surface px-4 py-2 text-sm font-medium hover:bg-muted">Account</button><ul id="account-menu" popover class="dropdown-content dropdown-end menu"><li class="menu-title">Signed in as Ana</li><li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></svg>Profile</a></li><li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M4.9 4.9 7 7M17 17l2.1 2.1M2 12h3M19 12h3M4.9 19.1 7 17M17 7l2.1-2.1"/></svg>Settings</a></li></ul></div>Classes
8 classes. Click a name to copy it. Utilities on the same element always win over component defaults, so any of them can be adjusted with plain utility classes.
| Class | Type | What it does |
|---|---|---|
| Base | Base class of the dropdown. On a <details> in the example. Sets inline-block display, height, absolute position, offsets, margin and transition.CSS |
|
| Modifier | Modifier, combined with the dropdown class. On an <ul> in the example. Sets fixed position, offsets, margin, opacity, transform and transition.CSS |
|
| Modifier | Modifier, combined with the dropdown class. On an <ul> in the example. Sets --popover-area and --dropdown-pos.CSS |
|
| Modifier | Modifier, combined with the dropdown class. Not used in the example above. Sets 6 custom properties.CSS |
|
| Modifier | Modifier, combined with the dropdown class. Not used in the example above. Sets 4 custom properties.CSS |
|
| Modifier | Modifier, combined with the dropdown class. Not used in the example above. Sets 4 custom properties.CSS |
|
| Modifier | Modifier, combined with the dropdown class. Not used in the example above. Sets opacity and transform.CSS |
|
| Modifier | Modifier, combined with the dropdown class. Not used in the example above. Sets opacity and transform.CSS |
Usage
Components ship inside the same stylesheet as the utilities. There is nothing else to install and no script to load: link Monsoon and write the markup.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/monsooncss">
<!-- Dropdown: start from the base class, then add modifiers -->
<div class="flex gap-2"><details class="dropdown"><summary class="inline-flex items-center justify-center gap-2 rounded-lg border border-border bg-surface px-4 py-2 text-sm font-medium hover:bg-muted">Options</summary><ul class="dropdown-content menu"><li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><path d="M14 3v6h6"/></svg>Rename</a></li><li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>Duplicate<kbd class="menu-shortcut">Ctrl D</kbd></a></li><li class="menu-divider"></li><li><a href="#" class="menu-danger"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6"/></svg>Delete</a></li></ul></details><button type="button" popovertarget="account-menu" class="inline-flex items-center justify-center gap-2 rounded-lg border border-border bg-surface px-4 py-2 text-sm font-medium hover:bg-muted">Account</button><ul id="account-menu" popover class="dropdown-content dropdown-end menu"><li class="menu-title">Signed in as Ana</li><li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></svg>Profile</a></li><li><a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M4.9 4.9 7 7M17 17l2.1 2.1M2 12h3M19 12h3M4.9 19.1 7 17M17 7l2.1-2.1"/></svg>Settings</a></li></ul></div>Theme it with --seed on any ancestor, for example style="--seed: #0d9488", and force a scheme with class="dark" or class="light" on a wrapper.
Accessibility
- Uses the
popoverattribute: the browser handles light dismiss, Escape and top layer stacking, andpopovertargetwires the trigger without JavaScript. - Built on
detailsandsummary, so it opens with Enter or Space and screen readers announce expanded and collapsed. A sharednamemakes a group exclusive. - Use
buttonfor actions andafor navigation. Icon only buttons need anaria-label; decorative icons carryaria-hidden="true". - Every interactive part shows a visible focus ring with
:focus-visible, and tone colors pair with-foregroundtokens that keep text at 4.5:1 or better in light and dark mode.