In a design handoff for a cloud admin console's resource table, which behaviours must be annotated because a static mockup cannot show them?
answer
- a mockup is one moment
- loading, empty, error, no permission
- longest name, zero rows, many rows
- what shrinks, truncates or scrolls
- what the screen does after an action
basics
~20 sAnnotate 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 sA 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
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.
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.
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.
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.