15 CSS Flexbox Layouts 05 / 15
CSS Flexbox Sidebar Dashboard Layout
A full app-shell dashboard with a fixed-width flex sidebar, collapsible nav groups, top header bar, stat cards row, and a main content area — all wired with flexbox.
The code
<div class="fl-05">
<div class="fl-05__shell">
<!-- Sidebar -->
<aside class="fl-05__sidebar">
<div class="fl-05__sidebar-top">
<div class="fl-05__workspace-icon">F</div>
<div>
<div class="fl-05__workspace-name">FlexBoard</div>
<div class="fl-05__workspace-plan">Pro Plan</div>
</div>
</div>
<nav class="fl-05__sidebar-nav">
<div class="fl-05__nav-section">Main</div>
<div class="fl-05__nav-item is-active">
<div class="fl-05__nav-dot" style="background:#3b82f6"></div>
Dashboard
</div>
<div class="fl-05__nav-item">
<div class="fl-05__nav-dot" style="background:#8b5cf6"></div>
Analytics
<span class="fl-05__nav-count">12</span>
</div>
<div class="fl-05__nav-item">
<div class="fl-05__nav-dot" style="background:#22c55e"></div>
Projects
</div>
<div class="fl-05__nav-item">
<div class="fl-05__nav-dot" style="background:#f97316"></div>
Tasks
<span class="fl-05__nav-count is-hot">3</span>
</div>
<div class="fl-05__nav-section">Settings</div>
<div class="fl-05__nav-item">
<div class="fl-05__nav-dot" style="background:#7d8590"></div>
Members
</div>
<div class="fl-05__nav-item">
<div class="fl-05__nav-dot" style="background:#7d8590"></div>
Billing
</div>
</nav>
<div class="fl-05__sidebar-bottom">
<div class="fl-05__user-row">
<div class="fl-05__user-avatar">JD</div>
<div>
<div class="fl-05__user-name">Jane Doe</div>
<div class="fl-05__user-role">Admin</div>
</div>
</div>
</div>
</aside>
<!-- Main -->
<main class="fl-05__main">
<div class="fl-05__topbar">
<div class="fl-05__topbar-title">Dashboard Overview</div>
<div class="fl-05__topbar-action fl-05__topbar-action--ghost">⬇ Export</div>
<div class="fl-05__topbar-action fl-05__topbar-action--primary">+ New Project</div>
</div>
<div class="fl-05__content">
<div class="fl-05__stats">
<div class="fl-05__stat">
<div class="fl-05__stat-label">Total Revenue</div>
<div class="fl-05__stat-value">$48.2k</div>
<div class="fl-05__stat-delta up">↑ 12.5% this month</div>
</div>
<div class="fl-05__stat">
<div class="fl-05__stat-label">Active Users</div>
<div class="fl-05__stat-value">2,841</div>
<div class="fl-05__stat-delta up">↑ 8.1% this week</div>
</div>
<div class="fl-05__stat">
<div class="fl-05__stat-label">Open Tasks</div>
<div class="fl-05__stat-value">34</div>
<div class="fl-05__stat-delta down">↓ 3 from yesterday</div>
</div>
</div>
<div class="fl-05__activity">
<div class="fl-05__activity-head">
Recent Activity
<span class="fl-05__activity-view">View all</span>
</div>
<div class="fl-05__activity-row">
<div class="fl-05__activity-dot" style="background:#22c55e"></div>
<div class="fl-05__activity-text">Deployment to production succeeded</div>
<div class="fl-05__activity-time">2m ago</div>
</div>
<div class="fl-05__activity-row">
<div class="fl-05__activity-dot" style="background:#3b82f6"></div>
<div class="fl-05__activity-text">New member <strong style="color:#e6edf3">@alex</strong> joined the workspace</div>
<div class="fl-05__activity-time">14m ago</div>
</div>
<div class="fl-05__activity-row">
<div class="fl-05__activity-dot" style="background:#f97316"></div>
<div class="fl-05__activity-text">Task "CSS Flexbox docs" moved to Review</div>
<div class="fl-05__activity-time">1h ago</div>
</div>
<div class="fl-05__activity-row">
<div class="fl-05__activity-dot" style="background:#ef4444"></div>
<div class="fl-05__activity-text">Build #142 failed — check logs</div>
<div class="fl-05__activity-time">3h ago</div>
</div>
</div>
</div>
</main>
</div>
</div> <div class="fl-05">
<div class="fl-05__shell">
<!-- Sidebar -->
<aside class="fl-05__sidebar">
<div class="fl-05__sidebar-top">
<div class="fl-05__workspace-icon">F</div>
<div>
<div class="fl-05__workspace-name">FlexBoard</div>
<div class="fl-05__workspace-plan">Pro Plan</div>
</div>
</div>
<nav class="fl-05__sidebar-nav">
<div class="fl-05__nav-section">Main</div>
<div class="fl-05__nav-item is-active">
<div class="fl-05__nav-dot" style="background:#3b82f6"></div>
Dashboard
</div>
<div class="fl-05__nav-item">
<div class="fl-05__nav-dot" style="background:#8b5cf6"></div>
Analytics
<span class="fl-05__nav-count">12</span>
</div>
<div class="fl-05__nav-item">
<div class="fl-05__nav-dot" style="background:#22c55e"></div>
Projects
</div>
<div class="fl-05__nav-item">
<div class="fl-05__nav-dot" style="background:#f97316"></div>
Tasks
<span class="fl-05__nav-count is-hot">3</span>
</div>
<div class="fl-05__nav-section">Settings</div>
<div class="fl-05__nav-item">
<div class="fl-05__nav-dot" style="background:#7d8590"></div>
Members
</div>
<div class="fl-05__nav-item">
<div class="fl-05__nav-dot" style="background:#7d8590"></div>
Billing
</div>
</nav>
<div class="fl-05__sidebar-bottom">
<div class="fl-05__user-row">
<div class="fl-05__user-avatar">JD</div>
<div>
<div class="fl-05__user-name">Jane Doe</div>
<div class="fl-05__user-role">Admin</div>
</div>
</div>
</div>
</aside>
<!-- Main -->
<main class="fl-05__main">
<div class="fl-05__topbar">
<div class="fl-05__topbar-title">Dashboard Overview</div>
<div class="fl-05__topbar-action fl-05__topbar-action--ghost">⬇ Export</div>
<div class="fl-05__topbar-action fl-05__topbar-action--primary">+ New Project</div>
</div>
<div class="fl-05__content">
<div class="fl-05__stats">
<div class="fl-05__stat">
<div class="fl-05__stat-label">Total Revenue</div>
<div class="fl-05__stat-value">$48.2k</div>
<div class="fl-05__stat-delta up">↑ 12.5% this month</div>
</div>
<div class="fl-05__stat">
<div class="fl-05__stat-label">Active Users</div>
<div class="fl-05__stat-value">2,841</div>
<div class="fl-05__stat-delta up">↑ 8.1% this week</div>
</div>
<div class="fl-05__stat">
<div class="fl-05__stat-label">Open Tasks</div>
<div class="fl-05__stat-value">34</div>
<div class="fl-05__stat-delta down">↓ 3 from yesterday</div>
</div>
</div>
<div class="fl-05__activity">
<div class="fl-05__activity-head">
Recent Activity
<span class="fl-05__activity-view">View all</span>
</div>
<div class="fl-05__activity-row">
<div class="fl-05__activity-dot" style="background:#22c55e"></div>
<div class="fl-05__activity-text">Deployment to production succeeded</div>
<div class="fl-05__activity-time">2m ago</div>
</div>
<div class="fl-05__activity-row">
<div class="fl-05__activity-dot" style="background:#3b82f6"></div>
<div class="fl-05__activity-text">New member <strong style="color:#e6edf3">@alex</strong> joined the workspace</div>
<div class="fl-05__activity-time">14m ago</div>
</div>
<div class="fl-05__activity-row">
<div class="fl-05__activity-dot" style="background:#f97316"></div>
<div class="fl-05__activity-text">Task "CSS Flexbox docs" moved to Review</div>
<div class="fl-05__activity-time">1h ago</div>
</div>
<div class="fl-05__activity-row">
<div class="fl-05__activity-dot" style="background:#ef4444"></div>
<div class="fl-05__activity-text">Build #142 failed — check logs</div>
<div class="fl-05__activity-time">3h ago</div>
</div>
</div>
</div>
</main>
</div>
</div>.fl-05, .fl-05 *, .fl-05 *::before, .fl-05 *::after {
margin: 0; padding: 0; box-sizing: border-box;
}
.fl-05 ::selection { background: #3b82f6; color: #fff; }
.fl-05 {
--bg: #0d1117;
--sidebar: #161b22;
--surface: #1c2128;
--border: #30363d;
--accent: #3b82f6;
--accent2: #8b5cf6;
--green: #22c55e;
--orange: #f97316;
--red: #ef4444;
--text: #e6edf3;
--muted: #7d8590;
font-family: 'Plus Jakarta Sans', sans-serif;
background: var(--bg);
border-radius: 16px;
overflow: hidden;
min-height: 500px;
}
/* Outer flex row: sidebar + main */
.fl-05__shell {
display: flex;
height: 500px;
}
/* ── Sidebar ── */
.fl-05__sidebar {
width: 220px;
flex-shrink: 0;
background: var(--sidebar);
border-right: 1px solid var(--border);
display: flex;
flex-direction: column;
padding: 0;
}
.fl-05__sidebar-top {
padding: 20px 16px 12px;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 10px;
}
.fl-05__workspace-icon {
width: 32px;
height: 32px;
border-radius: 8px;
background: linear-gradient(135deg, #3b82f6, #8b5cf6);
display: flex;
align-items: center;
justify-content: center;
font-size: 0.8rem;
font-weight: 800;
color: #fff;
flex-shrink: 0;
}
.fl-05__workspace-name {
font-size: 0.82rem;
font-weight: 700;
color: var(--text);
}
.fl-05__workspace-plan {
font-size: 0.65rem;
color: var(--accent);
font-weight: 600;
}
.fl-05__sidebar-nav {
flex: 1;
padding: 12px 8px;
display: flex;
flex-direction: column;
gap: 2px;
overflow-y: auto;
}
.fl-05__nav-section {
font-size: 0.6rem;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--muted);
padding: 10px 8px 4px;
}
.fl-05__nav-item {
display: flex;
align-items: center;
gap: 10px;
padding: 7px 10px;
border-radius: 6px;
cursor: pointer;
font-size: 0.8rem;
font-weight: 500;
color: var(--muted);
transition: all 0.15s;
position: relative;
}
.fl-05__nav-item:hover { background: rgba(255,255,255,0.06); color: var(--text); }
.fl-05__nav-item.is-active {
background: rgba(59,130,246,0.15);
color: var(--accent);
font-weight: 600;
}
.fl-05__nav-item.is-active::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 3px;
height: 60%;
background: var(--accent);
border-radius: 0 2px 2px 0;
}
.fl-05__nav-dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.fl-05__nav-count {
margin-left: auto;
font-size: 0.65rem;
font-weight: 700;
background: rgba(255,255,255,0.08);
padding: 1px 6px;
border-radius: 10px;
color: var(--muted);
}
.fl-05__nav-count.is-hot { background: var(--red); color: #fff; }
.fl-05__sidebar-bottom {
padding: 12px 8px;
border-top: 1px solid var(--border);
}
.fl-05__user-row {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 10px;
border-radius: 8px;
cursor: pointer;
transition: background 0.15s;
}
.fl-05__user-row:hover { background: rgba(255,255,255,0.06); }
.fl-05__user-avatar {
width: 28px;
height: 28px;
border-radius: 50%;
background: linear-gradient(135deg, #f97316, #ef4444);
font-size: 0.7rem;
font-weight: 800;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.fl-05__user-name {
font-size: 0.78rem;
font-weight: 600;
color: var(--text);
}
.fl-05__user-role {
font-size: 0.65rem;
color: var(--muted);
}
/* ── Main panel ── */
.fl-05__main {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.fl-05__topbar {
height: 52px;
background: var(--sidebar);
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
padding: 0 20px;
gap: 12px;
flex-shrink: 0;
}
.fl-05__topbar-title {
font-size: 0.9rem;
font-weight: 700;
color: var(--text);
flex: 1;
}
.fl-05__topbar-action {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 12px;
border-radius: 6px;
font-size: 0.75rem;
font-weight: 600;
cursor: pointer;
}
.fl-05__topbar-action--primary {
background: var(--accent);
color: #fff;
}
.fl-05__topbar-action--ghost {
background: rgba(255,255,255,0.06);
color: var(--muted);
border: 1px solid var(--border);
}
.fl-05__content {
flex: 1;
padding: 20px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Stats row */
.fl-05__stats {
display: flex;
gap: 12px;
}
.fl-05__stat {
flex: 1;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
padding: 14px;
}
.fl-05__stat-label {
font-size: 0.68rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--muted);
margin-bottom: 8px;
}
.fl-05__stat-value {
font-size: 1.4rem;
font-weight: 800;
color: var(--text);
}
.fl-05__stat-delta {
display: flex;
align-items: center;
gap: 4px;
font-size: 0.72rem;
font-weight: 600;
margin-top: 4px;
}
.fl-05__stat-delta.up { color: var(--green); }
.fl-05__stat-delta.down { color: var(--red); }
/* Activity list */
.fl-05__activity {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
overflow: hidden;
}
.fl-05__activity-head {
padding: 12px 16px;
border-bottom: 1px solid var(--border);
font-size: 0.8rem;
font-weight: 700;
color: var(--text);
display: flex;
justify-content: space-between;
align-items: center;
}
.fl-05__activity-view {
font-size: 0.7rem;
color: var(--accent);
font-weight: 600;
cursor: pointer;
}
.fl-05__activity-row {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 16px;
border-bottom: 1px solid rgba(48,54,61,0.5);
}
.fl-05__activity-row:last-child { border-bottom: none; }
.fl-05__activity-dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.fl-05__activity-text {
flex: 1;
font-size: 0.78rem;
color: var(--text);
}
.fl-05__activity-time {
font-size: 0.68rem;
color: var(--muted);
flex-shrink: 0;
}
@media (prefers-reduced-motion: reduce) {
.fl-05__nav-item, .fl-05__user-row { transition: none; }
} .fl-05, .fl-05 *, .fl-05 *::before, .fl-05 *::after {
margin: 0; padding: 0; box-sizing: border-box;
}
.fl-05 ::selection { background: #3b82f6; color: #fff; }
.fl-05 {
--bg: #0d1117;
--sidebar: #161b22;
--surface: #1c2128;
--border: #30363d;
--accent: #3b82f6;
--accent2: #8b5cf6;
--green: #22c55e;
--orange: #f97316;
--red: #ef4444;
--text: #e6edf3;
--muted: #7d8590;
font-family: 'Plus Jakarta Sans', sans-serif;
background: var(--bg);
border-radius: 16px;
overflow: hidden;
min-height: 500px;
}
/* Outer flex row: sidebar + main */
.fl-05__shell {
display: flex;
height: 500px;
}
/* ── Sidebar ── */
.fl-05__sidebar {
width: 220px;
flex-shrink: 0;
background: var(--sidebar);
border-right: 1px solid var(--border);
display: flex;
flex-direction: column;
padding: 0;
}
.fl-05__sidebar-top {
padding: 20px 16px 12px;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 10px;
}
.fl-05__workspace-icon {
width: 32px;
height: 32px;
border-radius: 8px;
background: linear-gradient(135deg, #3b82f6, #8b5cf6);
display: flex;
align-items: center;
justify-content: center;
font-size: 0.8rem;
font-weight: 800;
color: #fff;
flex-shrink: 0;
}
.fl-05__workspace-name {
font-size: 0.82rem;
font-weight: 700;
color: var(--text);
}
.fl-05__workspace-plan {
font-size: 0.65rem;
color: var(--accent);
font-weight: 600;
}
.fl-05__sidebar-nav {
flex: 1;
padding: 12px 8px;
display: flex;
flex-direction: column;
gap: 2px;
overflow-y: auto;
}
.fl-05__nav-section {
font-size: 0.6rem;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--muted);
padding: 10px 8px 4px;
}
.fl-05__nav-item {
display: flex;
align-items: center;
gap: 10px;
padding: 7px 10px;
border-radius: 6px;
cursor: pointer;
font-size: 0.8rem;
font-weight: 500;
color: var(--muted);
transition: all 0.15s;
position: relative;
}
.fl-05__nav-item:hover { background: rgba(255,255,255,0.06); color: var(--text); }
.fl-05__nav-item.is-active {
background: rgba(59,130,246,0.15);
color: var(--accent);
font-weight: 600;
}
.fl-05__nav-item.is-active::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 3px;
height: 60%;
background: var(--accent);
border-radius: 0 2px 2px 0;
}
.fl-05__nav-dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.fl-05__nav-count {
margin-left: auto;
font-size: 0.65rem;
font-weight: 700;
background: rgba(255,255,255,0.08);
padding: 1px 6px;
border-radius: 10px;
color: var(--muted);
}
.fl-05__nav-count.is-hot { background: var(--red); color: #fff; }
.fl-05__sidebar-bottom {
padding: 12px 8px;
border-top: 1px solid var(--border);
}
.fl-05__user-row {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 10px;
border-radius: 8px;
cursor: pointer;
transition: background 0.15s;
}
.fl-05__user-row:hover { background: rgba(255,255,255,0.06); }
.fl-05__user-avatar {
width: 28px;
height: 28px;
border-radius: 50%;
background: linear-gradient(135deg, #f97316, #ef4444);
font-size: 0.7rem;
font-weight: 800;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.fl-05__user-name {
font-size: 0.78rem;
font-weight: 600;
color: var(--text);
}
.fl-05__user-role {
font-size: 0.65rem;
color: var(--muted);
}
/* ── Main panel ── */
.fl-05__main {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.fl-05__topbar {
height: 52px;
background: var(--sidebar);
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
padding: 0 20px;
gap: 12px;
flex-shrink: 0;
}
.fl-05__topbar-title {
font-size: 0.9rem;
font-weight: 700;
color: var(--text);
flex: 1;
}
.fl-05__topbar-action {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 12px;
border-radius: 6px;
font-size: 0.75rem;
font-weight: 600;
cursor: pointer;
}
.fl-05__topbar-action--primary {
background: var(--accent);
color: #fff;
}
.fl-05__topbar-action--ghost {
background: rgba(255,255,255,0.06);
color: var(--muted);
border: 1px solid var(--border);
}
.fl-05__content {
flex: 1;
padding: 20px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Stats row */
.fl-05__stats {
display: flex;
gap: 12px;
}
.fl-05__stat {
flex: 1;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
padding: 14px;
}
.fl-05__stat-label {
font-size: 0.68rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--muted);
margin-bottom: 8px;
}
.fl-05__stat-value {
font-size: 1.4rem;
font-weight: 800;
color: var(--text);
}
.fl-05__stat-delta {
display: flex;
align-items: center;
gap: 4px;
font-size: 0.72rem;
font-weight: 600;
margin-top: 4px;
}
.fl-05__stat-delta.up { color: var(--green); }
.fl-05__stat-delta.down { color: var(--red); }
/* Activity list */
.fl-05__activity {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
overflow: hidden;
}
.fl-05__activity-head {
padding: 12px 16px;
border-bottom: 1px solid var(--border);
font-size: 0.8rem;
font-weight: 700;
color: var(--text);
display: flex;
justify-content: space-between;
align-items: center;
}
.fl-05__activity-view {
font-size: 0.7rem;
color: var(--accent);
font-weight: 600;
cursor: pointer;
}
.fl-05__activity-row {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 16px;
border-bottom: 1px solid rgba(48,54,61,0.5);
}
.fl-05__activity-row:last-child { border-bottom: none; }
.fl-05__activity-dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.fl-05__activity-text {
flex: 1;
font-size: 0.78rem;
color: var(--text);
}
.fl-05__activity-time {
font-size: 0.68rem;
color: var(--muted);
flex-shrink: 0;
}
@media (prefers-reduced-motion: reduce) {
.fl-05__nav-item, .fl-05__user-row { transition: none; }
}How this works
The outer shell is a flex-direction: row container: the sidebar has a fixed width: 220px; flex-shrink: 0 and the main area carries flex: 1; min-width: 0 so it absorbs all remaining horizontal space. Inside the main area, a second column flex container stacks the topbar, stat row, and content panel vertically.
The stat cards row uses a nested flex-wrap: wrap container with flex: 1 1 140px on each card so they reflow naturally on narrow viewports. The sidebar nav groups use flex-direction: column with gap for spacing, and the active item is highlighted with a left-border accent using border-left: 3px solid var(--accent).
Customize
- Collapse the sidebar by setting
width: 56pxand hiding text labels — toggle the class with JavaScript or a checkbox for a CSS-only drawer. - Change the sidebar width by editing the
widthon.fl-05__sidebar; the main area reflows automatically viaflex: 1. - Pin the sidebar so it doesn't scroll with content by adding
position: sticky; top: 0; height: 100vhto.fl-05__sidebar. - Add a top notification bar above the entire shell by wrapping everything in another column flex container and prepending a
flex-shrink: 0banner. - Swap to a dark sidebar on a light main area by editing
--sidebar-bgand--main-bgtokens on the root.
Watch out for
- The
min-width: 0on the main area is essential — flex children default tomin-width: autowhich prevents text from wrapping and causes overflow. - Using
height: 100vhon the outer wrapper breaks when the browser UI chrome is present on mobile; prefermin-height: 100dvhon modern targets. - Nested flex containers with
overflow: autorequire explicit heights on all ancestor containers to avoid the scrollable area collapsing to zero.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 29+ | 9+ | 28+ | 29+ |
dvh units for mobile viewport require Chrome 108+, Safari 15.4+; fall back to 100vh with a JS correction if targeting older mobile browsers.