Nav collapse by container width
A navigation bar that collapses its links into a scrollable row or a compact stack based on the container width, using only CSS container queries.
Drag the bottom-right corner of the box to resize and watch the nav collapse into a stack.
Quick implementation
.nav-cq {
container-type: inline-size;
}
.cq-nav {
display: flex;
align-items: center;
gap: 0.5rem;
flex-wrap: wrap;
padding: 0.75rem 1rem;
background: var(--card);
border-radius: var(--radius);
}
.cq-nav__logo {
font-weight: 700;
margin-right: auto;
color: var(--text);
}
.cq-nav__links {
display: flex;
gap: 0.25rem;
flex-wrap: wrap;
list-style: none;
margin: 0;
padding: 0;
}
.cq-nav__link {
padding: 0.4rem 0.75rem;
border-radius: var(--radius);
color: var(--muted);
text-decoration: none;
font-size: 0.875rem;
white-space: nowrap;
}
.cq-nav__link:hover,
.cq-nav__link[aria-current="page"] {
background: oklch(0.22 0.04 265);
color: var(--text);
}
@container (max-width: 28rem) {
.cq-nav {
flex-direction: column;
align-items: flex-start;
}
.cq-nav__links {
flex-direction: column;
width: 100%;
}
.cq-nav__link {
display: block;
width: 100%;
}
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer building component-driven navigation.
Goal: A navigation bar that switches from a horizontal row of links to a
full-width stacked list based on its container width — using only CSS
container queries, no JavaScript.
Technical constraints:
- Apply container-type: inline-size to a wrapper div around the nav.
- Use @container (max-width: 28rem) to trigger the stacked layout.
- In wide mode: nav uses display: flex with flex-wrap: wrap; logo gets
margin-right: auto to push links right.
- In narrow mode: nav switches to flex-direction: column; links become
full-width block elements.
- The active link uses aria-current="page" as the selector hook.
- Use oklch() for all color values — no hex or rgba.
- Do not use media queries — only @container queries.
Framework variant (pick one):
A) Vanilla CSS utility — .nav-cq wrapper + .cq-nav, .cq-nav__links,
.cq-nav__link, .cq-nav__logo BEM classes.
B) React component — accepts a links array and a logoText prop; renders
the nav with container-type applied via a CSS Module.
Edge cases to handle:
- If the nav appears inside a container query context itself, add
container-name to scope the query to the correct boundary.
- Ensure aria-label="Main navigation" is present on the <nav> element.
- The wrapping approach avoids a hamburger menu and is preferable for
simple navigation that does not need JavaScript interaction.
Return CSS only (or a React component if variant B).
Why
Navigation patterns that collapse based on viewport width break in component-driven UIs where a nav appears in sidebars, modals, or narrow columns. Container queries allow the same nav component to behave correctly regardless of where it is mounted.
The logic
container-type: inline-size on the nav wrapper creates the containment context. By default the nav uses flex-wrap: wrap so links flow naturally. Below 28rem container width, @container kicks in: the nav switches to flex-direction: column and the links become full-width block elements. margin-right: auto on the logo pushes links to the right at wide widths and has no effect in column mode.
Accessibility & performance
Ensure the nav has aria-label="Main navigation" and the active link has aria-current="page". The wrapping approach is preferable to a hamburger menu (which requires JavaScript) for simple navigation.