16 CSS Side Menu Designs 05 / 16
Responsive Sidebar Menu (Hidden-to-Visible)
A sidebar permanently visible as a fixed column on desktop that hides off-screen on mobile and is revealed by a burger toggle, all handled by CSS media queries alone.
The code
<div class="sm-05">
<input type="checkbox" class="sm-05__toggle" id="sm-05-toggle">
<nav class="sm-05__nav">
<div class="sm-05__brand">
<div class="sm-05__logo">P</div>
<div class="sm-05__brand-name">Prism UI</div>
</div>
<div class="sm-05__section-title">Main Menu</div>
<div class="sm-05__links">
<a class="sm-05__link sm-05__link--active" href="#"><span class="sm-05__link-icon">⬡</span> Home</a>
<a class="sm-05__link" href="#"><span class="sm-05__link-icon">◈</span> Reports <span class="sm-05__badge">4</span></a>
<a class="sm-05__link" href="#"><span class="sm-05__link-icon">▦</span> Campaigns</a>
<a class="sm-05__link" href="#"><span class="sm-05__link-icon">◬</span> Audience</a>
</div>
<div class="sm-05__divider"></div>
<div class="sm-05__section-title">Account</div>
<div class="sm-05__links">
<a class="sm-05__link" href="#"><span class="sm-05__link-icon">◉</span> Profile</a>
<a class="sm-05__link" href="#"><span class="sm-05__link-icon">⬙</span> Settings</a>
</div>
<div class="sm-05__footer">
<div class="sm-05__avatar">SR</div>
<div>
<div class="sm-05__uname">Sam R.</div>
<div class="sm-05__urole">Editor</div>
</div>
</div>
</nav>
<div class="sm-05__main">
<div class="sm-05__topbar">
<label class="sm-05__burger" for="sm-05-toggle">
<span></span><span></span><span></span>
</label>
<div class="sm-05__topbar-title">Home</div>
<div class="sm-05__topbar-breadcrumb">Prism / Home</div>
</div>
<div class="sm-05__content">
<div class="sm-05__welcome">Good morning, Sam 🌤</div>
<div class="sm-05__sub">Sidebar is always visible on wide screens. Resize to mobile to see it hide off-screen with a burger toggle — no JS.</div>
<div class="sm-05__grid">
<div class="sm-05__card"><div class="sm-05__card-val">5,382</div><div class="sm-05__card-lbl">Sessions</div></div>
<div class="sm-05__card"><div class="sm-05__card-val">63%</div><div class="sm-05__card-lbl">Conversion</div></div>
<div class="sm-05__card"><div class="sm-05__card-val">228</div><div class="sm-05__card-lbl">Subscribers</div></div>
<div class="sm-05__card"><div class="sm-05__card-val">$4.8k</div><div class="sm-05__card-lbl">Revenue</div></div>
</div>
</div>
</div>
</div> <div class="sm-05">
<input type="checkbox" class="sm-05__toggle" id="sm-05-toggle">
<nav class="sm-05__nav">
<div class="sm-05__brand">
<div class="sm-05__logo">P</div>
<div class="sm-05__brand-name">Prism UI</div>
</div>
<div class="sm-05__section-title">Main Menu</div>
<div class="sm-05__links">
<a class="sm-05__link sm-05__link--active" href="#"><span class="sm-05__link-icon">⬡</span> Home</a>
<a class="sm-05__link" href="#"><span class="sm-05__link-icon">◈</span> Reports <span class="sm-05__badge">4</span></a>
<a class="sm-05__link" href="#"><span class="sm-05__link-icon">▦</span> Campaigns</a>
<a class="sm-05__link" href="#"><span class="sm-05__link-icon">◬</span> Audience</a>
</div>
<div class="sm-05__divider"></div>
<div class="sm-05__section-title">Account</div>
<div class="sm-05__links">
<a class="sm-05__link" href="#"><span class="sm-05__link-icon">◉</span> Profile</a>
<a class="sm-05__link" href="#"><span class="sm-05__link-icon">⬙</span> Settings</a>
</div>
<div class="sm-05__footer">
<div class="sm-05__avatar">SR</div>
<div>
<div class="sm-05__uname">Sam R.</div>
<div class="sm-05__urole">Editor</div>
</div>
</div>
</nav>
<div class="sm-05__main">
<div class="sm-05__topbar">
<label class="sm-05__burger" for="sm-05-toggle">
<span></span><span></span><span></span>
</label>
<div class="sm-05__topbar-title">Home</div>
<div class="sm-05__topbar-breadcrumb">Prism / Home</div>
</div>
<div class="sm-05__content">
<div class="sm-05__welcome">Good morning, Sam 🌤</div>
<div class="sm-05__sub">Sidebar is always visible on wide screens. Resize to mobile to see it hide off-screen with a burger toggle — no JS.</div>
<div class="sm-05__grid">
<div class="sm-05__card"><div class="sm-05__card-val">5,382</div><div class="sm-05__card-lbl">Sessions</div></div>
<div class="sm-05__card"><div class="sm-05__card-val">63%</div><div class="sm-05__card-lbl">Conversion</div></div>
<div class="sm-05__card"><div class="sm-05__card-val">228</div><div class="sm-05__card-lbl">Subscribers</div></div>
<div class="sm-05__card"><div class="sm-05__card-val">$4.8k</div><div class="sm-05__card-lbl">Revenue</div></div>
</div>
</div>
</div>
</div>.sm-05, .sm-05 *, .sm-05 *::before, .sm-05 *::after {
box-sizing: border-box; margin: 0; padding: 0;
}
.sm-05 ::selection { background: #6366f1; color: #fff; }
.sm-05 {
--bg: #f8fafc;
--surface: #fff;
--nav-bg: #fff;
--accent: #6366f1;
--accent2: #818cf8;
--text: #1e293b;
--muted: #94a3b8;
--border: #e2e8f0;
--font: 'Nunito', system-ui, sans-serif;
--w: 240px;
--dur: 0.35s;
font-family: var(--font);
background: var(--bg);
color: var(--text);
min-height: 100vh;
display: flex;
position: relative;
overflow: hidden;
border-radius: 12px;
}
/* Mobile toggle */
.sm-05__toggle { position: absolute; opacity: 0; width: 0; height: 0; }
/* Nav */
.sm-05__nav {
width: var(--w);
min-height: 460px;
background: var(--nav-bg);
border-right: 1px solid var(--border);
display: flex;
flex-direction: column;
padding: 20px 0;
flex-shrink: 0;
position: relative;
box-shadow: 2px 0 12px rgba(99,102,241,0.06);
}
/* Desktop: always visible — simulated here by having the wrapper at full width */
/* On mobile the sidebar is off-canvas */
@media (max-width: 600px) {
.sm-05__nav {
position: absolute;
top: 0; left: 0;
height: 100%;
transform: translateX(-100%);
transition: transform var(--dur) cubic-bezier(0.4,0,0.2,1);
z-index: 20;
}
.sm-05__toggle:checked ~ .sm-05__nav { transform: translateX(0); }
}
.sm-05__brand {
display: flex; align-items: center; gap: 10px;
padding: 0 20px 18px;
border-bottom: 1px solid var(--border);
margin-bottom: 12px;
}
.sm-05__logo {
width: 34px; height: 34px;
background: linear-gradient(135deg, var(--accent), var(--accent2));
border-radius: 8px;
display: flex; align-items: center; justify-content: center;
font-weight: 800; font-size: 15px; color: #fff;
}
.sm-05__brand-name { font-size: 15px; font-weight: 800; }
.sm-05__section-title {
font-size: 10px; font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--muted);
padding: 8px 20px 4px;
}
.sm-05__links { flex: 1; padding: 0 10px; }
.sm-05__link {
display: flex; align-items: center; gap: 10px;
padding: 10px 14px;
border-radius: 9px;
color: #64748b;
font-size: 14px; font-weight: 600;
cursor: pointer; text-decoration: none;
transition: all 0.2s;
margin-bottom: 2px;
}
.sm-05__link:hover { color: var(--accent); background: rgba(99,102,241,0.07); }
.sm-05__link--active { color: var(--accent); background: rgba(99,102,241,0.1); }
.sm-05__link-icon { font-size: 16px; }
.sm-05__badge {
margin-left: auto;
background: var(--accent);
color: #fff;
font-size: 10px;
font-weight: 700;
padding: 2px 7px;
border-radius: 99px;
}
.sm-05__divider { height: 1px; background: var(--border); margin: 10px 20px; }
/* User bottom */
.sm-05__footer {
padding: 14px 16px 0;
border-top: 1px solid var(--border);
display: flex; align-items: center; gap: 10px;
}
.sm-05__avatar {
width: 32px; height: 32px;
border-radius: 50%;
background: linear-gradient(135deg, #6366f1, #a855f7);
display: flex; align-items: center; justify-content: center;
font-size: 12px; font-weight: 700; color: #fff;
}
.sm-05__uname { font-size: 13px; font-weight: 700; }
.sm-05__urole { font-size: 11px; color: var(--muted); }
/* Main */
.sm-05__main { flex: 1; min-width: 0; }
.sm-05__topbar {
display: flex; align-items: center; gap: 14px;
padding: 18px 20px;
border-bottom: 1px solid var(--border);
background: var(--surface);
}
.sm-05__burger {
display: none;
width: 36px; height: 36px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
cursor: pointer;
transition: background 0.2s;
}
@media (max-width: 600px) { .sm-05__burger { display: flex; } }
.sm-05__burger span { width: 14px; height: 2px; background: #64748b; border-radius: 2px; }
.sm-05__topbar-title { font-size: 16px; font-weight: 800; }
.sm-05__topbar-breadcrumb { font-size: 12px; color: var(--muted); margin-left: auto; }
.sm-05__content { padding: 22px 20px; }
.sm-05__welcome { font-size: 19px; font-weight: 800; margin-bottom: 6px; }
.sm-05__sub { font-size: 13px; color: var(--muted); line-height: 1.6; margin-bottom: 20px; }
.sm-05__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.sm-05__card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
padding: 14px;
box-shadow: 0 1px 4px rgba(0,0,0,0.04);
}
.sm-05__card-val { font-size: 22px; font-weight: 800; color: var(--accent); }
.sm-05__card-lbl { font-size: 12px; color: var(--muted); margin-top: 3px; }
@media (prefers-reduced-motion: reduce) {
.sm-05__nav { transition: none; }
} .sm-05, .sm-05 *, .sm-05 *::before, .sm-05 *::after {
box-sizing: border-box; margin: 0; padding: 0;
}
.sm-05 ::selection { background: #6366f1; color: #fff; }
.sm-05 {
--bg: #f8fafc;
--surface: #fff;
--nav-bg: #fff;
--accent: #6366f1;
--accent2: #818cf8;
--text: #1e293b;
--muted: #94a3b8;
--border: #e2e8f0;
--font: 'Nunito', system-ui, sans-serif;
--w: 240px;
--dur: 0.35s;
font-family: var(--font);
background: var(--bg);
color: var(--text);
min-height: 100vh;
display: flex;
position: relative;
overflow: hidden;
border-radius: 12px;
}
/* Mobile toggle */
.sm-05__toggle { position: absolute; opacity: 0; width: 0; height: 0; }
/* Nav */
.sm-05__nav {
width: var(--w);
min-height: 460px;
background: var(--nav-bg);
border-right: 1px solid var(--border);
display: flex;
flex-direction: column;
padding: 20px 0;
flex-shrink: 0;
position: relative;
box-shadow: 2px 0 12px rgba(99,102,241,0.06);
}
/* Desktop: always visible — simulated here by having the wrapper at full width */
/* On mobile the sidebar is off-canvas */
@media (max-width: 600px) {
.sm-05__nav {
position: absolute;
top: 0; left: 0;
height: 100%;
transform: translateX(-100%);
transition: transform var(--dur) cubic-bezier(0.4,0,0.2,1);
z-index: 20;
}
.sm-05__toggle:checked ~ .sm-05__nav { transform: translateX(0); }
}
.sm-05__brand {
display: flex; align-items: center; gap: 10px;
padding: 0 20px 18px;
border-bottom: 1px solid var(--border);
margin-bottom: 12px;
}
.sm-05__logo {
width: 34px; height: 34px;
background: linear-gradient(135deg, var(--accent), var(--accent2));
border-radius: 8px;
display: flex; align-items: center; justify-content: center;
font-weight: 800; font-size: 15px; color: #fff;
}
.sm-05__brand-name { font-size: 15px; font-weight: 800; }
.sm-05__section-title {
font-size: 10px; font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--muted);
padding: 8px 20px 4px;
}
.sm-05__links { flex: 1; padding: 0 10px; }
.sm-05__link {
display: flex; align-items: center; gap: 10px;
padding: 10px 14px;
border-radius: 9px;
color: #64748b;
font-size: 14px; font-weight: 600;
cursor: pointer; text-decoration: none;
transition: all 0.2s;
margin-bottom: 2px;
}
.sm-05__link:hover { color: var(--accent); background: rgba(99,102,241,0.07); }
.sm-05__link--active { color: var(--accent); background: rgba(99,102,241,0.1); }
.sm-05__link-icon { font-size: 16px; }
.sm-05__badge {
margin-left: auto;
background: var(--accent);
color: #fff;
font-size: 10px;
font-weight: 700;
padding: 2px 7px;
border-radius: 99px;
}
.sm-05__divider { height: 1px; background: var(--border); margin: 10px 20px; }
/* User bottom */
.sm-05__footer {
padding: 14px 16px 0;
border-top: 1px solid var(--border);
display: flex; align-items: center; gap: 10px;
}
.sm-05__avatar {
width: 32px; height: 32px;
border-radius: 50%;
background: linear-gradient(135deg, #6366f1, #a855f7);
display: flex; align-items: center; justify-content: center;
font-size: 12px; font-weight: 700; color: #fff;
}
.sm-05__uname { font-size: 13px; font-weight: 700; }
.sm-05__urole { font-size: 11px; color: var(--muted); }
/* Main */
.sm-05__main { flex: 1; min-width: 0; }
.sm-05__topbar {
display: flex; align-items: center; gap: 14px;
padding: 18px 20px;
border-bottom: 1px solid var(--border);
background: var(--surface);
}
.sm-05__burger {
display: none;
width: 36px; height: 36px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
cursor: pointer;
transition: background 0.2s;
}
@media (max-width: 600px) { .sm-05__burger { display: flex; } }
.sm-05__burger span { width: 14px; height: 2px; background: #64748b; border-radius: 2px; }
.sm-05__topbar-title { font-size: 16px; font-weight: 800; }
.sm-05__topbar-breadcrumb { font-size: 12px; color: var(--muted); margin-left: auto; }
.sm-05__content { padding: 22px 20px; }
.sm-05__welcome { font-size: 19px; font-weight: 800; margin-bottom: 6px; }
.sm-05__sub { font-size: 13px; color: var(--muted); line-height: 1.6; margin-bottom: 20px; }
.sm-05__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.sm-05__card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
padding: 14px;
box-shadow: 0 1px 4px rgba(0,0,0,0.04);
}
.sm-05__card-val { font-size: 22px; font-weight: 800; color: var(--accent); }
.sm-05__card-lbl { font-size: 12px; color: var(--muted); margin-top: 3px; }
@media (prefers-reduced-motion: reduce) {
.sm-05__nav { transition: none; }
}How this works
On desktop (>600px) the sidebar is a normal flex child that sits in document flow with no transforms applied. On mobile (<600px) the nav switches to position: absolute with transform: translateX(-100%), moving it off-canvas while the main content fills the full width.
The burger button uses display: none on desktop and display: flex on mobile — entirely controlled by media queries. The checkbox toggle is inert on desktop since the nav is always visible, but activates correctly at narrow widths. The same markup serves all viewport sizes with zero JavaScript.
Customize
- Change the breakpoint by editing
max-width: 600px— 768px targets tablets as well, while 480px limits responsive behaviour to the smallest phones. - Add a smooth body content shift at mobile by applying a
margin-lefttransition on the main element when the sidebar is open. - Show a mini logo in the topbar on mobile using a separate element that appears only at narrow widths via
display: none / block. - Persist the open/closed state across page refreshes by storing the checkbox value in
localStorageand restoring it on load. - Add swipe-to-close on mobile by detecting a horizontal touch delta and toggling the checkbox — remains non-critical without JS.
Watch out for
- The sidebar being
position: absoluteon mobile means it overlaps content — always pair with an overlay or ensure the nav width equals the viewport. - Any
z-indexon the desktop sidebar may interfere with sticky headers or modals when the layout switches to mobile. - Avoid
width: 0; overflow: hiddenfor mobile hide — always usetransform: translateXso layout position is unaffected.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 36+ | 9+ | 41+ | 36+ |
CSS media queries and transforms are fully supported in all modern browsers including IE11.