Collapsible Sidebar Navigation Menu
Create a responsive and collapsible sidebar menu using HTML, CSS, and JavaScript. Perfect for maximizing screen space on smaller devices.
Code
<!--
Collapsible Sidebar Navigation Menu
Responsive, accessible sidebar that toggles via button/ESC and supports reduced motion. Drop into any page.
-->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Collapsible Sidebar Navigation Menu</title>
<style>
:root { --sidebar-w: 250px; --bg: #333; --fg: #fff; --focus: #7dd3fc; }
body { margin: 0; font-family: Arial, sans-serif; min-height: 100vh; transition: margin-left .5s; }
.sidebar {
width: var(--sidebar-w);
position: fixed;
inset: 0 auto 0 calc(var(--sidebar-w) * -1); /* hidden by default */
background: var(--bg);
color: var(--fg);
padding: 15px;
transition: left .5s;
z-index: 1000;
box-sizing: border-box;
}
.sidebar.active { left: 0; }
#toggleBtn {
appearance: none;
border: 1px solid rgba(255,255,255,.25);
background: transparent;
color: var(--fg);
padding: 10px 12px;
border-radius: 8px;
cursor: pointer;
}
#toggleBtn:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.menu { padding: 12px 0 0; margin: 0; }
.menu li { list-style: none; margin: 12px 0; }
.menu a { color: var(--fg); text-decoration: none; display: inline-block; padding: 6px 4px; border-radius: 6px; }
.menu a:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
/* Small screens: push content when open; larger screens keep overlay behavior */
@media (max-width: 720px) { body.sidebar-open { margin-left: var(--sidebar-w); } }
@media (prefers-reduced-motion: reduce) { body, .sidebar { transition: none; } }
</style>
</head>
<body>
<div class="sidebar" id="sidebar" aria-hidden="true">
<button id="toggleBtn" type="button" aria-controls="sidebar" aria-expanded="false">Toggle Menu</button>
<ul class="menu">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>
<main style="padding: 20px;">
<h1>Page Content</h1>
<p>Example usage: click “Toggle Menu”, press Escape to close.</p>
</main>
<script>
// Sidebar toggle with accessibility (aria-*), ESC close, and safe init.
(() => {
const sidebar = document.getElementById('sidebar');
const toggleBtn = document.getElementById('toggleBtn');
if (!sidebar || !toggleBtn) return;
const setOpen = (isOpen) => {
sidebar.classList.toggle('active', isOpen);
document.body.classList.toggle('sidebar-open', isOpen);
sidebar.setAttribute('aria-hidden', String(!isOpen));
toggleBtn.setAttribute('aria-expanded', String(isOpen));
};
toggleBtn.addEventListener('click', () => setOpen(!sidebar.classList.contains('active')));
document.addEventListener('keydown', (e) => { if (e.key === 'Escape') setOpen(false); }, { passive: true });
// Example usage: call setOpen(true/false) to control programmatically.
})();
</script>
</body>
</html>