Mobile Navigation Drawer
Introduction: Why Mobile Navigation Matters
Welcome back!
In the last few lessons, you focused on features like task filtering, cross-view synchronization, and user feedback — all essential for a seamless desktop experience.
Now it’s time to make your app truly responsive.
Modern web users expect applications to adapt beautifully whether they’re on a laptop, tablet, or smartphone.
On larger screens, side navigation works perfectly — you have plenty of horizontal space.
But on smaller screens, that same sidebar eats up valuable screen real estate.
The solution? A responsive navigation system:
- A fixed sidebar on desktop.
- A hamburger-style drawer menu on mobile.
By the end of this lesson, you’ll understand exactly how this is built — how to structure it, control it, and style it so your app feels just as smooth on mobile as it does on desktop.
Big Picture: How the Layout Responds to Screen Size
Your DashboardLayout component is now fully responsive:
- On large screens (md and up) → you’ll see a permanent sidebar on the left.
- On small screens (below md) → the sidebar is hidden, replaced by:
- A hamburger menu button in the top header.
- A sliding drawer menu that appears when the button is clicked.
- A dimmed overlay that closes the menu when tapped.
This behavior is implemented with a combination of:
- Tailwind’s responsive utilities (
hidden md:block,md:hidden, etc.) - React state to open/close the mobile drawer.
- ARIA attributes and keyboard-friendly icons for accessibility.
Let’s explore how each part works.
Desktop Sidebar: The Base Navigation Structure
Here’s the sidebar portion from src/app/(dashboard)/layout.tsx:
Key details:
hidden md:block→ the sidebar is hidden on mobile but visible frommdbreakpoint (768px) and up.border-r bg-white→ gives the sidebar a solid white background with a subtle right border to separate it from the main area.space-y-1→ adds consistent spacing between navigation links.isActive(item.href)→ determines which route is currently active to highlight the link (important for user orientation).
Each <Link> uses Tailwind classes for hover effects, padding, and rounded corners.
This structure works well on desktop — always visible, stable, and non-intrusive.
Now let’s focus on the mobile experience.
Mobile Header: The Hamburger Menu
When you switch to mobile view, the sidebar disappears — and a header bar replaces it:
What’s happening:
- The header stays sticky at the top and uses a blurred, semi-transparent background (
bg-white/80 backdrop-blur) to look polished while scrolling. - The hamburger menu button (
md:hidden) only appears on small screens.
It’s styled with:
p-2padding for a good touch target.rounded-md hover:bg-gray-100for smooth hover/tap feedback.
The button triggers setMobileOpen(true) — setting React state that opens the mobile drawer.
The small empty <div className="w-10 md:hidden" /> on the right keeps spacing symmetrical when the hamburger icon is visible on the left.
Mobile Drawer: The Sliding Navigation Menu
When mobileOpen is true, this section renders:
Let’s unpack this step by step:
1. mobileOpen State
Controlled with React’s useState(false) hook.
Toggled via:
- Hamburger button →
setMobileOpen(true) - Overlay click or Close button →
setMobileOpen(false)
This state determines whether the drawer is visible.
2. The Overlay
- Covers the entire screen with a dark semi-transparent layer.
- Prevents interaction with the main content.
- Clicking it closes the drawer — intuitive for mobile users.
Tailwind details:
fixed inset-0→ covers the entire viewport.bg-black/50→ creates a 50% opacity dark overlay.z-40→ ensures it appears beneath the drawer (z-50).
3. The Drawer Itself
fixed inset-y-0 left-0→ pins the drawer to the left edge, full height.w-64→ gives it a consistent 256px width.bg-white shadow-xl→ matches desktop styling but adds a soft elevation for the sliding effect.z-50→ ensures it appears above the overlay.
4. Drawer Header
- Displays the app name and a close icon.
- Close button uses:
- A minimalist X SVG icon (
<path d="M6 18L18 6M6 6l12 12" />) aria-label="Close menu"for accessibility.hover:bg-gray-100to match the rest of the UI’s hover pattern.
- A minimalist X SVG icon (
5. Navigation Links Same logic as the desktop sidebar:
- Mapped from the same
navItemsarray. - Styled identically for visual consistency.
- Clicking a link also calls
closeMobile()to collapse the drawer after navigation.
6. Z-index and Layering
- Drawer (
z-50) sits above the overlay (z-40). - Overlay ensures focus remains on the open menu.
- The rest of the page content remains visible but inactive underneath.
Tailwind callout: The responsive behavior comes mainly from
hidden md:blockfor the desktop sidebar,md:hiddenfor mobile-only controls,fixed inset-0for the overlay, andfixed inset-y-0 left-0 w-64for the drawer panel.
Accessibility & UX Considerations
This layout also follows best accessibility practices:
aria-labelattributes → clarify the purpose of buttons for screen readers.- Keyboard navigability → users can tab through links easily since they’re semantic
<a>tags viaLink. - Visual consistency → colors, hover feedback, and spacing align with the desktop layout.
It’s not just mobile-friendly — it’s inclusive and usable for everyone.
Putting It All Together
Here’s how your layout behaves across devices:
| Device Type | Sidebar Behavior | Navigation Trigger |
|---|---|---|
| Desktop (md+) | Permanent sidebar visible | None (always open) |
| Tablet / Mobile (<md) | Sidebar hidden | Menu button (hamburger icon) |
| Menu open on mobile | Drawer slides in from left | Overlay click or Close button hides it |
No extra routes or components — just one smart layout component that adapts seamlessly to screen size.
Summary
In this lesson, you learned how to:
- Add a mobile navigation drawer that slides in and out with React state.
- Use Tailwind’s responsive classes to toggle between sidebar and drawer layouts.
- Combine overlay, drawer, and header layers for an intuitive experience.
- Maintain accessibility with ARIA labels and consistent focus patterns.
- Build a single unified layout that works perfectly on all screen sizes.
Your Task Manager app is now fully responsive — with a professional, production-grade navigation system that adapts to any device.
This wraps up the course: you’ve added URL-driven filtering, synchronized state across views, and improved the layout for mobile users.
