Master–Detail Drawer | LlamaPress Pattern Catalog
LlamaPress
Scan & Understand
Pattern

Master–Detail Drawer

Keep the list on screen and open the selected record in a panel beside it, so someone can inspect ten records without navigating ten times.

Scan & Understand Inspect

Someone is working through a collection — reviewing signups, checking orders, triaging tickets — and needs the full record for one row, then the next, then the next. A detail page gives them the record but takes the list away, so every inspection costs a round trip and they lose their place in the queue.

Live demo — try it Open full screen
Use when
  • People inspect several records in a row rather than one and stop.
  • Losing your place in the list would be expensive — a sorted queue, a filtered view, a long scroll position.
  • The detail is roughly a screenful. Ten fields and a note, not a nested workflow.
  • Comparison matters — "was the last one like this too?"
Avoid when
  • The record has its own workflows inside it (sub-tabs, a builder, a multi-step form). Give it a page.
  • People need to link, bookmark or share the record. A drawer that does not write the URL cannot be sent to a colleague.
  • The detail genuinely needs the full canvas — a document, a map, a dashboard.
  • The list has one row. Then the list is the ceremony, not the content.

Anatomy

┌───────────────────────────────────┬──────────────────────────────┐
│ Customers            [search   ]  │ Acme Corporation        [×]  │
│                                   │                              │
│ ▸ Acme Corp          Active       │ Status   Active              │
│   Globex             Trial        │ Owner    Dana Whitfield      │
│   Initech            Active       │ MRR      $1,200              │
│   Umbrella           Churned      │ Since    March 2024          │
│   Wonka Industries   Trial        │ ─────────────────────────    │
│                                   │ Notes                        │
│   … list keeps its scroll,        │ Renewed early. Asked about   │
│     sort and filter …             │ the reporting add-on.        │
└───────────────────────────────────┴──────────────────────────────┘
  ▸ = selected row, still visible     panel scrolls independently

Four parts, and all four are load-bearing:

  1. The list, unmoved. It keeps its scroll position, sort order, filters and pagination across every selection. The moment selecting a row disturbs any of those, the pattern has failed — the user is now doing navigation work again.
  2. The selection marker. A left border, a tint, a chevron. Without it the panel is floating detail with no visible source.
  3. The panel. Anchored to one edge, full height, its own scroll. It replaces its content on the next selection rather than closing and reopening.
  4. The exits. Escape, click-outside, and a visible close button. Three, because people reach for different ones and the pattern must not depend on which.

Why it works

It removes navigation from an inspection loop. Reviewing twelve records through detail pages costs twenty-four transitions and twelve chances to lose your place. Through a drawer it costs twelve clicks and none. That is the whole argument, and it is why the pattern earns its complexity.

It preserves spatial context. The list stays where the eye left it, so the user's mental model of "where am I in this queue" survives every inspection. This is the orientation principle doing real work: where am I is answered continuously instead of being rebuilt after each round trip.

It is progressive disclosure with the overview still on screen. Most disclosure patterns trade the overview for the detail. This one keeps both, which is why it suits comparison work — "was the last one like this too?" is answerable without remembering.

It shortens the distance between the row and its detail. The record's name and its facts sit side by side rather than a page apart, so connecting them costs a glance instead of a memory.

Getting it wrong

The four failures worth naming, because each one looks fine in a demo and hurts in daily use:

  • The disappearing list. The panel is modal, or takes 70% of the width, or dims the list to unreadability. Now it is a modal wearing a drawer's clothes, and the context you paid complexity for is gone.
  • No URL. Someone finds the record that explains the problem and cannot send it to anyone. Write the id into the URL; it costs one line and turns the drawer into something shareable.
  • Back leaves the page. The user presses Back expecting the panel to close, and lands on the previous screen with their filters gone. Push a history entry when the panel opens.
  • The drawer that grew. Sub-tabs appear, then a nested form, then a wizard. That is the signal the record deserved a page all along. Promote it rather than widening the panel again.

Exemplars

Linear's issue inspector. Selecting an issue from the list opens it beside the list, and the keyboard moves between issues without touching the mouse — the pattern's real ceiling is reached when the whole loop is keyboard-driven and the list becomes a cursor.

Stripe's payment inspector. A payment opens beside the ledger with the timeline of events first. The lesson worth stealing is the ordering: the panel leads with what happened to this record over time, because that is what someone inspecting a payment came to find out. A drawer's top 200 pixels should answer the question that made you click.

Gmail's reading pane. The oldest version of this pattern in daily use, and the one that proves the split: it survives because the list is a queue people work through in order, not a directory they visit occasionally.

The extractable rule from all three: the drawer belongs to the list, not to the record. It is a way of reading a collection. When the record starts to feel like the subject rather than the current item, it has outgrown the pattern.

Instead of this, consider

Same problem, different trade-off. Pick on the condition, not on taste.

Drawer vs Modal vs Page
When: You are not yet sure which of the three surfaces this record deserves. Start here.
Dense Operational Table
When: People need to compare across records rather than read one deeply. Put more in the row and you may not need a drawer at all.

Ask Leo for this

Paste this into your Leo chat. It describes the behaviour, not the code, so Leo can fit it to your data.

Prompt
Use the master–detail drawer pattern on this screen.

- Keep the list or table exactly where it is. Selecting a row must not scroll,
  re-sort, re-filter or re-paginate it.
- Open the selected record in a panel anchored to the right edge, 420–600px
  wide depending on the content, full height, scrolling independently of the list.
- Mark the selected row so it is obvious which record the panel is showing.
- Selecting another row replaces the panel content in place. Do not close and
  reopen, and do not stack panels.
- Escape closes the panel. So does clicking outside it, and an explicit close
  button in the panel's top corner.
- Put the selected record's id in the URL so the view can be reloaded and shared,
  and make browser Back close the panel rather than leave the page.
- Give the panel a heading that names the record, and put its two or three most
  important facts directly under that heading before any other detail.
- On a narrow screen, show the panel as a full-screen sheet instead of a side
  panel. Do not shrink the layout to fit both.

Related

Cookbook recipe
Filterable Index with Slide-Out Detail Drawer
The Rails, Turbo and Stimulus implementation of this pattern, with the code.
Cookbook recipe
Progressive Disclosure for Dense Detail Pages
What to do when the record turns out to be too big for a drawer after all.
Wiki guide
UX Principles Guide for Building Web Software
The principles this pattern applies — orientation, minimizing distance, and progressive disclosure.