Interface craft
This is about product UI: the screens someone opens for the fifth time
today to get something done. Different goals from a landing page — a landing
page must be memorable, a tool must be forgettable, because attention spent on
the interface is attention taken from the work.
1. One primary action per screen
Decide what this screen is for and let exactly one thing look like the
answer. Everything else steps down: secondary buttons, tertiary links, items in
a menu.
Three buttons of equal weight means the design has not decided, and the user
has to. Count the things competing for attention on each screen; if it is more
than one, the fix is demotion, not rearrangement.
Corollary: if the primary action is unclear to you, the requirements are
unclear. Go back rather than designing around it.
2. Density is a decision, matched to frequency
| Used |
Wants |
| Once (signup, setup) |
Generous space, one thing at a time, guidance |
| Daily |
Moderate density, keyboard access, few clicks |
| All day (an operator's console) |
High density, everything visible, no wizards, no animations |
Applying onboarding spaciousness to a tool someone lives in makes them scroll
all day. Applying console density to a first-run flow overwhelms. Pick per
screen, not per product, and say which you picked.
3. Hierarchy comes from structure, not decoration
Size, weight, spacing and position carry the hierarchy. Colour, borders and
shadows are for grouping and state — using them to signal importance runs out
quickly and fails for anyone who cannot distinguish them.
- Group with proximity and whitespace before reaching for a card or a border. A
page where every group is a bordered card has flattened its own hierarchy.
- A consistent spacing scale (4 / 8 / 12 / 16 / 24 / 32) does more for
perceived quality than any individual choice within it.
- Align to a grid and keep to it. Misalignment is the thing people notice
without being able to name.
4. Forms
Where most product UI lives, and where most of it is careless.
- Labels above fields, always visible. Placeholder-as-label disappears the
moment someone types and is unreadable for low vision.
- One column. Multi-column forms cause skipped fields. Two fields side by
side only when they are genuinely one thing (city/postcode, expiry/CVC).
- Validate on blur and on submit, not on every keystroke. Never mark a field
invalid before it has been left.
- Never clear input on error. Especially passwords, and especially on
mobile.
- Say what is required, and mark the smaller set — if most fields are
required, mark the optional ones instead.
- The right keyboard and autofill on mobile:
type, inputmode,
autocomplete. Making someone switch to the numeric keyboard for a phone
number is a small insult repeated thousands of times.
- Submit must be reachable with the on-screen keyboard open.
- Errors in a summary at the top for long forms, each linking to its field.
- Preserve a draft for anything long. Browsers crash and sessions expire.
5. Tables and lists
- Decide what is sortable, what is filterable, and what the default order is —
and make the default the one people want most days.
- Sticky header once the list is taller than the viewport.
- Right-align numbers, use tabular figures so digits line up, and keep units and
precision consistent down a column.
- Decide the row action. Clicking the row, a trailing menu, or an explicit
button — one of them, consistently, everywhere.
- Paginate or virtualise past a threshold you have chosen, and show the total.
"Showing 50 of 12,480" is information; a silently truncated list is a bug.
- Bulk actions need a clear selection count and an undo.
- On narrow screens a table becomes a list of cards, not a horizontally
scrolling table, unless comparing columns is the whole point.
6. Feedback timing
Three thresholds worth designing to:
| Under |
The user perceives |
So |
| ~100 ms |
Instant |
Acknowledge every press within this, even if the work continues |
| ~1 s |
A pause |
No spinner needed, but do not let the UI appear frozen |
| ~10 s |
Lost attention |
Progress, an estimate, or hand it off and notify |
Latency you cannot remove can still be made to feel shorter by responding
immediately and filling the wait with the shape of what is coming.
7. Destructive actions
- Prefer undo over confirm. A confirm dialog is dismissed on reflex; an undo
window is forgiving of the mistake that actually happened.
- Where confirmation is warranted, name the object and its consequences —
"Delete North Depot and its 214 records?" — and do not focus the destructive
button by default.
- Keep destructive controls physically away from the ones next to them in the
flow. Adjacent Save and Delete is a trap.
- Soft-delete wherever you can, so undo is real rather than a promise.
8. Consistency is a feature
- One action has one name everywhere. The button that says Publish produces a
message that says Published.
- The same kind of object looks the same wherever it appears.
- Do not invent a control that already exists in the platform. A custom select
loses keyboard support, screen-reader support, mobile native pickers and
autofill, in exchange for looking slightly different.
- Follow the platform's conventions for back, dismiss, and where the primary
button sits in a dialog. Users have expectations from everything else they
use.
9. The accessibility floor
Not a phase. A floor, and it is low:
- Keyboard reachable, in a sensible order, with a visible focus ring.
Never remove the outline without replacing it.
- Contrast at least 4.5:1 for body text, 3:1 for large text and for the
boundaries of controls.
- Never colour alone for state — pair it with a shape, an icon or a word.
- Labels on everything, including icon-only buttons.
- Announce what changed. A live region for anything that updates without a
page change, so it is not silent for a screen reader.
- Respect
prefers-reduced-motion.
- Touch targets at least 44×44 px with spacing between them.
- Test one flow with the keyboard alone, and one with a screen reader. Both take
minutes and both find things.
10. Motion earns its place
In product UI, motion has one job: showing what changed and where it came from.
An item moving to the place it now lives, a panel opening from the control that
opened it, a row settling after a sort.
Decorative entrance animations on every card are noise at first sight and
friction by the fiftieth. Keep transitions fast — 150–250ms — and skip them
entirely for anything used repeatedly.
Checklist
1---2name: interface-craft3description: Build or review product UI — the screens people use repeatedly to do a job, as opposed to a marketing page. Covers hierarchy, density, forms, tables, feedback timing, destructive actions, consistency and an accessibility floor. Use when building an app screen, a dashboard, a settings page, an admin console or a form, and when reviewing one.4---56# Interface craft78This is about **product UI**: the screens someone opens for the fifth time9today to get something done. Different goals from a landing page — a landing10page must be memorable, a tool must be forgettable, because attention spent on11the interface is attention taken from the work.1213## 1. One primary action per screen1415Decide what this screen is *for* and let exactly one thing look like the16answer. Everything else steps down: secondary buttons, tertiary links, items in17a menu.1819Three buttons of equal weight means the design has not decided, and the user20has to. Count the things competing for attention on each screen; if it is more21than one, the fix is demotion, not rearrangement.2223Corollary: if the primary action is unclear to you, the requirements are24unclear. Go back rather than designing around it.2526## 2. Density is a decision, matched to frequency2728| Used | Wants |29|---|---|30| Once (signup, setup) | Generous space, one thing at a time, guidance |31| Daily | Moderate density, keyboard access, few clicks |32| All day (an operator's console) | High density, everything visible, no wizards, no animations |3334Applying onboarding spaciousness to a tool someone lives in makes them scroll35all day. Applying console density to a first-run flow overwhelms. Pick per36screen, not per product, and say which you picked.3738## 3. Hierarchy comes from structure, not decoration3940Size, weight, spacing and position carry the hierarchy. Colour, borders and41shadows are for grouping and state — using them to signal importance runs out42quickly and fails for anyone who cannot distinguish them.4344- Group with proximity and whitespace before reaching for a card or a border. A45 page where every group is a bordered card has flattened its own hierarchy.46- A consistent spacing scale (4 / 8 / 12 / 16 / 24 / 32) does more for47 perceived quality than any individual choice within it.48- Align to a grid and keep to it. Misalignment is the thing people notice49 without being able to name.5051## 4. Forms5253Where most product UI lives, and where most of it is careless.5455- **Labels above fields**, always visible. Placeholder-as-label disappears the56 moment someone types and is unreadable for low vision.57- **One column.** Multi-column forms cause skipped fields. Two fields side by58 side only when they are genuinely one thing (city/postcode, expiry/CVC).59- **Validate on blur and on submit**, not on every keystroke. Never mark a field60 invalid before it has been left.61- **Never clear input on error.** Especially passwords, and especially on62 mobile.63- **Say what is required**, and mark the smaller set — if most fields are64 required, mark the optional ones instead.65- **The right keyboard and autofill** on mobile: `type`, `inputmode`,66 `autocomplete`. Making someone switch to the numeric keyboard for a phone67 number is a small insult repeated thousands of times.68- **Submit must be reachable** with the on-screen keyboard open.69- **Errors in a summary at the top** for long forms, each linking to its field.70- Preserve a draft for anything long. Browsers crash and sessions expire.7172## 5. Tables and lists7374- Decide what is sortable, what is filterable, and what the default order is —75 and make the default the one people want most days.76- Sticky header once the list is taller than the viewport.77- Right-align numbers, use tabular figures so digits line up, and keep units and78 precision consistent down a column.79- Decide the row action. Clicking the row, a trailing menu, or an explicit80 button — one of them, consistently, everywhere.81- Paginate or virtualise past a threshold you have chosen, and show the total.82 "Showing 50 of 12,480" is information; a silently truncated list is a bug.83- Bulk actions need a clear selection count and an undo.84- On narrow screens a table becomes a list of cards, not a horizontally85 scrolling table, unless comparing columns is the whole point.8687## 6. Feedback timing8889Three thresholds worth designing to:9091| Under | The user perceives | So |92|---|---|---|93| ~100 ms | Instant | Acknowledge every press within this, even if the work continues |94| ~1 s | A pause | No spinner needed, but do not let the UI appear frozen |95| ~10 s | Lost attention | Progress, an estimate, or hand it off and notify |9697Latency you cannot remove can still be made to feel shorter by responding98immediately and filling the wait with the shape of what is coming.99100## 7. Destructive actions101102- Prefer undo over confirm. A confirm dialog is dismissed on reflex; an undo103 window is forgiving of the mistake that actually happened.104- Where confirmation is warranted, name the object and its consequences —105 "Delete *North Depot* and its 214 records?" — and do not focus the destructive106 button by default.107- Keep destructive controls physically away from the ones next to them in the108 flow. Adjacent Save and Delete is a trap.109- Soft-delete wherever you can, so undo is real rather than a promise.110111## 8. Consistency is a feature112113- One action has one name everywhere. The button that says *Publish* produces a114 message that says *Published*.115- The same kind of object looks the same wherever it appears.116- Do not invent a control that already exists in the platform. A custom select117 loses keyboard support, screen-reader support, mobile native pickers and118 autofill, in exchange for looking slightly different.119- Follow the platform's conventions for back, dismiss, and where the primary120 button sits in a dialog. Users have expectations from everything else they121 use.122123## 9. The accessibility floor124125Not a phase. A floor, and it is low:126127- **Keyboard reachable**, in a sensible order, with a **visible focus ring**.128 Never remove the outline without replacing it.129- **Contrast** at least 4.5:1 for body text, 3:1 for large text and for the130 boundaries of controls.131- **Never colour alone** for state — pair it with a shape, an icon or a word.132- **Labels on everything**, including icon-only buttons.133- **Announce what changed.** A live region for anything that updates without a134 page change, so it is not silent for a screen reader.135- **Respect `prefers-reduced-motion`.**136- **Touch targets** at least 44×44 px with spacing between them.137- Test one flow with the keyboard alone, and one with a screen reader. Both take138 minutes and both find things.139140## 10. Motion earns its place141142In product UI, motion has one job: showing what changed and where it came from.143An item moving to the place it now lives, a panel opening from the control that144opened it, a row settling after a sort.145146Decorative entrance animations on every card are noise at first sight and147friction by the fiftieth. Keep transitions fast — 150–250ms — and skip them148entirely for anything used repeatedly.149150## Checklist151152- [ ] One primary action per screen; everything else demoted153- [ ] Density chosen to match how often the screen is used154- [ ] Hierarchy from size, weight, spacing and position; a consistent spacing scale155- [ ] Forms: labels above, one column, validate on blur, input never cleared, right keyboard156- [ ] Tables: default sort chosen, totals shown, row action consistent, narrow-screen behaviour decided157- [ ] Acknowledge within ~100ms; progress or handoff beyond ~10s158- [ ] Undo preferred over confirm; destructive controls separated and never default-focused159- [ ] One name per action everywhere; native controls not reinvented160- [ ] Keyboard reachable with visible focus; contrast met; never colour alone; labels on icon buttons161- [ ] Reduced motion respected; motion only where it shows what changed