---
title: Grouped List
slug: grouped-list
kind: pattern
summary: One collection divided into labelled sections with counts, so the shape of the set is visible before any individual row is read.
problem: >-
  A flat list of eighty items hides its own structure. Sixty are routine and
  twenty need attention, and the only way to learn that is to read all eighty —
  so people either read everything or miss the twenty.
family: [scan]
data_shape: [collection, tabular]
principles: [progressive-disclosure, minimize-distance, orientation]
interaction: [scanning, disclosure]
density: medium
complexity: low
status: stable
visibility: public
use_when:
  - Records fall into a small number of meaningful groups people already think in.
  - Group membership changes what someone does with a record.
  - The distribution across groups is itself useful information.
avoid_when:
  - Groups would be many and small — twenty groups of two is a worse list than one of forty.
  - People compare across the whole set on one metric. Grouping breaks the single sorted order that makes that possible.
  - Membership is arbitrary, so the headings teach nothing.
alternatives:
  - slug: filter-bar
    when: People want one group at a time rather than all of them at once.
  - slug: dense-operational-table
    when: A single sort order across the whole set answers the question better than sections do.
ask_leo: |
  Group this list into labelled sections.

  - Group by the attribute that changes what someone does — usually status,
    owner, or due window. Not by an attribute that is merely true.
  - Give every group a heading with its name and a count.
  - Order the groups deliberately, most urgent or most actionable first. Do not
    order them alphabetically unless that genuinely is the priority.
  - Keep group headings visible while their rows scroll.
  - Let groups collapse, remember which are collapsed, and keep the count
    visible on a collapsed group so nothing disappears silently.
  - Always show a group that is empty but meaningful — "Overdue (0)" is
    information. Hide groups that are empty and merely possible.
  - Sort inside each group by the same rule, so the sections read consistently.
related:
  - title: Dense Operational Table
    url: /patterns/dense-operational-table
    summary: The ungrouped baseline — grouping is a layer on top of it.
  - title: Progressive disclosure
    url: /patterns/progressive-disclosure
    summary: Collapsed groups are disclosure with a visible door.
---

## Anatomy

```
▾ Needs attention (3)                      ← ordered by urgency, not A–Z
    INV-1041  Riverside Fit-Out   12d overdue
    INV-1043  Kestrel Joinery      4d overdue
    INV-1046  Kestrel Marine       9d overdue
▾ Due this week (2)
    INV-1049  Marlow & Sons        due Thu
    INV-1051  Harbour Depot        due Fri
▸ Paid (14)                                ← collapsed, count still visible
▾ Overdue over 90 days (0)                 ← empty but MEANINGFUL, so shown
```

- **Counts on every heading.** The counts are often more useful than the rows;
  they are the summary the list would otherwise make people compute.
- **Deliberate group order.** Alphabetical is a decision not to have decided.
- **A collapsed group keeps its count**, so collapsing hides detail without
  hiding existence.
- **Meaningful empty groups stay.** "Overdue (0)" is a fact worth reading.

## Why it works

It turns a list into a **shape**. Before reading any row, a person learns the
distribution — three urgent, two soon, fourteen done — and that distribution is
usually the actual answer to why they opened the screen.

It is progressive disclosure applied horizontally rather than vertically: the
headings are the overview layer, the rows are the detail, and collapsing is the
visible door between them. Because the door carries a count, nothing is ever
hidden without leaving a trace.

Grouping also places related things adjacent, which is the
[minimize distance](/patterns/minimize-distance) principle doing its work — the
three overdue invoices are next to each other, so comparing them costs a glance.

## The trade you are making

Grouping **destroys the single sorted order**. In a flat table, "the largest
amount" is the top row. In a grouped list it is the largest within one of five
sections, and finding it means scanning all five.

So group when the *category* drives the work, and keep it flat when a *metric*
does. Both are legitimate; the mistake is grouping by habit and then wondering
why the list is harder to compare.

## Getting it wrong

- **Too many groups.** Twenty sections of two rows is more chrome than content.
- **Alphabetical group order** on categories that have an obvious urgency order.
- **Counts missing**, which throws away most of the benefit for none of the
  cost saved.
- **Collapsed groups that forget**, so every visit starts with the same
  re-collapsing.
- **Hiding empty groups indiscriminately**, so "no overdue invoices" — good news
  someone wants — silently looks identical to the group not existing.

## Exemplars

**Gmail's date grouping** — Today, Yesterday, Earlier — is grouping by the
attribute that actually changes behaviour, and it is why the inbox reads as a
shape rather than a stream.

**Linear's grouped issue list** lets the grouping attribute be switched
(status, assignee, priority) which makes the trade explicit: you choose which
question the list is currently good at answering.

**Things and other task managers** converge on Today / Upcoming / Someday, which
is the same insight — the grouping people want is the one that maps to when they
will act.

The extractable rule: **group by what changes the work, and put the count in the
heading.** If the headings do not change anyone's behaviour, the list was better
flat.
