☰ Mobile Menu Design Guide
Mobile hamburger menus є standard navigation pattern для responsive websites коли screen space обмежено. Named після three-line icon (☰) що resembles hamburgер, цей UI pattern reveals hidden navigation upon tap/click. Цей comprehensive guide covers UX best practices, animation patterns, accessibility considerations, та complete implementation для mushroom education website.
🎯 When to Use Hamburger Menu
✅ Good Use Cases
- Many nav items (> 5-6): Doesn't fit horizontally
- Secondary navigation: Not critical для immediate access
- Mobile-only: Desktop має horizontal nav
- Content-first sites: Article reading priority
- Complex hierarchies: Multi-level menus
❌ Avoid If...
- Few items (≤ 4): Tab bar кращий
- E-commerce: visible navigation increases conversions
- Task-critical actions: Login, cart need visibility
- Discovery-focused: Users need browse options
📱 For Mushroom Education Website:
Recommendation: ✅ Use hamburger menu
Rationale:
- Complex content hierarchy (Species, Safety, Growing, Therapy)
- Mobile users primarily read articles (content-first)
- Desktop має enough space для horizontal nav
- Search bar needs primary position (visible)
🎨 Design Patterns
1. Icon Styles
Interactive Demo (Click to Transform):
Classic 3-Line
HTML Structure:
<button class="hamburger" aria-label="Menu" aria-expanded="false">
<span></span>
<span></span>
<span></span>
</button>
CSS Animation (X Transform):
.hamburger {
background: transparent;
border: none;
cursor: pointer;
padding: 15px;
display: flex;
flex-direction: column;
justify-content: space-around;
width: 50px;
height: 50px;
}
.hamburger span {
display: block;
width: 100%;
height: 3px;
background: #2c3e50;
border-radius: 3px;
transition: all 0.3s ease;
transform-origin: center;
}
.hamburger.active span:nth-child(1) {
transform: rotate(45deg) translate(5px, 5px);
}
.hamburger.active span:nth-child(2) {
opacity: 0;
}
.hamburger.active span:nth-child(3) {
transform: rotate(-45deg) translate(7px, -6px);
}
.hamburger span:nth-child(1) { transform: translateY(-8px); }
.hamburger span:nth-child(3) { transform: translateY(8px); }
2. Menu Overlay Styles
| Style | Animation | UX Impact | Best For |
|---|---|---|---|
| Slide від Right | transform: translateX(100%) → translateX(0) |
Familiar mobile pattern | Standard content sites |
| Slide від Left | transform: translateX(-100%) → translateX(0) |
Facebook-style drawer | Apps, social platforms |
| Full-Screen Overlay | opacity: 0 → opacity: 1 |
Immersive, focus на nav | Simple menus, portfolios |
| Push Content | Entire page slides, menu reveals | Spatial awareness maintained | Feature-rich apps |
| Expand від Top | max-height: 0 → max-height: 100vh |
Simple, lightweight | Minimal nav items |
💻 Complete Implementation
HTML Structure:
<!-- Mobile Header -->
<header class="mobile-header">
<!-- Logo -->
<a href="/" class="logo">
<img src="/logo.svg" alt="Mushroom Knowledge Hub">
</a>
<!-- Hamburger Button -->
<button class="hamburger"
aria-label="Toggle navigation menu"
aria-expanded="false"
aria-controls="mobile-menu">
<span></span>
<span></span>
<span></span>
</button>
</header>
<!-- Mobile Menu Overlay -->
<nav class="mobile-menu" id="mobile-menu" aria-hidden="true">
<!-- Close Button -->
<button class="close-menu" aria-label="Close menu">
<svg width="24" height="24" viewBox="0 0 24 24">
<path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2"/>
</svg>
</button>
<ul class="menu-list">
<li><a href="/species">Mushroom Species</a></li>
<li><a href="/effects">Effects & Science</a></li>
<li><a href="/safety">Safety Guide</a></li>
<li><a href="/growing">Cultivation</a></li>
<li><a href="/microdosing">Microdosing</a></li>
<li><a href="/therapy">Therapeutic Use</a></li>
<li><a href="/research">Research</a></li>
<li><a href="/community">Community</a></li>
</ul>
<!-- Optional: Secondary Links -->
<div class="menu-footer">
<a href="/about">About Us</a>
<a href="/contact">Contact</a>
</div>
</nav>
<!-- Backdrop Overlay -->
<div class="menu-backdrop"></div>
CSS Styling:
/* Mobile Header */
.mobile-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 20px;
background: white;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
position: sticky;
top: 0;
z-index: 1000;
}
/* Only show on mobile */
@media (min-width: 769px) {
.mobile-header, .hamburger {
display: none;
}
}
/* Mobile Menu Overlay */
.mobile-menu {
position: fixed;
top: 0;
right: 0;
width: 85%;
max-width: 350px;
height: 100vh;
background: white;
transform: translateX(100%);
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 2000;
overflow-y: auto;
box-shadow: -4px 0 20px rgba(0,0,0,0.2);
}
.mobile-menu.active {
transform: translateX(0);
}
/* Backdrop */
.menu-backdrop {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.5);
opacity: 0;
visibility: hidden;
transition: opacity 0.3s, visibility 0.3s;
z-index: 1999;
}
.menu-backdrop.active {
opacity: 1;
visibility: visible;
}
/* Menu List */
.menu-list {
list-style: none;
padding: 80px 0 40px;
margin: 0;
}
.menu-list li {
margin: 0;
}
.menu-list a {
display: block;
padding: 18px 30px;
font-size: 1.1em;
font-weight: 500;
color: #2c3e50;
text-decoration: none;
border-left: 4px solid transparent;
transition: all 0.2s;
}
.menu-list a:hover,
.menu-list a:focus {
background: #f093fb;
color: white;
border-left-color: #f5576c;
}
/* Close Button */
.close-menu {
position: absolute;
top: 20px;
right: 20px;
background: transparent;
border: none;
cursor: pointer;
padding: 10px;
color: #2c3e50;
transition: color 0.2s;
}
.close-menu:hover {
color: #f5576c;
}
/* Menu Footer */
.menu-footer {
padding: 20px 30px;
border-top: 1px solid #e9ecef;
display: flex;
gap: 20px;
}
.menu-footer a {
color: #6c757d;
font-size: 0.9em;
text-decoration: none;
}
/* Prevent body scroll when menu open */
body.menu-open {
overflow: hidden;
}
JavaScript Functionality:
// Get elements
const hamburger = document.querySelector('.hamburger');
const mobileMenu = document.querySelector('.mobile-menu');
const menuBackdrop = document.querySelector('.menu-backdrop');
const closeMenu = document.querySelector('.close-menu');
const body = document.body;
// Open menu
function openMenu() {
hamburger.classList.add('active');
mobileMenu.classList.add('active');
menuBackdrop.classList.add('active');
body.classList.add('menu-open');
// Accessibility
hamburger.setAttribute('aria-expanded', 'true');
mobileMenu.setAttribute('aria-hidden', 'false');
// Focus first link
const firstLink = mobileMenu.querySelector('a');
setTimeout(() => firstLink.focus(), 300);
}
// Close menu
function closeMenuFn() {
hamburger.classList.remove('active');
mobileMenu.classList.remove('active');
menuBackdrop.classList.remove('active');
body.classList.remove('menu-open');
// Accessibility
hamburger.setAttribute('aria-expanded', 'false');
mobileMenu.setAttribute('aria-hidden', 'true');
// Return focus
hamburger.focus();
}
// Event listeners
hamburger.addEventListener('click', openMenu);
closeMenu.addEventListener('click', closeMenuFn);
menuBackdrop.addEventListener('click', closeMenuFn);
// Close on Escape key
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && mobileMenu.classList.contains('active')) {
closeMenuFn();
}
});
// Close menu on link click
const menuLinks = mobileMenu.querySelectorAll('a');
menuLinks.forEach(link => {
link.addEventListener('click', () => {
// Delay for navigation
setTimeout(closeMenuFn, 200);
});
});
♿ Accessibility Best Practices
ARIA Attributes
aria-label="Menu"на buttonaria-expanded="false|true"(toggle state)aria-controls="mobile-menu"(connects button до menu)aria-hidden="true|false"на nav
Keyboard Navigation
- Tab: Navigate через links
- Escape: Close menu
- Space/Enter: Activate hamburger
- Focus trap: Keep focus у menu коли open
Screen Reader Support
- Descriptive button label
- Announce state changes
- Skip links available
- Semantic HTML (
<nav>,<button>)
Touch Targets
- Minimum: 44x44px (WCAG 2.1)
- Hamburger: 48x48px recommended
- Menu items: ≥ 48px height
- Spacing: 8px minimum між items
⚡ Performance & UX Tips
Animation Performance:
/* Use GPU-accelerated properties */
.mobile-menu {
/* ✅ Good: GPU accelerated */
transform: translateX(100%);
will-change: transform;
/* ❌ Avoid: triggers layout/paint */
/* left: 100%; */
}
/* Use cubic-bezier для smooth easing */
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
Prevent Body Scroll:
// When menu opens
body.classList.add('menu-open');
// CSS
body.menu-open {
overflow: hidden;
position: fixed; /* iOS fix */
width: 100%;
}
Debounce Resize Events:
// Close menu if resized to desktop
let resizeTimer;
window.addEventListener('resize', () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(() => {
if (window.innerWidth > 768 && mobileMenu.classList.contains('active')) {
closeMenuFn();
}
}, 250);
});
✅ Mobile Menu Checklist
Implementation Checklist:
- ☐ Hamburger icon має proper ARIA labels
- ☐ Smooth animation (≤ 300ms)
- ☐ Backdrop overlay з opacity transition
- ☐ Body scroll prevented коли menu open
- ☐ Close button visible та accessible
- ☐ Click backdrop closes menu
- ☐ Escape key closes menu
- ☐ Focus management (trap, return)
- ☐ Touch targets ≥ 44x44px
- ☐ Screen reader tested
- ☐ Keyboard navigation works
- ☐ Responsive auto-close на desktop resize
- ☐ Performance optimized (GPU acceleration)
- ☐ Active state indicator
- ☐ Works на iOS/Android