One thing per page pattern
patterns specs/patterns/one-thing-per-page.kmd
A form-design constraint: each page in a flow asks the user for ONE thing — one decision or one logically-grouped piece of information — with a single primary action. Reduces cognitive load, makes validation and error recovery trivial, and is the structural reason multi-step wizards work on small screens and for assistive tech. Modeled after the GOV.UK "one thing per page" service-design principle.
Quando este padrão se aplica
Triggers primários
- Design the page-granularity of a form journey
Todos os triggers
- Decide how much to ask on a single form page
- Split a long single-page form into a sequence
- Design a step of a multi-step flow
Corpo da especificação
Pattern — One thing per page
Status: v0.1.0 — Draft. Promoted from the GOV.UK parity scan (meta/docs/stack #096). A design constraint applied BY
specs/patterns/wizard-multistep.kmd(each wizard step honors it). Source: https://www.gov.uk/service-manual/design/structuring-forms
R1 — The constraint
Each page asks for one thing. "One thing" is one decision or one logically-inseparable group of fields — not literally one input. A page may hold multiple fields when they describe a single concept:
- ✅ One thing: a postal address (several fields, one concept).
- ✅ One thing: a date of birth (day/month/year).
- ❌ Two things: "address AND date of birth" on one page.
When in doubt, split. Pages are cheap; a confused or error-prone user is not.
R2 — What each page has
| Element | Required | Notes |
|---|---|---|
| One question heading | Yes | The page <h1> IS the question ("What is your address?") |
| Field(s) for that one thing | Yes | Grouped in a <fieldset>+<legend> when multi-field |
| One primary action | Yes | A single forward button ("Continue" / "Save and continue") |
| Back link | Yes | To the previous page; preserves entered data (specs/navigation/back-behavior.kmd) |
| Inline help | Optional | Hint text under the heading, before the field |
There is at most ONE primary button. Secondary paths (e.g. "I don't have this") are links or a clearly secondary control, never a second primary.
R3 — Why split (rationale, normative intent)
- Validation becomes per-thing: one page can only fail for one
concept, so error messages are unambiguous (pairs with
specs/errors/user-facing-messages.kmdand the error-summary component). - Cognitive load: the user makes one decision at a time.
- Small screens & AT: one thing fits a phone viewport
(
specs/app-layout/safe-area.kmd) and a single screen-reader pass. - Branching: the answer to one page can route the next page
(see
specs/patterns/wizard-multistep.kmdR1 branching).
R4 — When to group vs split
- Group fields that the user thinks of as one item AND that are always needed together (address, full name, date).
- Split when fields are independently optional, independently validated, or conditionally shown.
- Never group merely to save pages — page count is not a cost to optimize against the constraint.
R5 — Relation to wizard & task list
- A
wizard-multistepstep SHOULD be one-thing-per-page; this spec is the per-step granularity rule the wizard composes. - A
task-listtask is itself a short one-thing-per-page sequence. - Koder Sign's multi-step signing flow applies this constraint: each required field/decision (place signature, confirm intent, provide reason) is its own page/step.
R6 — Accessibility & i18n
- The single question is the page
<h1>; the field's label/legend is the same question (no orphan placeholder-as-label). - Focus on page enter lands on the heading or first field per
specs/navigation/back-behavior.kmd. - Each page's strings are independent i18n keys
(
specs/i18n/contract.kmd); splitting/grouping decisions are language- invariant (do not regroup pages per locale).
Não-escopo
- The step indicator / progress UI (in
wizard-multistep.kmd). - Field-level component specs (text field, date input, radios — under
specs/components/). - Server-side persistence of partial answers (multi-tenancy contract).
Referências
specs/patterns/wizard-multistep.kmdspecs/patterns/task-list.kmdspecs/errors/user-facing-messages.kmdspecs/app-layout/safe-area.kmd