The word “drawer” gets applied to two different behaviors. Material 3’s standard navigation drawer sits beside the page content with no scrim, and Atlassian’s Drawer is a modal dialog that locks the page behind it.
Either way it’s a panel that slides in from a screen edge to hold navigation or context-specific content, then hides so the main view keeps its space. Mobile apps mostly use it for navigation destinations. Web apps put filters, settings, carts and detail views in it.
Focus handling, dismissal and screen-size rules all follow from which of the two behaviors a team builds.
What Is a UI Drawer?
The job is simple. A panel comes in from an edge on demand, holds app destinations, filters, settings, a cart or a short form, and goes away again.
The term is looser than it looks, though. Design systems don’t agree on it. Material 3 uses it for a list of app destinations that is modal on compact screens and docked beside content on large ones (SAP Fiori guidance for Material 3). Atlassian’s Drawer is a modal dialog that appears from the side, built for secondary tasks.
PatternFly’s version slides in on the right by default and can either overlay the page or sit inline beside it. shadcn’s Drawer, the Radix version built on Vaul, is a draggable panel that comes up from the bottom and closes with a downward swipe. Its newer Base UI version replaces Vaul with Base UI.
Here, a drawer means the overlap between all of them, an edge-anchored panel that appears on demand. Systems that behave differently get named where it matters.
Other names for a drawer
Navigation drawer is the Material and Android term. Designers also say side menu, off-canvas menu, side panel and slide-out menus for the same family of panels.
In code the names shift again. Android has DrawerLayout, Flutter has a Drawer widget, and Bootstrap calls it Offcanvas.
What a drawer is not
A hamburger icon is only a trigger. The panel is the thing that opens.
A centered modal dialog is closer kin. A modal drawer blocks the page the way a modal dialog does, but it stays anchored to an edge and the page stays visible around it.
Then there’s the macOS window drawer. Early Mac OS X apps used drawers that popped out beside the window frame, and Mail listed mailboxes in one until Mac OS X 10.4 Tiger replaced it with a sidebar.
Apple’s OS X Human Interface Guidelines, quoted in Wikipedia’s sidebar entry, tell designers to avoid drawers in new Mac apps. It’s a different component from the one covered here.
Parts of a UI Drawer and Where It Sits on Screen
Most drawers have a container, a header with the title and close control, and a scrollable content area. Modal ones add a scrim behind it. Footer actions are optional.
Naming varies by system. GitLab Pajamas breaks the component into a container, header, title, close button, optional top-level actions, content and optional contextual actions. The Material Components for Android docs for Material 3 go with container, headline, label text, icon, active indicator, badge label text and scrim.
When content overflows, GitLab scrolls it under the header, so the title and close button stay put.
Edge defaults split by system. Material UI’s Drawer and React Native’s DrawerLayoutAndroid open from the left (the React Native component is now deprecated in favor of react-native-drawer-layout). PatternFly, GitLab Pajamas and Ant Design default to the right, although PatternFly also allows left and bottom. Vaul defaults to the bottom, and shadcn’s Radix-based Drawer inherits that.
MUI’s anchor prop accepts left, right, top and bottom. Material 3 flips the navigation drawer to the right edge in right-to-left languages (SAP Fiori guidance).
Navigation destinations are the classic contents. Filters, settings, detail views and short forms get put in drawers too.
In app and site navigation, destinations sit under non-interactive section titles, with optional icons and trailing counters that flag changed data (Android’s legacy navigation drawer pattern).
Filters, settings and detail views are a different job. Atlassian recommends a drawer for a secondary task that keeps people on the page they are working on, and GitLab wants the copy inside kept short and plain, with something the user can act on.
Standard, Modal, Inline and Bottom Drawer Types
Material defines the standard and modal types, PatternFly adds overlay and inline, and the Vaul and shadcn component set contributes the bottom drawer.
| Type | Effect on the page | Scrim | Defined by |
|---|---|---|---|
| Standard | Sits beside content | None | Material 3 |
| Modal | Covers content, blocks interaction | Yes | Material 3, Atlassian |
| Overlay | Covers content until closed | Shadow only | PatternFly |
| Inline | Shares the screen, page compacts | None | PatternFly, GitLab (embedded) |
| Bottom | Slides up, drag handle | Optional overlay | Vaul, shadcn |
Standard vs modal navigation drawers
The scrim is the dividing line, and in my view it’s the quickest way to tell the two apart. SAP’s Material 3 guidance makes it available only for the modal drawer, where it blocks interaction with the app content.
MUI slices it a little differently. Its temporary variant is the modal pattern and the default, opening above content with a backdrop. Persistent toggles open and closed at the same elevation as content, which resizes around it. Permanent is always visible and can’t be closed, and MUI’s docs recommend it as the desktop default.
Visa’s design system adds a rule against shifting page content to fit a navigation drawer. If users need the page while they navigate, it points to vertical navigation instead.
Overlay vs inline drawers
In PatternFly, an overlay drawer appears on top of the page, and the covered content stays unreadable until the drawer is minimized or closed. An inline drawer sits beside the page and compacts it, like a split screen.
GitLab Pajamas defaults to overlay. Its embedded variant pushes content aside when full-width page elements should stay uncovered.
Bottom drawers
Bottom drawers swap the close button for a gesture, with a drag handle and swipe-to-dismiss.
In shadcn’s component set, the Vaul-based Drawer is the drag-to-dismiss option, while Sheet extends Radix Dialog for edge panels without drag gestures. MiHCM’s design system advises Dialog or Sheet on desktop, because bottom sheets feel out of place on wide viewports.
Drawer behavior by screen size
SAP Fiori’s Material 3 guidance (v26.4) recommends a permanently visible standard drawer for windows wider than 1200dp.
On compact screens that means a modal drawer. Medium screens get a navigation rail instead, and the rail can open into a modal drawer if there are more destinations. Past that, wide screens use the permanent standard drawer or a rail that expands into a modal one.
MUI documents the same idea with its temporary variant for small screens and permanent for wider ones.
This is responsive design applied to one component. The drawer changes type at breakpoints instead of just shrinking.
At its smallest breakpoint, GitLab’s drawer takes up the full viewport width.
How a UI Drawer Opens and Closes
A drawer opens when the user does something on purpose, like tapping a menu icon, pressing a button or swiping in from the edge. It closes through a close control, a scrim tap, the Esc key or a swipe back toward its edge.
GitLab’s Pajamas rule covers the opening half. A drawer should never take the user by surprise, so a user action always opens it.
The usual trigger is a menu icon, most often a hamburger menu button. On Android, the drawer is also reachable by swiping in from the left edge.
React Native’s DrawerLayoutAndroid wrapper (now deprecated) has lock modes too. Unlocked is the default and responds to touch gestures. Locked-closed stays shut and ignores gestures, and locked-open does the same while staying open.
React Native’s docs note that a locked-open drawer can still be opened and closed through code.
Closing paths depend on who wrote the guidance.
Touch-first guidance (SAP Fiori, Material 3) has people pick a destination, tap the scrim, swipe toward the anchoring edge or press Back. Desktop-first systems like Atlassian, GitLab and MUI lean on the close control and Esc. Atlassian and MUI also close on a click of the blanket or overlay, while GitLab’s Pajamas lists only the close button and Esc.
A drawer used on both screen types needs every one of those paths.
On timing, UCL’s design system opens its drawer in 300 ms with ease-out and closes it in 200 to 250 ms with ease-in, while GitLab’s Pajamas uses 200 ms with ease-in.
When Should You Use a UI Drawer?
Use a drawer when the destinations outnumber what a tab bar or navigation bar can hold, or when a secondary task should stay on the current page. For a handful of top-level destinations, visible navigation wins.
Sources disagree on where that line sits. Android’s legacy navigation drawer pattern says more than 3 top-level views. Nielsen Norman Group (2016) says 4 or fewer top-level links should stay visible on a phone, and more than 4 justifies hiding some. SAP Fiori’s Material 3 guidance (v25.4) says 5 or more destinations, with a navigation bar below that on compact screens.
Read together, they land between 4 and 5 destinations. The Android number is the oldest of the bunch and the outlier.
Equinor’s design system names the drawer for two or more levels of navigation hierarchy. Other good cases are more sections than fit as tabs in a top bar, and cross-navigation between lower-level screens (legacy Android guidance). GitLab Pajamas defines the component by a different use, context-specific information or actions that shouldn’t take the user off the page.
UCL’s design system says to skip the drawer when there are only a few navigation items. Key actions that need to stay visible are a bad fit too, and so is critical content that shouldn’t wait behind a tap.
In practice I’d start by counting destinations, then look at screen width. After that comes the question of whether people need the page visible while the drawer is open. Visa’s design system limits navigation drawers to small responsive screens and native apps, which matches the width check.
If people do need the page visible, an inline drawer or a permanent sidebar fits better than a modal one.
UI Drawer vs Sidebar, Bottom Sheet, Tab Bar and Modal
A tab bar suits a few core destinations. Once the screen gets wide, a rail or sidebar takes over, and the drawer covers the long tail. One focused task goes in a modal or bottom sheet.
| Component | Fits | Visibility | Screen size |
|---|---|---|---|
| Tab bar or navigation bar | 2 to 5 core destinations | Always visible | Compact |
| Navigation rail | 3 to 7 destinations | Always visible | Medium and up |
| Sidebar | Many destinations, deep hierarchy | Visible, can collapse | Large |
| Drawer | 5 or more destinations, side tasks | Hidden until opened | Compact (modal), large (standard) |
| Bottom sheet or modal | One focused or contextual task | Interrupts the page | Any |
The tab bar and rail ranges come from SAP Fiori’s Material 3 component guidance.
On wide screens, a permanent sidebar navigation pane replaces the drawer. Apple’s sidebar guidance tells designers not to hide a sidebar by default, so it stays discoverable.
Apple handles overflow without a drawer at all. On iPad, an app’s tab bar can convert into a sidebar when there are more areas than fit. On iPhone, the extra tabs fall into a More tab, which Apple’s guidance tells designers to limit.
Where design systems are moving
Material and Atlassian are both moving away from the drawer.
For Material 3 Expressive, the Material Components for Android docs say the expanded navigation rail is meant to replace the navigation drawer. The standard and modal drawers described earlier still ship, though, and Compose’s Material 3 API reference lists all three navigation drawer composables next to WideNavigationRail and ModalWideNavigationRail.
The sources split on phones. 9to5Google (May 2025) read the change as leaving phones without a drawer replacement, while SAP’s Fiori guidance (v26.4) flags the drawer as deprecated yet still describes a modal drawer for compact screens with five or more destinations, and its navigation rail page points compact screens to the navigation bar.
Atlassian’s docs say Drawer is planned for deprecation in favor of Modal and should not be used with the new navigation system. The secondary-task advice cited earlier is therefore guidance for a component on its way out.
When a UI Drawer Hurts Usability
A drawer hurts usability when it hides navigation people need, and the damage is largest on desktop. Nielsen Norman Group put numbers on it with 179 participants across 6 websites.
The study ran in December 2015 and was published in June 2016. On desktop, navigation use was 27% with hidden menus, against 48% with visible navigation and 50% with combo navigation. Content discoverability was more than 20% lower with hidden navigation, and desktop tasks took at least 39% longer. Perceived difficulty came out 21% higher than with visible navigation (mobile and desktop combined).
The study tested hidden main navigation on websites, and the hamburger icon is the usual trigger for a drawer. Treat it as the best measured evidence for the pattern, not a drawer-specific benchmark.
Its conclusion is aimed at mobile-first design ported to desktop unchanged. NN/g’s wording was that mobile-first should not equal mobile-only.
Primary navigation on desktop is the biggest problem. NN/g advises against hidden navigation in desktop interfaces and recommends showing top-level options across the top or down the left side.
Tasks that need the page behind the drawer are another one, since Atlassian warns that background content stays inert while a modal drawer is open. A task that references that content doesn’t belong inside.
And then there’s the trigger nobody sees. On Bloomberg’s phone site, a small unlabeled arrow icon sat beside the logo and participants often missed the navigation altogether, while SupermarketHQ’s wide Browse button drew the most use.
On phones, the same study found a smaller usability penalty. NN/g still recommends hiding links when a site has more than 4 top-level ones.
The fixes are cheap. Label the icon with the word “Menu” and keep it visually distinct from the logo. Exposing some links outside the drawer (combo navigation) helps too. All of that is NN/g advice.
Android’s legacy guidance adds one more, which is to open the drawer automatically on first launch and keep doing so until the user opens it manually.
NN/g calls the hamburger an imperfect answer to the small-screen constraint that works acceptably when nothing else competes for the tap. It also notes that hiding hurts most for content with no direct in-page link.
How to Build an Accessible UI Drawer
A modal drawer should behave like a dialog. It gets a name, takes focus when it opens, keeps Tab inside, closes on Esc and hands focus back to its trigger.
The ARIA Authoring Practices Guide defines that pattern. Bootstrap’s docs treat its offcanvas as a modal dialog and add the dialog role through JavaScript.
Accessibility steps for a modal drawer
- Name the drawer. Give it a visible title and point aria-labelledby at it. Atlassian requires a title or label, and Flutter’s Drawer takes a semanticLabel.
- Move focus in on open. Atlassian and Chakra UI send focus to the first focusable item, and Chakra’s initialFocusEl overrides that when the drawer holds a form.
- Trap Tab inside while the drawer is modal. The ARIA Authoring Practices Guide and GitLab Pajamas both describe an intentional keyboard trap.
- Close on Esc. It is the default in the APG pattern, Radix UI, Chakra UI, Ant Design, Bootstrap and Flutter.
- Make the page inert. The APG says windows under a modal dialog cannot be interacted with, and aria-modal=”true” signals that to assistive technology.
- Return focus to the trigger on close. Atlassian, Chakra UI and the APG all specify it.
The trap is allowed. WCAG 2.1.2 (No Keyboard Trap) accepts a restricted focus region as long as people know how to leave it, and Esc is that exit.
WCAG 2.2, a W3C Recommendation since 5 October 2023, adds SC 2.4.11 (Focus Not Obscured, Minimum). A non-modal drawer that entirely hides the focused element behind it fails that criterion.
Bootstrap’s docs add a caveat. Dismissing an offcanvas from a button outside it does not match the APG dialog pattern.
Component libraries that ship a drawer
Native mobile
- Android’s DrawerLayout hosts the drawer view, with a NavigationView inside it for the modal variant (Material Components for Android docs).
- Jetpack Compose ships ModalNavigationDrawer, DismissibleNavigationDrawer and PermanentNavigationDrawer.
- Flutter’s Drawer sits in a Scaffold, gets its menu icon from the AppBar, and lets the Scaffold handle the edge swipe. Flutter’s docs prefer NavigationDrawer for Material 3 apps.
React component libraries
- MUI’s SwipeableDrawer adds touch gestures and keeps its contents mounted in the DOM by default.
- Ant Design’s Drawer defaults placement to right, closes on a mask click or Esc, and nested drawers push each other aside.
- Chakra UI’s Drawer is built on Chakra’s Dialog, so focus trap and focus return come built in.
- Radix UI Dialog isn’t a drawer, but it’s a modal and non-modal primitive that follows the WAI-ARIA dialog pattern. shadcn’s Radix-based Drawer builds on Vaul, which in turn sits on Radix Dialog, while its Sheet extends Radix Dialog directly (shadcn docs). shadcn’s newer Base UI Drawer no longer uses Vaul.
CSS framework
Bootstrap 5.3 Offcanvas has no default placement, so you pick start, end, top or bottom. Its backdrop option takes true, false or static, and responsive variants such as offcanvas-lg turn the panel into regular content above a breakpoint.
Whatever the library, test the finished drawer against a web accessibility checklist, with keyboard only first and a screen reader second.
UI Drawer FAQ
Can more than one drawer be open at once?
Usually not. Bootstrap’s docs state that only one offcanvas can be shown at a time.
Ant Design is an exception. Its Drawer has a push option that shifts the parent aside when a nested drawer opens, and shadcn’s Base UI drawer also supports nesting.
How wide should a drawer be?
Published defaults run from 360dp to 400px. Material 3 sets the navigation drawer container at 360dp, while GitLab Pajamas and Bootstrap’s offcanvas both default to 400px.
Atlassian skips a single number and offers five named sizes, from narrow to full.
How long should a drawer’s slide animation take?
Roughly 200 to 300 ms. GitLab’s Pajamas uses 200 ms, UCL’s design system uses 300 ms to open and 200 to 250 ms to close, and Bootstrap’s offcanvas defaults to 0.3 s.
Bootstrap also ties the animation to the prefers-reduced-motion media query, and a custom drawer should respect the same setting.
Who designed the hamburger icon?

Norm Cox drew it for the Xerox Star workstation, released in 1981. By his account, the aim was road-sign simplicity and a shape that mimics the menu list it opens.
The icon returned in mobile apps from 2009, when phone screens left little room for visible navigation.
Testing a UI Drawer Before It Ships
Test the drawer against a visible-navigation variant of the same screens, using real tasks, before release.
Nielsen Norman Group (NN/g) advises a usability test tailored to the design and its users, since navigation guidelines depend on context.
On phones, NN/g measured navigation use at 57% with hidden navigation and 86% with combo navigation (2016). That 29-point gap is what a few exposed links beside the drawer can buy, at the cost of screen space.
Start with a keyboard-only and screen reader pass, since it needs no participants and mishandled focus would distort the user test that follows. After that, build prototypes with visible, combo and drawer navigation and measure task success and time on task with real users.
As of October 2026, Material 3 Expressive points navigation drawers toward the expanded navigation rail, so a Material app should re-test after migrating.
The same focus checks carry over to other accessible UI components in the interface.
- How to Insert Image in Figma With Ease - November 3, 2026
- How to Download Figma Files Fast and Free - October 30, 2026
- Figma Keyboard Shortcuts That Will 10x Your Speed - October 25, 2026


