TS-17: Graphical user interfaces (GUIs)

This technical standard covers the design and implementation of graphical user interfaces (GUIs): interfaces composed of windows, views, and on-screen controls, operated by pointer, touch, or keyboard. The guidance is platform-agnostic, and applies to desktop applications, mobile applications, and web front-ends alike.

This is a deliberately thin standard. The usability principles that apply to every kind of human-computer interface — feedback, cognitive load, error messages, visual perception, typography — are covered by TS-15: User interfaces, and are not repeated here. What follows is limited to the concerns that are specific to graphical interfaces: platform conventions, layout, controls and input, interface states, error recovery, and accessibility.

For the web-specific implementation of these requirements — including the detailed treatment of WCAG conformance, performance, and responsive design — see TS-18: Web GUIs. For text-based interfaces, see TS-16: Command line interfaces (CLIs).

Platform conventions

A GUI is never the only application its users run. Users arrive with expectations already set by the platform they are on — where the primary action sits, what Ctrl/Cmd+Z does, how a window is closed, what a long-press means. Meeting those expectations is close to free; violating them costs the user something on every interaction.

A GUI MUST conform to the conventions of the platform it runs on. In practice this means honoring the host platform’s standard keyboard shortcuts, its window and view management, its system-wide gestures, its navigation idioms, and its user-level appearance settings — light and dark appearance, text size, contrast, and reduced motion. Where a platform publishes human interface guidelines, those guidelines are the reference for the platform-specific layer of the interface, and this standard is the reference for what sits above them.

Standard controls SHOULD be preferred over custom ones. A standard control carries a large contract that is easy to underestimate: keyboard operation, focus behavior, accessibility semantics, input-method support, internationalization, and conformance to the user’s own system settings. A custom control MUST reimplement that entire contract, not just the parts that are visible in a design mockup. Build one only where the standard control genuinely cannot express the interaction, and budget for the contract.

Where a product ships on more than one platform, consistency of the conceptual model — terminology, information architecture, and the sequence of steps in a task — matters more than pixel-level uniformity of the chrome. Users moving between the desktop and mobile versions of a product need to recognize it, not to find it identical. Platform-specific idioms SHOULD be honored per-platform even where that makes the two builds look different.

Within a product, consistency is not optional. A product SHOULD define its interface once, as a design system or shared component library, and assemble screens from it. Components defined once and reused are the only practical way to keep behavior, spacing, and accessibility properties consistent as an interface grows.

Layout and navigation

Every view SHOULD have a single, obvious primary action, given the most visual weight on the screen. Secondary actions are present but visually subordinate; rarely-used and advanced actions are progressively disclosed rather than shown by default. A view in which everything is emphasized has no hierarchy at all, and the user has to read all of it to find any of it.

Related controls and information MUST be grouped together, and groups separated by whitespace or an explicit boundary. Proximity is the strongest grouping signal available, and it overrides labeling: a control placed nearer to the wrong group will be read as part of that group whatever its label says.

Adapting to the viewport

A GUI MUST NOT assume a fixed window size, screen density, or orientation. Layouts MUST reflow to the space available, and MUST remain usable when the user changes the system text size — content MUST NOT be clipped, truncated, or overlapped when text is enlarged to 200%. Fixed-height containers sized around a specific string are the usual cause of this failure, and they break again under translation, where string lengths commonly grow by 30% or more.

Layout MUST NOT depend on the physical dimensions of a particular device model. Design against breakpoints derived from the content — the width at which a line of text becomes hard to scan, or at which a table stops fitting — rather than against the screen sizes of the current generation of hardware.

Navigation

A user MUST be able to tell, at any point, where they are in the application, how they arrived there, and how to leave without losing work. Navigation SHOULD be persistent and consistently placed, so that it is available without the user first having to find it.

Application state SHOULD survive navigation. Returning to a view the user has already visited SHOULD restore its scroll position, selection, filters, and any data the user had entered. Silently discarding that state forces the user to reconstruct by hand something the application already knew, and is one of the most common causes of lost work in an otherwise well-behaved interface.

Controls and input

The control MUST match the shape of the data it collects. The choice is determined by cardinality and by whether the effect is immediate:

  • Binary, applied immediately. A switch. Flipping it takes effect at once, with no separate confirmation step.
  • Binary, applied on submit. A checkbox. Its state is part of a form that is submitted later.
  • One of a small, fixed set. Radio buttons or a segmented control — all options visible at once.
  • One of a large set. A dropdown or combobox, with type-ahead filtering once the list is long enough that scanning it becomes work.
  • Unbounded or free-form. A text field, with the input type declared so that the platform can offer the appropriate keyboard and validation.

The switch-versus-checkbox distinction is not cosmetic. A switch that does not take effect until the user presses a "Save" button elsewhere on the screen misrepresents what the interface is doing, and users will leave the screen believing a change was applied.

Input modalities

A GUI MUST NOT assume a single input modality. The same interface is commonly driven by pointer, touch, keyboard, stylus, and assistive technology, often on the same device and sometimes within the same session.

It follows that no functionality or information may be available only on hover. Hover does not exist on touch, and it is not reachable by keyboard. A hover state MAY reinforce an affordance, but MUST NOT be the only way to discover or reach one.

Interactive targets MUST be at least 24×24 pixels, per WCAG 2.2 Level AA success criterion 2.5.8, or else be separated by enough spacing to give each target an equivalent undisturbed area. Primary touch targets SHOULD be at least 44×44 pixels. Targets placed close together SHOULD be spaced so that a missed tap does not trigger a neighboring action — a general rule that matters most where one of the neighbors is destructive.

Forms

Every input MUST have a persistently visible label. Placeholder text is not a label: it disappears exactly when the user needs it, and it is unreliably exposed to assistive technology.

Validation SHOULD run when the user leaves a field, or on submission — not on every keystroke, which reports an error against input the user has not finished typing. Error messages MUST appear adjacent to the field at fault, and, where a submission fails as a whole, MUST also be summarized in one place so that the user can see everything that needs fixing without hunting for it.

A failed submission MUST NOT discard what the user entered. Nor may a form block pasting into any field — the practice defeats password managers without preventing a single error.

States and feedback

Any view that loads data has more states than the one it is usually designed in. Each of the following MUST be designed explicitly, not left to whatever the implementation happens to render:

  1. Loading. Data has been requested but has not arrived.
  2. Loaded. The normal case, and usually the only one that gets designed.
  3. Empty. The request succeeded and there is legitimately nothing to show, because the user has not created anything yet.
  4. No results. The request succeeded but the user’s current filter or search excludes everything. This is distinct from empty, and telling a user with 200 records that they have none because a filter is set is a bug.
  5. Error. The request failed. The message MUST say what failed and what the user can do about it. "An error occurred" fails this test.

An empty state SHOULD explain what belongs in the view and offer the action that creates the first item. A blank pane communicates nothing, and is indistinguishable from a view that is broken.

Responsiveness

Every user input MUST produce a visible acknowledgment immediately, whether or not the operation behind it has completed. An interface that appears to do nothing for half a second will be clicked again.

Response times set the required treatment:

  • Under 100ms reads as instantaneous, and needs no indicator.
  • Up to about one second is a perceptible pause that does not break the user’s flow. An indicator is optional.
  • Beyond about one second, the interface MUST show that work is in progress.
  • Beyond about ten seconds, the user will switch to something else. Show determinate progress, and let the operation run in the background rather than holding the interface hostage.

Determinate progress SHOULD be shown wherever the total quantity of work is known. Where it is not, an indeterminate indicator is acceptable, but a skeleton that preserves the eventual layout is preferable for content loads: it sets expectations about what is arriving and avoids the layout shift that occurs when real content replaces a spinner.

Content MUST NOT shift under the user once it has been presented. Late-loading elements that reflow the page cause mis-clicks, and they most often do so at the moment the user has just committed to a target.

Optimistic updates — reflecting the result of an action before it is confirmed — MAY be used for actions that are fast, near-certain to succeed, and cheap to reverse. Where used, failure MUST be surfaced and the interface reconciled to the true state; a silent rollback leaves the user believing something happened that did not.

Transient notifications MUST NOT be the only channel for information the user needs. Anything that must be acted on has to remain available after the toast has gone.

Error prevention and recovery

Prevention comes first. Where an action is not currently possible, the interface SHOULD constrain the input rather than accept it and reject it afterwards — a date picker instead of a free-text date field, a bounded selection instead of a value the user has to guess. Where a control is disabled, the interface MUST make it discoverable why, since a disabled control with no explanation is indistinguishable from a broken one.

Destructive actions MUST be separated from the benign actions they sit alongside, both in position and in appearance. Placing "Delete" immediately next to the action a user performs routinely guarantees that some proportion of users will hit it, and the cost of that mistake is borne entirely by them.

Undo in preference to confirmation

Where an action is reversible, the interface SHOULD perform it immediately and offer undo, rather than interrupting with a confirmation dialog. Confirmation taxes every user on every occurrence in order to catch the rare mistake; undo costs nothing until a mistake is actually made.

Confirmation dialogs SHOULD be reserved for actions that are irreversible or carry serious consequence — permanent deletion, destroying other users' work, or significant financial commitment. Their effectiveness depends on their rarity: an interface that asks for confirmation routinely trains users to dismiss the dialogs without reading them, at which point they protect nobody.

Where a confirmation dialog is warranted:

  • It MUST state specifically what will happen, naming the object affected and saying whether the action can be reversed. "Are you sure?" conveys nothing.
  • Its buttons MUST be labeled with the actions they perform — "Delete project" and "Keep project" — not "Yes" and "No", which require the user to have read and correctly parsed the question.
  • The destructive option MUST NOT be the default or carry initial focus, so that a reflexive Enter cannot trigger it.
  • For catastrophic and unrecoverable actions, the dialog SHOULD require a deliberate non-default gesture, such as typing the name of the object being destroyed.

Protecting work in progress

An application MUST NOT lose work the user has done. Data entered into a form of any length SHOULD be preserved across navigation, accidental dismissal, and application restart, either by autosaving a draft or by warning before discarding it. Session expiry MUST NOT silently destroy unsaved input.

Undo SHOULD extend beyond destructive actions to ordinary editing. An interface that can be explored without risk is one users learn faster, because the cost of trying something and being wrong drops to zero.

Accessibility

WCAG 2.2 Level AA is the baseline for all graphical user interfaces, including those that are not web-based. WCAG is written against web technologies, but its success criteria describe interface behavior rather than markup, and it is the only widely-adopted, testable specification available. Native applications SHOULD be held to it, mapping each criterion onto the equivalent platform mechanism. For the web-specific implementation of these requirements, see TS-18: Web GUIs.

Accessibility MUST be treated as a property of the interface from the beginning, not as a remediation pass before release. Retrofitting is substantially more expensive than building correctly, and some defects — particularly in information architecture and focus order — cannot be fixed without redesign.

Keyboard operability

Every function MUST be operable by keyboard alone. This is the single highest-value accessibility requirement, because it is a precondition for switch access, voice control, and screen reader use, and because it is verifiable by any engineer in a few minutes.

Keyboard behavior MUST follow established GUI conventions: Tab and Shift+Tab move between components, and arrow keys move within a composite component — a menu, a toolbar, a list, a grid — which occupies a single stop in the tab sequence. Making every element in a large grid individually tabbable is conformant to the letter and unusable in practice.

Focus MUST NOT be trapped anywhere the user cannot escape from by keyboard, and MUST always rest somewhere visible. Opening a dialog MUST move focus into it and confine focus to it while it is open; closing the dialog MUST return focus to the control that opened it. Focus MUST NOT be left on a removed element, which drops it back to the top of the view and forces the user to navigate from the start.

A visible focus indicator is REQUIRED, on every focusable element, at a contrast ratio of at least 3:1 against adjacent colors. Removing focus indicators because they are considered unattractive makes an interface unusable for keyboard users.

Presentation

  • Contrast. Text MUST meet a contrast ratio of at least 4.5:1 against its background, or 3:1 for large text. Interface components and meaningful graphics MUST meet 3:1.
  • Color. Color MUST NOT be the sole means of conveying information, indicating state, or distinguishing an element. Pair it with text, shape, or an icon.
  • Motion. Animation MUST respect the platform’s reduced-motion setting. Content that moves, blinks, or auto-updates MUST be pausable, and nothing may flash more than three times per second.
  • Semantics. Custom controls MUST expose a role, an accessible name, and their current state through the platform’s accessibility API. A control assembled from generic containers is invisible to assistive technology regardless of how it looks.

Verification

Conformance MUST be verified, not assumed. Automated tooling catches a useful minority of defects — commonly cited at around a third — and cannot assess focus order, alternative text quality, or whether an interaction makes sense non-visually. Every interface SHOULD therefore be tested by operating it with the keyboard alone, and with a screen reader, on each platform it ships to.


References