Testable UI acceptance criteria describe observable, verifiable behavior — not adjectives. Replace "the form should be user-friendly" with statements that name a trigger, a state, and an expected result: what the user does, what the screen shows, and how the system recovers from error. Pair Given/When/Then scenarios with a states matrix (default, loading, empty, error, success) so nothing observable is left to interpretation.

Quick Answer: Good UI acceptance criteria specify a trigger, a state, and an observable result — never a feeling. Use Given/When/Then for behavior and a states matrix for coverage across default, loading, empty, error, and success states, plus explicit focus and keyboard rules.

Why "Make It Feel Polished" Fails as an Acceptance Criterion

Subjective UI feedback fails as acceptance criteria because it can't be falsified — nobody can prove a screen "feels polished" is done or not done. Acceptance criteria need a binary pass/fail test anyone on the team can run without asking the PM what they meant.

This is the same gap Jobs to Be Done research surfaces when teams write requirements around a feature instead of the outcome a user is hiring it for — vague criteria and vague problem statements share a root cause: nobody named the observable job. If you haven't mapped the underlying job, our Jobs to Be Done complete guide is a useful prerequisite before you even open a spec doc.

Words like "polished," "clean," "intuitive," and "user-friendly" are design intents, not requirements. They belong in a design brief or a north-star description. They do not belong in the "Done means" section of a spec, because:

  1. They can't be tested. A QA engineer can't write a test case for "feels modern."
  2. They invite scope creep. "Polished" grows to mean whatever the last reviewer noticed.
  3. They shift the judgment call onto whoever ships last — usually the engineer, under deadline pressure, with the least product context.
  4. They erase the difference between a design opinion and a functional requirement, which makes trade-off conversations impossible to have cleanly.

Engineers and designers both distrust fuzzy acceptance criteria for different, valid reasons. Engineers can't estimate or test against a feeling. Designers see intent flattened into someone else's interpretation once it reaches build. Testable criteria fix both problems by making the requirement observable rather than aesthetic — the design opinion still exists, it just lives in the design file, not the spec's Done conditions.

The Translation Gap Is a Component API Problem

A UI acceptance criterion is really a contract for how a component behaves under given inputs — the same discipline behind treating a UI element like an API with defined inputs, outputs, and error states. Our guide on component API thinking for PMs goes deeper on this framing if acceptance criteria keep drifting into implementation detail instead of behavior.

How Given/When/Then Converts Feelings Into Tests

Given/When/Then (from behavior-driven development, popularized by Dan North and the Cucumber/Gherkin ecosystem) converts a fuzzy requirement into a scenario with a precondition, a trigger, and an observable outcome. Each line names one state, one action, and one result — no adjectives required.

The format forces three decisions a PM often skips:

  • Given — what state is the screen in before the user acts? (empty form, populated form, prior error)
  • When — what specific action does the user take? (blur a field, click submit, press Tab)
  • Then — what does the user observe as a direct result? (a message appears, focus moves, a button disables)

A criterion that can't be rewritten in this shape usually isn't a requirement yet — it's a hope.

Worked Example: "The Form Should Be User-Friendly"

Below is the fuzzy request from the brief, translated into scenarios covering validation, focus, keyboard access, and error recovery — the four places "polished" usually turns out to mean something specific.

Validation:

Given the email field is empty
When the user blurs the field without entering a value
Then an inline error reads "Email is required" below the field
And the field border changes to the error color token
And the field gets an aria-invalid="true" attribute

Focus management:

Given the form has one or more validation errors
When the user clicks Submit
Then focus moves to the first invalid field
And the page does not scroll unexpectedly past the error

Keyboard access:

Given the user is navigating by keyboard only
When the user presses Tab through the form
Then focus visibly outlines each interactive element in DOM order
And Enter on the last field submits the form if all fields are valid

Error recovery:

Given the form submission fails due to a server error
When the error response returns
Then a non-blocking banner states the error and a retry action
And previously entered values remain in their fields
And the submit button re-enables within 300ms of the response

Each block is independently testable by an engineer and independently reviewable by a designer against the mockup — nobody has to guess what "user-friendly" meant on the day of hand-off.

Why a States Matrix Catches What Given/When/Then Misses

A states matrix lists every UI state a component can be in — default, loading, empty, error, partial, and success — against every dimension that changes it, so gaps become visible as empty cells instead of surprises during QA. Given/When/Then is strong on sequences of action; it's weak at guaranteeing you've enumerated every state up front.

StateTriggerVisible contentInteractive elements
DefaultInitial load, no data enteredEmpty fields, placeholder textAll inputs enabled
LoadingSubmit pressed, awaiting responseSpinner on submit buttonAll inputs disabled
EmptyZero results after a search/filterEmpty-state illustration + CTAFilter controls remain enabled
Error (field-level)Invalid input on blurInline message, error color tokenField stays enabled and editable
Error (system-level)Server/network failureBanner with retry actionRetry enabled, submit re-enabled
SuccessSubmission acceptedConfirmation message or redirectForm fields cleared or disabled

Build the matrix before writing Given/When/Then scenarios, not after — the matrix tells you which scenarios are missing. A common failure mode is specs that cover default and success beautifully and never mention loading, empty, or error, because those states are less fun to design and easiest to leave implicit.

Reading a Gap as a Missing Requirement, Not an Edge Case

Treat any empty cell in the matrix as an open acceptance criterion, not an "edge case we'll handle later." Engineers build what's specified; if the loading state isn't specified, the engineer picks one — and that pick becomes the de facto spec, discovered in review instead of in planning. This is the same "state before flow" discipline behind mapping a customer journey: you can't specify the transitions correctly until you've named every state a person — or a screen — can be in.

How to Scope Acceptance Criteria Without Micromanaging Design

Scope acceptance criteria to observable behavior and states — never to visual specifics like exact pixel values, colors, or copy, which belong in the design file and design tokens, not the spec. The line to hold: PMs own what must be true; designers own how it looks while being true.

A useful test before writing any criterion: "if the designer picked a totally different visual treatment tomorrow, would this line still be true?" If yes, it's a legitimate acceptance criterion. If no — if it only holds for the current mockup's spacing or color — it's a design decision masquerading as a requirement.

Belongs in acceptance criteriaBelongs in the design file / tokens
"An error message appears below the field"Exact copy wording and tone
"The error uses the error-state color token"The specific hex/HSL value behind that token
"Focus moves to the first invalid field"The visual style of the focus ring
"The submit button disables during loading"Spinner animation style
"Disabled fields are announced to screen readers"Icon choice for the disabled state

Referencing tokens rather than raw values (error-color instead of a hex code) is exactly the boundary design tokens explained for PMs covers — the acceptance criterion names the semantic state, the token system resolves it to an actual value, and nobody hardcodes anything that breaks the next time the design system updates. This is also where acceptance criteria sit downstream of a broader design system: if your components already have documented states, your acceptance criteria are largely a matter of citing them correctly, not inventing them from scratch.

Get scoping wrong and one of two failure modes shows up:

  1. Over-specification — the PM dictates pixel spacing and animation timing, which reads as micromanagement and slows design iteration.
  2. Under-specification — the PM writes "should look good," which pushes every judgment call downstream to whoever ships last.

Where Designers Should Push Back

A designer should feel free to challenge any criterion that prescribes an implementation rather than an outcome. If a criterion says "use a red border," ask whether the actual requirement is "communicate an error state visually" — the latter survives a redesign, the former doesn't.

How to Validate Acceptance Criteria Before Hand-Off

Validate acceptance criteria by running each one through three checks: can it be tested with a pass/fail result, does it name every state in the matrix, and would it still hold under a different visual design? A criterion that fails any of the three isn't ready to leave the spec stage.

Nielsen Norman Group's long-running heuristic evaluation research — particularly the heuristics on visibility of system status and error prevention/recovery — maps almost directly onto the states-matrix categories above: loading states are status visibility, and field-level errors are error prevention. If your matrix is missing a state, it's often missing one of Nielsen's ten heuristics in disguise.

A short pre-hand-off checklist:

  • Every state in the matrix has at least one corresponding Given/When/Then scenario
  • No criterion contains a subjective adjective ("clean," "intuitive," "modern")
  • Every color/spacing reference points to a token name, not a raw value
  • Keyboard-only navigation is covered explicitly, not assumed
  • Error recovery states preserve user input rather than clearing the form
  • Focus management is specified for every error and success transition

Run this checklist as a working session with both a designer and an engineer present, not solo — the gaps each discipline notices tend to differ, and reconciling them before hand-off is cheaper than reconciling them mid-sprint.

Where Spec Readiness Gates Fit Into This

That's a natural complement to the practices above — a states matrix and Given/When/Then scenarios give you the content a readiness gate checks for; the gate is what keeps an incomplete spec from quietly reaching engineering anyway.

Key Takeaways

  • Subjective language like "polished" or "user-friendly" can't be tested — replace it with observable trigger-state-result statements before a spec reaches hand-off.
  • Given/When/Then scenarios force three explicit decisions per requirement: starting state, user action, and observable result.
  • A states matrix (default, loading, empty, error, success) surfaces missing requirements as empty cells, catching gaps Given/When/Then alone tends to miss.
  • Acceptance criteria should scope to behavior and states, referencing design tokens — never to pixel values, exact copy, or animation specifics that belong in the design file.
  • The test for a legitimate criterion: would it still hold true under a completely different visual design? If not, it's a design decision, not a requirement.
  • Validate before hand-off with a joint PM-designer-engineer checklist, not a solo pass — the gaps each discipline spots tend to differ.
  • Spec readiness gates, like those in Prodinja's Spec Studio, are designed to hold a spec back until acceptance criteria are actually complete.

Frequently Asked Questions

What is the difference between UI acceptance criteria and a design spec?

UI acceptance criteria state observable, testable conditions for "done" (states, triggers, results); a design spec shows the exact visual treatment (colors, spacing, typography) that satisfies those conditions. Acceptance criteria should hold true even if the design spec changes; if a criterion breaks under a redesign, it was really a design decision.

How detailed should acceptance criteria be for a simple UI change?

Detailed enough to cover every state in a states matrix — even a simple change usually has default, loading, error, and success states worth naming explicitly. A one-line change to a button's label still needs a criterion for what happens on click, not just what the label says.

Should PMs write acceptance criteria alone or with designers and engineers?

Write a first draft alone from the states matrix and Given/When/Then format, then validate jointly with both a designer and an engineer before hand-off. Each discipline tends to catch different gaps — designers spot missing states, engineers spot missing edge-case triggers.

How do you write acceptance criteria for accessibility without a separate a11y spec?

Fold keyboard navigation, focus management, and screen-reader announcements directly into the same Given/When/Then scenarios as functional behavior, rather than treating accessibility as a separate checklist appended at the end. Specifying "focus moves to the first invalid field" is both a UX requirement and an accessibility requirement in one line.

What's a common mistake teams make with UI acceptance criteria?

The most common mistake is specifying only the default and success states and leaving loading, empty, and error states implicit — which pushes those decisions onto whoever builds the feature last. Building the states matrix before writing scenarios is the most reliable way to catch that gap early.