30 Tailwind CSS Sidebar Layouts

29 Pure Tailwind1 Tailwind + JSPublished

30 Tailwind CSS sidebar layouts for SaaS dashboard shells, admin consoles, documentation trees, and webmail two-pane inboxes — spanning fixed and sticky rails, collapse-to-icon and off-canvas drawers, dual-panel and three-pane workspaces, nested <details> file trees, and floating glassmorphism panels. Scoped under .tsl-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.

Related30 CSS Sidebar Layouts16 CSS Two-Column Layouts17 CSS Dashboard Layouts14 Tailwind CSS Wave Section Dividers

Premium template pickPartner: Cruip

Affiliate link

Building the whole admin dashboard, not just this layout?

You just browsed 30 Tailwind sidebar layouts. Mosaic by Cruip is a complete Tailwind CSS admin dashboard template, coded in HTML, React, Next.js, Vue and Laravel, with a Figma version too. It costs $69.

View Mosaic dashboard

Mosaic by Cruip. We may earn a commission, at no extra cost to you.

01. Tailwind SaaS Dashboard Sidebar with Native Dark Mode Switch (opens in a new tab)

Published

Pure Tailwind
The 2027 SaaS shell in one file: brand, nav, user badge and a real light/dark switch that re-skins the ENTIRE app from a single checkbox. The port's win is that the theme flip gets simpler in v4 — every utility already compiles to var(--color-tsl01-*), so one scoped rule re-points the tokens and the whole shell follows without a single conditional class.
Newsletter

Enjoying these demos? Get new ones by email.

A short email when a new collection ships. Unsubscribe any time.

at

Almost there: check your inbox to confirm.Manage

Newsletter

Enjoying these demos? Get new ones by email.

A short email when a new collection ships. Unsubscribe any time.

at

Almost there: check your inbox to confirm.Manage

Newsletter

Enjoying these demos? Get new ones by email.

A short email when a new collection ships. Unsubscribe any time.

at

Almost there: check your inbox to confirm.Manage

FAQ

Frequently asked questions

How do I build a collapsible Tailwind sidebar with no JavaScript?
Demo 08 holds the open/closed state in a visually hidden <input type="checkbox"> placed before the rail in the DOM. A <label> with a matching for toggles it, and Tailwind's has-checked: variant reads that state from an ancestor — has-checked:w-16 shrinks the rail, has-checked:opacity-0 hides the labels. No click handler, no state library. The rule that trips people up: has-checked: compiles to :has(:checked), which only matches inside the element's own subtree, so the checkbox must sit in the layout root where the styled nodes can see it — not buried inside a card. Pair the width change with transition-[width] so the fold eases instead of snapping, and keep the checkbox off-screen with sr-only rather than hidden, since a fully hidden input can't take focus for keyboard users.
How do I keep the sidebar collapsed state after a page refresh?
Demo 20 stores one value in localStorage and drives every dimension from a single custom property. The rail's width is --w, applied with an arbitrary value like w-[var(--w)], and a data-state attribute on the root switches --w between the expanded and collapsed sizes. The toggle writes the new state back to storage. Because all geometry flows from one variable, padding, label opacity and icon centring key off the same attribute instead of a dozen hardcoded widths. The common bug is a flash of the wrong width: if you read localStorage after hydration, the first paint shows the default rail, then it jumps. Fix it by setting data-state in a small blocking inline script in the <head>, before the body renders, so the very first paint already matches the stored preference.
How do I make the content scroll independently while the sidebar stays fixed?
Demo 09 is the base shell: the layout root is a flex row at h-screen, the rail is a fixed-width column, and the main pane gets flex-1 overflow-y-auto. The rail never scrolls with the page because the whole shell is pinned to the viewport height and only the content column owns the overflow. Two things break this. First, forgetting min-h-0 on the scrolling child — flex items default to min-height: auto, which refuses to shrink below their content, so the pane grows the page instead of scrolling inside it. Second, putting overflow on the wrong element. Keep the height cap on the root, let the rail size naturally, and scope overflow-y-auto to the content column only. If the rail also carries a long menu, give it its own overflow-y-auto so the two panes scroll independently.
Why is my sticky sidebar not sticking as I scroll?
Demo 07 uses sticky top-0, and it fails for two predictable reasons. A position: sticky element only travels within its parent's box, so if the parent is no taller than the sidebar there's no room to move and nothing appears to stick — the sidebar's column needs to be the short one beside a tall article that supplies the height. The second killer is overflow: hidden or overflow: auto on any ancestor up to the scroll root: it silently creates a scroll container that clips sticky positioning. Walk every wrapper and remove stray overflow. You also need a real offset like top-0, because sticky with no threshold never engages. Demo 07 also caps the rail with max-h-screen plus its own overflow-y-auto, so a long table of contents scrolls inside the sticky pane rather than overflowing past the viewport.
How do I keep an icon-only collapsed rail accessible?
When labels disappear in the collapsed rail (demos 02, 06, 14) each link becomes an unlabelled icon, so add aria-label to every control and mark the decorative glyph with aria-hidden="true". The hover tooltips are a visual nicety, not an accessibility feature — keyboard and screen-reader users never fire hover, so the aria-label is what actually announces each destination. Keep targets at least 44px (demo 14 pins them there) so they stay tappable. Mark the active page with aria-current="page", never colour alone. If the collapse is a real button, give it aria-expanded reflecting the open state and aria-controls pointing at the rail. And never strip the focus ring in the collapsed state — a Tab user needs to see which icon is focused when there's no text beside it, and focus-visible: keeps it from showing on mouse clicks.
How do I switch a sidebar to a bottom navigation bar on mobile?
Demo 04 renders one <nav> and restyles it at the breakpoint rather than shipping two markup blocks. Below md it's a fixed bottom bar — fixed bottom-0 inset-x-0 flex with items spread evenly; at md and up those classes flip to a vertical column pinned left. A single <nav> means one source of truth for the links and no duplicated ARIA to drift out of sync. Two details matter on phones: add pb-[env(safe-area-inset-bottom)] so the bar clears the iOS home indicator, and give the main content matching bottom padding so the fixed bar never covers the last row. Labels drop to icon-plus-caption at the bottom size. Don't try to animate the layout switch — it's a hard breakpoint swap, and transitioning between a fixed bottom bar and a flex column just produces jank with no payoff.
Should I use the CSS resize property or container queries for a resizable sidebar?
They solve different halves of the problem. Demo 27 makes the rail user-draggable with resize-x plus overflow-auto and a min-w/max-w clamp — the browser draws the handle and does the width maths, with no pointer listeners or drag state. What it does not do is change what's inside as the width changes. That's demo 29's job: an @container query makes the nav respond to its own width, so labels hide and icons centre once the rail drops below a threshold, independent of the viewport. Combine them — resize-x for the drag, a container query for the adaptive contents — and the rail both resizes and reflows. The gotcha with resize: it only shows a handle when overflow is not visible, and it's mouse-only, so treat it as an enhancement, never your mobile story.
When should I avoid a fixed sidebar or off-canvas drawer?
A permanent fixed rail (demos 09, 11) costs 240px-plus of horizontal space — fine on a dashboard, wrong on a content site read mostly on phones, where you should collapse to a drawer or the bottom-bar pattern below md. The off-canvas overlay drawers (demos 10, 19) are modal: they trap the page behind a scrim, so don't use them for primary navigation a user needs while reading — a push-content drawer (demo 18) or a persistent rail keeps context visible. Reserve the frosted floating showpieces (demos 16, 30) for marketing shells; heavy backdrop-blur plus backdrop-saturate is a genuine paint cost over long scrolling lists and on low-end devices. And skip the pure-CSS :target tree (demo 23) when a link must survive a refresh or deep-link — :target writes to the URL hash and will hijack the back button in ways users don't expect.

Related collections

15 CSS Aspect Ratio Demos preview

15 CSS Aspect Ratio Demos

15 hand-coded CSS aspect-ratio demos for video embeds, product galleries, IAB ad slots, native dialogs, and CLS-safe placeholders: 16:9 iframe YouTube embed with click-to-load facade + up-next rail, 21:9 full-screen hero video with min-height/max-height:100svh guardrails + Ken Burns drift, 1:1 Instagram-style square grid with 2×2 feature tile, 4:3 magazine card image cover, 9:16 vertical stories rail (TikTok/Reels/Shorts pattern) with scroll-snap + segment bars, 4:5 apparel product image gallery with radio-driven state + 1:1 thumbnails, 1:1 zoom thumbnail carousel with pointer-tracked --zx/--zy magnifier, prevent-layout-shift placeholder with live PerformanceObserver CLS meter (before/after side-by-side lab), dynamic content fallback with three policies (bend/strict/auto) via :has() toggle, IAB ad banner slots (728×90 leaderboard, 300×250 medium rectangle, 300×600 half-page, 320×50 mobile) with skeletons + container-query mobile swap, responsive modal dialog sized min(92vw, 88svh×16/9, 1080px) with @starting-style animation, responsive OpenStreetMap iframe wrapper with 16:9 → 1:1 container-query narrow swap, media query orientation live HUD + resize:both container-ratio playground, object-fit logo cloud with contain/cover/fill switcher via :has(), and side-by-side padding-top hack (height:0 + padding-top:56.25%) → modern aspect-ratio migration comparison with live ratio picker. 11 truly Pure CSS + 4 with a tiny optional vanilla JS snippet (facade swap, pointer magnifier, CLS meter, native dialog). Every demo is scoped under a unique .car-NN prefix so it drops into any project without CSS collisions, ships prefers-reduced-motion guards, and is framework-agnostic (works as-is in React, Vue, Svelte, Astro, Next.js, Remix, or plain HTML).

6 CSS Bento Grid Layouts preview

6 CSS Bento Grid Layouts

6 production CSS bento grid layouts with 12 hand-coded designs — Apple-style product showcase, SaaS feature value-prop matrix, analytics dashboard overview, creative portfolio, e-commerce category hub, and link-in-bio social hub. Each topic ships 2 sub-variants side-by-side so visitors see both a keynote aesthetic and a paper-doc variant at once. Container queries, CSS Grid, zero dependencies, copy-paste ready.

20 CSS Blog Layouts preview

20 CSS Blog Layouts

20 hand-coded CSS blog and editorial layouts for magazine homepages, news sites, personal archives, newsletter back-issues, recipe and podcast blogs, developer tutorials, and long-form journalism. Covers a magazine homepage with hero plus editor-picks rail, a news homepage with breaking-news ticker, blog archives with sticky year separators, Substack-style issue-numbered archives, recipe card grids with prep-time badges, podcast episode lists with waveforms, long-form articles with scroll-driven reading progress, drop caps and floated pull quotes via first-letter, Medium-style 65ch centred reader layouts, dev tutorials with a sticky code panel beside prose, interview transcripts with alternating speakers, case-study pages with stat counters, video blogs with an episode rail, full-bleed photo essays, news articles with sticky related-stories sidebars, documentation pages with prev/next chapter nav, a standalone blog post card, a scroll-snap category filter bar, an inline newsletter callout that breaks out of the prose column, and a horizontal featured-post rail. 12 are pure CSS with zero JavaScript. Every layout is scoped under a .bl-NN prefix for no-collision pasting, guards prefers-reduced-motion, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.

Search CodeFronts

Loading…