---
title: Drawer vs Modal vs Page
slug: drawer-vs-modal-vs-page
kind: decision
summary: The decision guide for where a record or task should open. Three surfaces, three different promises about context — pick on the conditions, not on taste.
problem: You have a list and you need somewhere to put the detail. Every team argues this from preference, ships whichever surface someone liked last, and ends up with all three in one app meaning nothing in particular. The choice is actually decidable, and getting it wrong shows up as either lost context or a workflow trapped in a box too small for it.
family: [inspect, act]
data_shape: [record]
principles: [orientation, progressive-disclosure, consistency]
interaction: [disclosure, navigation]
density: medium
complexity: low
status: stable
visibility: public
use_when:
  - You are deciding where a record opens and the team is arguing from preference.
  - An existing screen feels wrong and nobody can say why.
  - You are about to add a third surface to an app that already has two.
avoid_when:
  - The answer is already forced — deep linking is a requirement, or the parent list must stay visible. Then you have a condition, not a choice.
alternatives:
  - slug: master-detail-drawer
    when: You have decided on the drawer and want the detail of building it well.
  - slug: dense-operational-table
    when: The real fix is fewer columns and no detail surface at all.
ask_leo: |
  Before building the detail view, choose the surface deliberately.

  Use a side drawer when the parent list must stay visible, people inspect
  several records in a row, and the detail is about one screenful. Keep the list
  unmoved, put the record id in the URL, and let Escape and browser Back close it.

  Use a modal when the task is short and bounded, interrupting is the point, and
  there is exactly one way out. Never open a modal from a modal. If the modal
  needs its own tabs or a second step, it should be a page.

  Use a full page when the record has real depth, people will spend minutes
  there, it has nested workflows, or the URL needs to be shareable and
  bookmarkable.

  Pick one surface per kind of object and use it everywhere that object appears.
  Do not mix surfaces for the same object in different parts of the app.

related:
  - title: Progressive Disclosure for Dense Detail Pages
    url: /cookbook/progressive-disclosure-detail-page
    summary: What to do once you have chosen the page and it is still too dense.
  - title: Filterable Index with Slide-Out Detail Drawer
    url: /cookbook/filterable-index-with-detail-drawer
    summary: The implementation, if the decision below lands on the drawer.
  - title: UX Principles Guide for Building Web Software
    url: /wiki/ux-principles-for-web-software
    summary: Orientation and progressive disclosure, the two principles this decision trades against each other.
---

## The decision

Start at the top and take the first row that matches. The order matters — the earlier conditions are hard constraints, the later ones are preferences.

| If this is true | Use | Because |
|---|---|---|
| People must link, bookmark or share this record | **Page** | Only a page has a durable, meaningful URL |
| The record contains its own multi-step workflow | **Page** | Nested workflows need room and their own history |
| People will spend more than a couple of minutes here | **Page** | A long stay in a temporary surface feels precarious |
| The parent list must stay visible and in place | **Drawer** | It is the only surface that preserves the collection |
| People inspect several records in sequence | **Drawer** | Replacing panel content beats navigating twice per record |
| The task is short, bounded, and worth interrupting for | **Modal** | Deliberate interruption is the modal's one real strength |
| None of the above | **Page** | The safest default: it can hold anything and always has a URL |

## What each surface actually promises

**A page promises permanence.** It has an address, it can be sent to a colleague, it can hold anything, and browser Back means what people expect. The cost is that it takes the previous context away — which is exactly why it is wrong for sequential inspection and right for deep work.

**A drawer promises the parent stays.** Its entire value is that the list does not move: scroll, sort, filters and your place in the queue all survive. Everything else about a drawer is a detail. If the parent is not visible, or the panel takes so much width the list is unusable, you have built a modal with a slide-in animation and paid for nothing.

**A modal promises this is the only thing that matters right now.** It blocks the page deliberately. That is a strength for a confirm, a short form, a picker — and it is a liability for anything else, because a blocked page cannot be referred to. The classic tell that a modal was the wrong choice: someone needs a value that is behind it.

## The rules that are not negotiable

- **Never open a modal from a modal.** The named anti-pattern is *Modal Maze*. The second modal is the signal that the first one was already carrying too much; promote the whole thing to a page.
- **One surface per kind of object, everywhere.** If a customer opens in a drawer from the list, it must not open in a modal from search and a page from the dashboard. Three surfaces for one object means people learn three mental models for one thing — the same failure as viewing an invoice one way and editing it another.
- **Anything that can be linked to, should be.** A drawer without a URL is a record you found and cannot share. Writing the id into the URL is cheap and turns the drawer into something forwardable.
- **Escape closes, on every surface that floats.** Both drawer and modal. People try it first.

## When the choice is a symptom

Three cases where the argument about surfaces is really an argument about something else:

- **The drawer keeps getting wider.** Every widening is evidence the record deserved a page. Promote it.
- **The modal grew tabs.** A modal with tabs is a page that has not admitted it yet.
- **You need the detail because the table is unreadable.** Sometimes the fix is a better table — the right six columns — and no detail surface at all. Check [the dense operational table](/patterns/dense-operational-table) before building anything.

## Exemplars

**GitHub** is the clearest demonstration of all three in one product, each used correctly: an issue is a **page** because people link to issues constantly and conversation accumulates there for months; the file finder is a **modal** because it is a bounded ten-second task; the pull-request file browser uses **panels** because you are moving through a sequence and the list of files must stay put.

**Linear** shows the drawer at its ceiling — issues open beside the list, and the keyboard moves between them without the mouse. It also shows the escape valve: the same issue has a real URL and a real page, so the drawer never traps anything.

**Stripe** is worth studying for its restraint with modals. Almost nothing is modal, because almost nothing in reading a payment ledger is a bounded interruption. The modals that exist are confirmations and short forms — exactly the surface's job description.

The extractable rule: **the surface is a promise about context.** A page promises a place, a drawer promises the list stays, a modal promises this is the only thing. Break the promise and no amount of polish fixes the screen.
