figma guide

Designing sidebars and navigation drawers in Figma: patterns, states, and handoff

Design persistent sidebars and off-canvas navigation drawers in Figma with collapsed states, nested nav, mobile breakpoints, and Dev Mode specs for engineers.

Published
Updated
Jun 12, 2026
Read time
8 min
Level
Beginner

Quick answer

Sidebars and drawers in Figma are app-shell navigation patterns—a persistent sidebar stays visible on desktop; a drawer slides in from the edge on mobile or when space is tight. Build a Sidebar / Shell component with variants for state=expanded | collapsed | hidden, breakpoint=desktop | mobile, and optional style=rail | full. Pair nav items with tabs, badges, and modals. Document width tokens, collapse behavior, active route styling, nested menu rules, and focus trap for mobile drawers in Dev Mode. Start from the Figma guides hub if you are new to layout shells.


Who this is for

  • Product designers shipping admin dashboards, SaaS apps, and mobile-first products with shared navigation.
  • Design system teams replacing one-off left-nav hacks with one shell primitive.
  • Engineers implementing responsive breakpoints, aria-current, and drawer overlay behavior.

PatternLayoutBest forAvoid when
Persistent sidebarFixed left column; content shifts6–20 destinations; admin toolsMarketing sites with 4 links
Collapsible railIcon-only strip; expands on hover or clickDense apps; power usersFirst-time users who need labels
Off-canvas drawerHidden until hamburger opensMobile, narrow viewportsDesktop-primary workflows
Top navigationHorizontal barMarketing, shallow IA15+ nested sections
TabsPeer views in same contextSettings sub-viewsGlobal app destinations

Verdict: use a sidebar on desktop and a drawer on mobile for the same nav tree—do not maintain two different information architectures. Use tabs inside the content area for section switching, not for primary app routes.


App shell anatomy

PartPurposeSpec tip
Sidebar containerNav columnWidth: 240–280px expanded; 56–72px rail
Header slotLogo, product name, collapse toggleSticky at top of sidebar
Nav group label”Main”, “Settings” (optional)Caption style; hide in rail mode
Nav itemLink or button rowIcon + label; min 40–44px height
Active indicatorCurrent routeLeft border, fill, or bold—one system-wide
Nested itemsChildren under parentIndent 16–24px; chevron on parent
Footer slotUser menu, help, collapseSticky at bottom
Content areaMain page canvasFills remaining width
Mobile overlayScrim behind drawerrgba(0,0,0,0.4–0.6); click to dismiss
AppShell
├── Variant: sidebar=expanded | collapsed | hidden
├── Variant: breakpoint=desktop | mobile
├── Layer: Sidebar (vertical auto layout, fill height)
│   ├── Header (logo + collapse toggle)
│   ├── NavGroup × N
│   │   ├── Group label (optional)
│   │   └── NavItem × N
│   └── Footer (user avatar, settings)
├── Layer: Main (fill container)
│   └── Page content slot
└── Layer: DrawerOverlay (mobile only, optional)

Use layout grids on the main content area—not inside the sidebar list.


ModeWidthShowsWhen to use
Expanded240–280pxIcon + label + badgesDefault desktop
Collapsed rail56–72pxIcon only; tooltip on hoverPower users; small laptops
Hidden0pxDrawer trigger in top barMobile; immersive editors
Overlay sidebar280px over contentDrawer on desktop tooCanvas-heavy tools (Figma, video editors)

Document whether collapse is user-persisted (localStorage) or breakpoint-driven. Engineering cannot infer this from a single frame.


StateVisualInteraction
DefaultNeutral text and iconHoverable
Hoversurface/hover backgroundPointer cursor
Active / currentBrand accent, left bar, or bold labelaria-current="page"
FocusVisible focus ring on entire rowKeyboard navigable
DisabledMuted; no pointeraria-disabled
Parent expandedChevron rotated; children visibleToggle on click
Parent collapsedChevron default; children hiddenChildren still reachable via route

Reuse interactive components for hover and press on nav rows. Active state should not rely on color alone—add weight, icon fill, or left indicator.


Nested navigation

DepthPatternSpec tip
1 levelFlat list with group labelsUp to ~12 items per group
2 levelsParent row + indented childrenMax 5–7 children per parent
3+ levelsFlyout submenu or accordion in sidebarAvoid on mobile drawer
NavItem / Parent
├── Variant: state=default | hover | active | expanded
├── Property: hasChildren=true | false
├── Layer: Row (horizontal auto layout, gap 12px, padding 8–12px)
│   ├── Icon (20–24px)
│   ├── Label (truncate with tooltip)
│   ├── Badge (optional)
│   └── Chevron (if hasChildren)
└── Layer: Children (vertical auto layout, indent 24px)
    └── NavItem / Child × N

Document default expanded parents (e.g., current section open on load) in the component description.


Mobile drawer behavior

BehaviorSpecCommon mistake
TriggerHamburger in top app barHidden with no menu affordance
EntrySlide from left (or right for RTL)Instant appear with no motion spec
ScrimTap outside closesDrawer blocks entire screen permanently
Focus trapTab cycles inside drawer until closeFocus lost behind overlay
EscapeEsc closes drawerNo keyboard dismiss
ScrollNav list scrolls inside drawerBody scrolls underneath
Active routeCloses drawer after navigation (optional)Drawer stays open on every tap

Prototype at least: closed, open, and nested expanded frames. Note animation duration (200–300ms) and easing in Dev Mode.


Responsive breakpoint strategy

ViewportShell behaviorFrame in Figma
≥1024pxExpanded sidebarDesktop 1440 or 1280 frame
768–1023pxCollapsed rail or overlayTablet frame
<768pxHidden sidebar + drawerMobile 390 frame

Use constraints and breakpoints on the shell—not separate unrelated files per breakpoint. Publish Sidebar and Drawer as linked variants or separate components with a mapping table in handoff.


Pairing with other patterns

NeedPatternLink
User account menuAvatar + dropdown in footerProfile, logout
NotificationsBell icon + badge in headerBadges
Search⌘K or search in top barSearch UI
Settings sectionsContent-area tabs or accordionsNot duplicate nav
Destructive actionsModalNever bury delete in drawer footer

Accessibility checklist

RequirementImplementation
Landmark<nav aria-label="Main">
Current pagearia-current="page" on active item
Expandable sectionsaria-expanded on parent rows
Mobile drawerrole="dialog" or focus trap; return focus to trigger on close
Icon-only railaria-label or tooltip on every icon
Skip link”Skip to main content” above shell (document in handoff)

Test keyboard order: logo → nav items top-to-bottom → footer → main content. Verify contrast on active and hover states.


Prototyping limits

Figma cannot persist collapse state across pages. For demos:

  1. Build frames: expanded, collapsed rail, mobile drawer open.
  2. Wire collapse toggle between expanded and rail frames.
  3. Wire hamburger → drawer open; scrim tap → closed.
  4. Note real routing and persistence in sticky comments.

Organize flows with sections per breakpoint.


Handoff to engineering

DeliverableWhere it lives
Sidebar widths (expanded / rail)Token table or component description
Breakpoint valueslg, md px thresholds
Collapse persistenceUser toggle vs responsive-only
Nav data shape{ label, href, icon, children?, badge? }
Active matching rulesExact path vs prefix
Drawer animationDuration, easing, transform origin
RTL mirrorDrawer from right; chevron flip
z-index stackDrawer above modals? Document layer order

Include the shell in your Dev Mode handoff checklist. Publish under Patterns / Navigation in your team library.


Real-world examples

SaaS admin dashboard

Expanded sidebar with grouped nav (Dashboard, Projects, Reports, Settings). Collapsed rail on tablet. User avatar and logout in footer. Content uses tables and breadcrumbs in page header.

Mobile-first consumer app

No persistent sidebar on phone. Bottom tab bar for 4 primary destinations; hamburger drawer for secondary links (Help, Legal, Account). Drawer uses full-height list with large tap targets.

Design tool / canvas app

Overlay sidebar that does not push canvas. Icon rail default; panel expands over content. Document that main canvas does not reflow when sidebar opens.


Common mistakes

MistakeConsequenceFix
Different nav trees on mobile vs desktopUsers get lostSame IA; only presentation changes
Active state only changes icon colorFails contrast / color-blind usersAdd weight, bar, or background
40+ items in flat sidebarUnusable scrollGroup, collapse, or move to search
Drawer with no scrimUsers do not know how to closeOverlay + tap-outside + Esc
Rail mode without tooltipsIcons ambiguousRequired aria-label or tooltip
Sidebar scrolls entire pageFooter nav disappearsInternal scroll in nav list
Nested flyouts on mobileAccidental dismissUse accordion expand in drawer
z-index fights with modalsDrawer covers dialogsLayer order spec

FAQ

Use persistent sidebar when users switch destinations many times per session (admin, email, design tools). Use hamburger-only when navigation is rare (marketing, single-task flows).

Bottom tab bar instead of drawer?

Bottom tabs for 3–5 primary mobile destinations users hit daily. Drawer for secondary or 10+ links. Many apps combine both.

Should the sidebar push content or overlay?

Push when users need spatial context (file browsers). Overlay when canvas space is sacred (Figma, maps, video). Document which mode you chose.

Collapse on route change?

Optional for mobile drawer (close after tap). Desktop sidebar usually stays open—do not collapse without user intent.


Bottom line

Design navigation as an app shell—sidebar, rail, drawer, and content area—not isolated nav rows. Document widths, breakpoints, collapse rules, active states, and mobile focus behavior in Dev Mode. Continue with navigation tabs, avatars in the sidebar footer, responsive frames, and the tutorials hub.

Share on X

§ Keep reading

Related guides.