The Sidebar Layout
The sidebar pattern is one fixed-width column next to one fluid column that takes the rest of the space, with a rule for what happens when the container gets too narrow for both. Every Layout's version of this pattern (see Further Learning Resources) frames it as an intrinsic layout — no media query decides the breakpoint, the content's own width does.
Grid version — fixed + fluid
.layout {
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
gap: 1.5rem;
}minmax(0, 1fr) rather than plain 1fr matters here — an implicit minimum width of auto on a grid track means wide content (a code block, a long unbreakable URL) can stretch the "fluid" column past the container. Explicitly flooring it at 0 lets it shrink instead.The intrinsic (Every Layout) version — no fixed breakpoint
The classic Every Layout Sidebar recipe uses flexbox with flex-wrap and a flex-basis calculation so the sidebar collapses to full width automatically once the container gets too narrow to hold the sidebar's minimum width plus the fluid column's minimum width — no @media query at all.
.sidebar-layout {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.sidebar-layout > .sidebar {
flex-basis: 240px;
flex-grow: 1;
}
.sidebar-layout > .content {
flex-basis: 0;
flex-grow: 999; /* wins almost all the growth, staying "the main column" */
min-width: 60%; /* the threshold below which content wraps to its own row */
}The lopsided
flex-growvalues (1vs999) mean the content column claims essentially all extra space while the sidebar only grows if there is truly nothing else competing for room.min-width: 60%on.contentis the real trigger: once the container is too narrow for the content column to have 60% of it and the sidebar its 240px, flexbox wraps the sidebar onto its own line.There is no media query anywhere in this recipe — the breakpoint is a function of the sidebar's own declared width, so it "just works" inside any container, including a narrower parent than the whole viewport.
Collapsible sidebar (checkbox / JS-light toggle)
For an app shell where the sidebar should be dismissible (docs sites, dashboards), a hidden checkbox plus sibling selectors gets you a toggle with zero JavaScript for the visual state — only a <label> click driving native checkbox behavior.
<input type="checkbox" id="sidebar-toggle" class="sr-only" /> <label for="sidebar-toggle" class="toggle-btn">☰</label> <div class="app-shell"> <aside class="sidebar">Navigation</aside> <main class="content">Page content</main> </div>
.app-shell {
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
transition: grid-template-columns 0.2s ease;
}
#sidebar-toggle:checked ~ .app-shell {
grid-template-columns: 0px minmax(0, 1fr);
}
#sidebar-toggle:checked ~ .app-shell .sidebar {
overflow: hidden;
padding: 0;
}~ general sibling combinator (see the Combinators page) to reach it — this is the same trick used for pure-CSS accordions and tab panels.Responsive breakpoint collapse (media-query version)
When the intrinsic wrap-based approach isn't granular enough — say, the sidebar should become a bottom drawer or an off-canvas panel rather than simply stacking above the content — a plain media query is the more predictable tool.
.app-shell {
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
gap: 1.5rem;
}
@media (max-width: 768px) {
.app-shell {
grid-template-columns: minmax(0, 1fr);
}
.sidebar {
position: fixed;
inset-block: 0;
inset-inline-start: 0;
transform: translateX(-100%);
transition: transform 0.2s ease;
}
.sidebar.is-open {
transform: translateX(0);
}
}Sticky sidebar
.sidebar {
position: sticky;
top: 1.5rem;
align-self: start; /* prevents grid stretch from cancelling out sticky */
max-height: calc(100dvh - 3rem);
overflow-y: auto;
}align-self: start is easy to forget: by default a grid item stretches to fill its row's height, and a stretched element has nowhere left to "stick" as you scroll — it's already as tall as its track. See the position: sticky page for the full mechanics.Flexbox vs intrinsic vs media-query — choosing
Approach | Breakpoint driven by | Best for |
|---|---|---|
Grid (fixed | Never collapses on its own | Layouts that should always show both columns (desktop-only tools) |
Intrinsic flex-wrap (Every Layout) | The content's own minimum width | Reusable components dropped into unpredictable containers |
Media query | A fixed viewport width you choose | App shells needing an off-canvas/drawer transformation, not just stacking |
Related pages: Holy Grail Layout, Sticky Footer Patterns, The Switcher Layout, and position: sticky.