skip to content

In a design handoff for a cloud admin console's resource table, which behaviours must be annotated because a static mockup cannot show them?

level: middleimportance: must knowfreq 50%

answer

  1. a mockup is one moment
  2. loading, empty, error, no permission
  3. longest name, zero rows, many rows
  4. what shrinks, truncates or scrolls
  5. what the screen does after an action

basics

~20 s

Annotate what one frame hides: loading, empty, error and permission states; content extremes and truncation; how the layout resizes; data rules such as default sort; and what changes after an action. Left out, each becomes the engineer's guess.

solid answer

~40 s

A mockup shows one moment with ideal data, so the handoff annotates the rest. **Screen states**: loading, first-use empty versus no results for a filter, whole-table error versus one failing region, and view-only permission. **Content extremes**: a 60-character instance name, zero rows, ten thousand rows, missing values. **Resize rules**: which columns shrink, hide or scroll, what truncates and how the full value stays reachable. **Data rules**: default sort, time format, how each status maps to its indicator. **Outcomes**: what a row shows while a stop is in progress, what happens on failure, where focus lands if the row disappears. A system component's own hover and focus states need no annotation — the component defines them; the handoff covers how *this screen* composes and responds.

go deeper

for a junior

Recall the families of behaviour a single frame hides: screen states, content extremes, resize rules, data rules and action outcomes. Be able to name at least one example of each for a table.

for a middle

Explain why first-use empty and no-results empty differ, why typical data hides the extremes, and why a component's own states belong to the component rather than to every screen's annotations.

for a senior

Show how you would make handoff completeness checkable across teams: a short checklist, reusable patterns pushed into components, and backend state lists feeding design decisions rather than engineering defaults.

for a principal

Weigh annotation cost against guess cost: which behaviour the system should standardise once, which each product decides, and how that split changes as more teams build on the same components.

## Why a mockup under-specifies A static mockup is one frame: one screen width, one set of well-behaved data, one moment in time. Real screens load, fail, overflow, resize and change after the user acts. Every behaviour the frame cannot show is decided by *someone* — and if the handoff does not say, it is decided by whoever writes the code, usually late and under deadline. **Behaviour annotations** are the notes that travel with the frame to close that gap. The test for any screen: *what would an engineer have to guess?* Take the instance table in a cloud provider's admin console — a filter bar, a sortable table of virtual machines with a status column, and a row action menu. ## Screen states | State | What the annotation records | |---|---| | Loading | What shows while data arrives; whether the filter bar is usable meanwhile | | First-use empty | No instances exist yet: what the resource is, and the action to create one | | No results | Instances exist but the filter matched none: keep the filter visible, offer to clear it | | Error | Whole table failed versus one region unreachable; what the user can retry | | Permission | The user can view but not act: are actions hidden, or shown with an explanation | First-use empty and no-results empty look alike and are not: collapsing them sends a filtering user toward a create flow, or shows a new user a *clear filters* action that does nothing. ## Content extremes Designers draw with typical data; production data is not typical. The annotation states the rule for: - **Long values** — a 60-character instance name, a long region label: truncate or wrap, and how the full value stays reachable. - **Missing values** — an instance with no public address: a dash, the word *none*, or an empty cell. - **Counts at both ends** — zero rows, one row, ten thousand rows: pagination, virtual scrolling or a *load more* control. - **Translation growth** — labels that grow substantially in other languages, which moves every truncation point. ## Resize and layout rules A frame drawn at one width says nothing about any other width. The handoff says which regions **fill** and which keep their size, which columns **hide first** as the panel narrows, whether the table **scrolls horizontally** or reflows, and where the row actions go when space runs out. On native mobile the same annotation answers what the table becomes on a phone — often a list of cards — and which fields survive. ## Data and interaction rules - **Default sort** and whether the user's choice persists. - **Formats**: relative or absolute time, time zone, units for size and cost. - **Status mapping**: every status the backend can return and the indicator state each maps to — including the ones the designer never drew, such as *stopping* or *unknown*. - **Selection**: whether rows are selectable, what bulk actions appear, what happens to selection when the filter changes. ## Outcomes of actions The frame shows a button; the annotation shows what pressing it does. For *stop instance*: 1. The row's status changes at once to an in-progress state, and the stop action becomes unavailable for that row. 2. The table refreshes the row until the final state arrives. 3. On success the status reads *stopped*; on failure the row returns to *running* and a message says why and where to retry. 4. If an action removes the row entirely, the annotation says where focus goes, because the element that held it no longer exists. ## What the handoff does not need to annotate A design system exists partly so that screens need fewer notes. A system component's own behaviour — a button's hover, pressed, focus and disabled states, the table's built-in sort indicator — is defined once, in the component. Annotating it on every screen adds noise and invites contradictions. The handoff annotates: - **composition** — how this screen's pieces behave together; - **deviations** — anywhere the screen deliberately departs from the component's default; - **gaps** — behaviour the component does not support yet, which becomes a request to the system team rather than a local patch. A short checklist per handoff — states, extremes, resize, data rules, outcomes — makes missing answers visible without turning each screen into a wall of sticky notes.

  • How do you stop behaviour annotations from growing into a hundred notes per screen?
    Push reusable behaviour down into components and documented patterns — the table's own truncation and sort rules, a standard empty-state pattern — then annotate only composition, deviations and gaps. A five-part checklist per handoff (states, extremes, resize, data rules, outcomes) shows what is missing without restating what the system already defines.
  • The backend adds a new instance status after the design shipped; whose problem is the unannotated state?
    Both sides', which is why the annotation should list every status the backend can return plus a rule for unknown ones — a neutral indicator showing the raw status text. Without that fallback the engineer invents a mapping. The durable fix is that data contracts feed the handoff: new states trigger a design decision, not a silent default.

saying these in an interview costs you the question

  • The happy-path mockup is the spec; edge cases are engineering's call.
  • One empty state is enough, whatever the reason the table is empty.
  • Long names can be truncated with no way to see the full value.
  • Every system component's hover and focus states must be redrawn on each screen.
  • Loading and error states can be designed after the feature ships.