Mobile Navigation
Practical patterns for calm, accessible navigation on small screens.
01 — Foundation
Mobile navigation should reduce effort
Bad mobile navigation feels like opening a haunted wardrobe.
On smaller screens, navigation must help users move confidently. They should always know how to open and close the menu, where they are, and what options exist — without fullscreen chaos or hidden interaction zones.
02 — Controls
Open, close, and labelling
The menu button is infrastructure — label it honestly.
-
buttonwith “Menu” / “Navigation” — not an unlabeled icon alone -
aria-expandedreflects open state; focus moves into the panel when opened - obvious close control and Escape to dismiss
-
real links inside
nav— see Navigation and Buttons vs Links
This site uses a button with aria-expanded and
aria-controls on small viewports, a sibling nav with
real links, and site-header.is_open toggled in JavaScript — not
details / summary for the main menu.
<button type="button" aria-expanded="false" aria-controls="site-nav">
Menu
</button>
<nav id="site-nav" hidden>
<!-- links -->
</nav> 03 — Structure
Calm structure on small screens
Restrained depth beats nested maze menus.
- touch-friendly targets — minimum ~44px where possible
- limit nesting; accordions for submenus with keyboard support — see Accordions
-
show current page —
aria-current="page" - no hover-dependent behaviour — touch has no hover
04 — Avoid
What to avoid
Fullscreen takeover is not automatically good mobile UX.
-
never wrap the whole site menu in
details/summary— it breaks desktop layout and fights responsive navigation; use abuttonplusnavand JavaScript (or a dedicated mobile-only pattern) - fullscreen navigation chaos with no clear hierarchy
- excessive animation — respect reduced motion
- trapping users without scroll or focus escape
05 — Review
Before you approve
A short checklist for mobile navigation in code review.
- open/close is obvious; keyboard and screen reader paths work
- current location is clear; links are real and tappable
-
main menu uses
button+nav— neverdetails/summaryfor the whole site header - complements the Navigation pattern — not a conflicting second system