Adaptive Navigation
One navigation, three shapes depending on its container's width: a menu button that opens the list, inline links from 320 px, a sidebar from 480 px.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Utilities has 43 effects, including 3 free. Explore the category →
3 usage examples



How it works
The .fx-0757-root element is the queried container (container: anv-nav / inline-size). It holds .anv-shell, with the <nav class="anv-nav"> (the .anv-logo brand, the .anv-burger button and a single <ul class="anv-links"> list) followed by the .anv-content area, where your page content goes. The links exist only once in the HTML: only their layout changes.
Below 320 px, the bar shows the brand and a three-line button; the list is hidden. The button adds the is-open class to the nav and sets aria-expanded to true: the list opens as a column under the bar and pushes the content down, the lines turn into a cross. Escape closes it (and returns focus to the button if it was inside the menu), as do a click outside, a click on a link or tabbing out of the menu.
From 320 px, @container anv-nav (min-width: 320px) hides the button and lines the links up to the right of the brand. From 480 px, the shell becomes a 160px 1fr grid: the nav turns into a vertical sidebar (brand on top, links stacked) and the content is centred to its right. The script attaches once per root, with no id; the clicked link gets aria-current="page".
Accessibility
- Real menu button: a
<button type="button">named “Menu”, witharia-expanded; the list follows the button in reading order, so Tab goes straight to the first link once the menu is open. - Keyboard closing: Escape closes the menu and puts focus back on the button; tabbing past the last link closes it too, without trapping focus.
- Real links:
<a href>in a<ul>inside a<nav aria-label>; the active link carriesaria-current="page". In Safari, Tab only stops on links with Option+Tab or the macOS keyboard setting. - Visible focus: 2 px
#a78bfaoutline on the brand, the button and the links. Button target: 32 × 32 px. - Reduced motion: the menu always opens without animation; under
prefers-reduced-motion: reduce, the links' hover fade is removed too.
Browser compatibility
Container queries (Chrome 105, Firefox 110, Safari 16), Element.closest(), :focus-visible (Safari 15.4). Measured in Chromium 151, Firefox 153 and WebKit 26.5 with two copies on one page: button shown up to 319 px, inline links from 321 to 479 px, sidebar from 481 px; at 280 px, the 2nd copy's button opens only the 2nd (4 links visible and clickable) on click, tap and Enter; Escape, outside click and focus leaving close it; 0 errors.
Without container queries, the nav keeps its narrow shape (button + collapsible list) at every width, still usable. Without JavaScript, the button opens nothing below 320 px: keep the script, or repeat the links in the footer.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0757-root">
<div class="anv-shell">
<nav class="anv-nav" aria-label="…">
<div class="anv-head">
<a class="anv-logo" href="#">…</a>
<button type="button" class="anv-burger" aria-expanded="false" aria-label="Menu">…</button>
</div>
<ul class="anv-links">
<li><a href="#…" aria-current="page">…</a></li>
<li><a href="#…">…</a></li>
</ul>
</nav>
<div class="anv-content">…</div>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Breakpoints (CSS — @container anv-nav (min-width: 320px) and (min-width: 480px)) |
320 px inline links, 480 px sidebar | Fit them to your labels' length: with six links, raise the first one towards 420 px. |
Sidebar width (CSS — grid-template-columns: 160px 1fr) |
160 px | Widen it for long labels. |
Links (HTML — .anv-links) |
Home, About, Blog, Contact | One <li><a> per link; aria-current="page" on the current page. |
Brand (HTML — .anv-logo) |
“Brand” text, colour #986ef7 |
Replace it with your name or a logo <img alt>. |
Content (HTML — .anv-content) |
“Page content area” | Put your page in it; in sidebar mode it is centred: switch it to display: block for running text. |
| Colours (CSS) | Shell rgba(255,255,255,.05), links rgba(255,255,255,.7), active link #c4b5fd |
On a light background, also change the button lines (.anv-burger span). |
FAQ
overflow: hidden parent. For an overlay menu, set .anv-links to position: absolute in your CSS.