SolutionsCase StudiesAI ToolsResourcesAboutContact
Get Your Free AI Automation Audit Book a Free 30-Minute Strategy Call
Playground~/frontend Open editor

~/css/sidebar-layouts

7 CSS Sidebar Layouts

5 Pure CSS2 with JSPublished 2026-10-05Free · no sign-up

Seven sidebar layouts: a fixed filter sidebar beside fluid content, a sidebar that collapses to an icon rail, a right-hand aside, a flexbox sidebar that decides when to stack, an off-canvas sidebar for small screens, a three-part docs layout and a feed with sidebars on both sides.

01. Fixed Sidebar and Fluid Main

SidebarGrid

A fixed-width sidebar beside a main area that takes all the remaining space: grid-template-columns: 180px minmax(0, 1fr). The minmax(0, …) matters, because without it a wide table or long URL in the main area would push the layout off screen.

View code
<div class="sbl1"><div class="in"><aside><b>Filters</b><label><input type="checkbox" checked> In stock</label><label><input type="checkbox"> On sale</label></aside><main><p>32 products</p><div class="g"><i></i><i></i><i></i><i></i></div></main></div></div>
.sbl1 { width: 580px; max-width: 100%; container-type: inline-size; font: 13px Inter, system-ui, sans-serif; }
.sbl1 .in { display: grid; gap: 14px; }
.sbl1 aside { display: grid; gap: 8px; align-content: start; padding: 14px; border-radius: 12px; background: #f2f4f7; color: #344054; }
.sbl1 aside b { color: #101828; }
.sbl1 label { display: flex; gap: 6px; align-items: center; }
.sbl1 main p { margin: 0 0 8px; color: #475467; }
.sbl1 .g { display: grid; grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); gap: 8px; }
.sbl1 .g i { aspect-ratio: 1; border-radius: 10px; background: #e0e7ff; }
@container (min-width: 440px) { .sbl1 .in { grid-template-columns: 160px minmax(0, 1fr); } }

02. Collapsible Icon Sidebar

SidebarToggle

A sidebar that collapses to an icon rail and expands to show labels. The toggle is a button with aria-expanded, the labels stay in the DOM as visually hidden text when collapsed so each icon link keeps its name, and the width transition is on a grid column.

View code
<div class="sbl2"><nav aria-label="App"><button aria-expanded="true" aria-label="Collapse sidebar">⟨</button><a href="#home" aria-current="page"><span aria-hidden="true">⌂</span><span class="l">Home</span></a><a href="#inbox"><span aria-hidden="true">✉</span><span class="l">Inbox</span></a><a href="#files"><span aria-hidden="true">▤</span><span class="l">Files</span></a></nav><main>Main content</main></div>
.sbl2 { display: grid; grid-template-columns: auto 1fr; width: 480px; max-width: 100%; height: 240px; border-radius: 14px; overflow: hidden; background: #0f172a; font: 14px Inter, system-ui, sans-serif; }
.sbl2 nav { display: grid; align-content: start; gap: 4px; width: 150px; padding: 10px; background: #111827; transition: width .3s ease; }
.sbl2.mini nav { width: 52px; }
.sbl2 button { justify-self: end; width: 32px; height: 32px; border: 0; border-radius: 8px; background: #1f2937; color: #e5e7eb; cursor: pointer; }
.sbl2 a { display: flex; align-items: center; gap: 10px; padding: 8px; border-radius: 8px; color: #9ca3af; text-decoration: none; white-space: nowrap; overflow: hidden; }
.sbl2 a[aria-current] { background: #1f2937; color: #fff; }
.sbl2 a span:first-child { flex: none; width: 18px; text-align: center; }
.sbl2.mini .l { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.sbl2 main { padding: 16px; color: #94a3b8; }
.sbl2 :focus-visible { outline: 2px solid #93c5fd; outline-offset: 1px; }
@media (prefers-reduced-motion: reduce) { .sbl2 nav { transition: none; } }
var w = document.querySelector('.sbl2'), b = w.querySelector('button');
b.onclick = function () { var mini = w.classList.toggle('mini'); b.setAttribute('aria-expanded', !mini); b.setAttribute('aria-label', mini ? 'Expand sidebar' : 'Collapse sidebar'); b.textContent = mini ? '⟩' : '⟨'; };

03. Content with Right Aside

SidebarArticle

An article with related links in a right-hand aside, which drops below the article on narrow containers. The aside is complementary content, so it uses the aside element with a heading, and it comes after the article in the source.

View code
<div class="sbl3"><div class="in"><article><h3>Packing for a week with one bag</h3><p>Roll, don't fold. Pick two colours that go together. Wear the bulky shoes.</p></article><aside aria-labelledby="sbl3h"><h4 id="sbl3h">Related</h4><ul><li><a href="#r1">Carry-on size guide</a></li><li><a href="#r2">Our travel kit list</a></li></ul></aside></div></div>
.sbl3 { width: 580px; max-width: 100%; container-type: inline-size; font: 14px/1.6 Inter, system-ui, sans-serif; }
.sbl3 .in { display: grid; gap: 14px; }
.sbl3 article { color: #344054; } .sbl3 h3 { margin: 0 0 6px; color: #101828; } .sbl3 p { margin: 0; }
.sbl3 aside { padding: 14px; border-left: 3px solid #f79009; background: #fffaeb; }
.sbl3 h4 { margin: 0 0 6px; color: #93370d; font-size: 13px; text-transform: uppercase; letter-spacing: .05em; }
.sbl3 ul { margin: 0; padding-left: 18px; } .sbl3 a { color: #b54708; }
.sbl3 a:focus-visible { outline: 2px solid #b54708; outline-offset: 2px; }
@container (min-width: 460px) { .sbl3 .in { grid-template-columns: minmax(0, 1fr) 170px; gap: 24px; } }

04. Intrinsic Sidebar with Flexbox

SidebarFlexbox

A sidebar layout that decides for itself when to stack: the sidebar has a fixed basis, the main area has flex-grow: 999 and a minimum of half the container, and flex-wrap does the rest. When the main area would drop below 50 percent, it wraps.

View code
<div class="sbl4"><aside>Sidebar · 160px</aside><main>Main · grows, min 50%</main></div>
.sbl4 { display: flex; flex-wrap: wrap; gap: 12px; width: 560px; max-width: 100%; font: 700 13px "JetBrains Mono", ui-monospace, monospace; }
.sbl4 aside { flex-basis: 160px; flex-grow: 1; padding: 30px 14px; border-radius: 12px; background: #312e81; color: #c7d2fe; text-align: center; }
.sbl4 main { flex-basis: 0; flex-grow: 999; min-inline-size: 50%; padding: 30px 14px; border-radius: 12px; background: #1e293b; color: #e2e8f0; text-align: center; }

05. Off-Canvas Sidebar on Small Screens

SidebarResponsive

On wide containers the sidebar sits beside the content; on narrow ones it is hidden off to the side and slides in over the content when the Menu button is pressed. When closed it is inert, so keyboard users never tab into links they cannot see.

View code
<div class="sbl5"><div class="in"><button class="mb" aria-expanded="false" aria-controls="sbl5n">Menu</button><nav id="sbl5n" aria-label="Sections"><a href="#a">Overview</a><a href="#b">Billing</a><a href="#c">Team</a></nav><main><h3>Overview</h3><p>Your account at a glance.</p></main></div></div>
.sbl5 { width: 560px; max-width: 100%; container-type: inline-size; font: 14px Inter, system-ui, sans-serif; }
.sbl5 .in { position: relative; display: grid; grid-template-columns: 150px 1fr; gap: 14px; min-height: 220px; padding: 12px; border: 1px solid #e4e7ec; border-radius: 14px; background: #fff; overflow: hidden; }
.sbl5 nav { display: grid; align-content: start; gap: 4px; }
.sbl5 nav a { padding: 8px 10px; border-radius: 8px; color: #344054; text-decoration: none; } .sbl5 nav a:hover { background: #f2f4f7; }
.sbl5 .mb { display: none; }
.sbl5 h3 { margin: 0 0 4px; color: #101828; } .sbl5 p { margin: 0; color: #475467; }
.sbl5 :focus-visible { outline: 3px solid #84adff; outline-offset: 1px; }
@container (max-width: 439px) {
  .sbl5 .in { grid-template-columns: 1fr; }
  .sbl5 .mb { display: block; justify-self: start; padding: 8px 12px; border: 1px solid #d0d5dd; border-radius: 8px; background: #fff; font: 600 13px Inter, system-ui, sans-serif; cursor: pointer; }
  .sbl5 nav { position: absolute; top: 0; bottom: 0; left: 0; width: 160px; padding: 56px 10px 10px; background: #f9fafb; box-shadow: 4px 0 16px -8px rgba(0,0,0,.3); transform: translateX(-105%); transition: transform .3s ease; z-index: 1; }
  .sbl5 nav.open { transform: none; }
  .sbl5 .mb { position: relative; z-index: 2; }
}
@media (prefers-reduced-motion: reduce) { .sbl5 nav { transition: none !important; } }
var b = document.querySelector('.sbl5 .mb'), n = document.getElementById('sbl5n');
function sync() { var small = getComputedStyle(b).display !== 'none'; n.inert = small && !n.classList.contains('open'); }
b.onclick = function () { var o = n.classList.toggle('open'); b.setAttribute('aria-expanded', o); sync(); };
new ResizeObserver(sync).observe(document.querySelector('.sbl5'));

06. Docs Layout with Nav and Contents

SidebarDocs

The three-part documentation layout: section navigation on the left, the page in the middle and an on-this-page list on the right. The right column disappears first as space shrinks, then the left one moves above the content.

View code
<div class="sbl6"><div class="in"><nav aria-label="Docs"><b>Guides</b><a href="#install">Install</a><a href="#theme" aria-current="page">Theming</a><a href="#deploy">Deploy</a></nav><article><h3>Theming</h3><p>Every colour is a custom property you can override.</p></article><aside aria-label="On this page"><b>On this page</b><a href="#tokens">Tokens</a><a href="#dark">Dark mode</a></aside></div></div>
.sbl6 { width: 600px; max-width: 100%; container-type: inline-size; font: 13px/1.6 Inter, system-ui, sans-serif; }
.sbl6 .in { display: grid; gap: 14px; padding: 14px; border-radius: 14px; background: #0f172a; }
.sbl6 nav, .sbl6 aside { display: grid; align-content: start; gap: 2px; }
.sbl6 b { color: #64748b; font-size: 11px; text-transform: uppercase; letter-spacing: .08em; }
.sbl6 a { color: #94a3b8; text-decoration: none; } .sbl6 a[aria-current] { color: #38bdf8; font-weight: 600; }
.sbl6 a:focus-visible { outline: 2px solid #38bdf8; outline-offset: 2px; }
.sbl6 h3 { margin: 0 0 4px; color: #f8fafc; } .sbl6 article p { margin: 0; color: #cbd5e1; }
.sbl6 aside { display: none; }
@container (min-width: 420px) { .sbl6 .in { grid-template-columns: 110px minmax(0, 1fr); } }
@container (min-width: 560px) { .sbl6 .in { grid-template-columns: 110px minmax(0, 1fr) 110px; } .sbl6 aside { display: grid; } }

07. Sidebars on Both Sides

SidebarThree column

A social-feed style layout with navigation on the left, the feed in the middle and suggestions on the right, all on one grid. The middle column has a maximum readable width with minmax(0, 520px), and the side columns share whatever is left.

View code
<div class="sbl7"><div class="in"><nav aria-label="Main">Nav</nav><main>Feed</main><aside aria-label="Suggestions">Suggestions</aside></div></div>
.sbl7 { width: 600px; max-width: 100%; container-type: inline-size; font: 700 13px Inter, system-ui, sans-serif; }
.sbl7 .in { display: grid; gap: 10px; }
.sbl7 .in > * { display: grid; place-items: center; min-height: 60px; border-radius: 12px; }
.sbl7 nav { background: #ecfdf3; color: #054f31; } .sbl7 main { min-height: 180px; background: #f2f4f7; color: #344054; } .sbl7 aside { background: #eef4ff; color: #1e3a8a; }
@container (min-width: 520px) { .sbl7 .in { grid-template-columns: minmax(80px, 1fr) minmax(0, 520px) minmax(80px, 1fr); } .sbl7 nav, .sbl7 aside { min-height: 180px; } }

About these CSS Sidebar Layouts

Fixed plus fluid

grid-template-columns: 180px minmax(0, 1fr) gives a fixed sidebar and a main area that takes the rest without overflowing. The minmax matters when the main area holds tables or long words.

Collapsed does not mean nameless

An icon rail still needs names. Keep each label in the DOM as visually hidden text when the sidebar collapses, and give the toggle aria-expanded.

Hide off-canvas content properly

A sidebar slid off screen is still in the tab order unless you remove it. The inert attribute takes the whole panel out of focus and the accessibility tree while it is closed.

Let the layout decide

With flexbox, a sidebar with a fixed basis and a main area with a large flex-grow and a minimum width will stack by itself when space runs out, no breakpoint required.

Frequently asked questions

Left or right sidebar?

Navigation usually goes left; related or supplementary content goes right.

Should the sidebar be sticky?

For long pages, often yes. See the sticky elements collection.

Is aside the right element for a sidebar?

For complementary content, yes. A sidebar of site navigation is a nav.