tim witter
All articles

Blog

Visual quality comes from iteration, not a score

I find a single screenshot too easy to mistake for a finished interface. Visual quality emerges from checking how a page behaves across sizes and states, then revisiting the specific thing I changed.

Choose representative views

I inspect a narrow and a wide viewport, plus an intermediate width where layouts often become awkward. I also look at real UI states: long text, focus, empty content, and an open control where applicable. My heuristic is to select views that could expose a failure, not merely the most flattering frame. This costs attention but gives a more useful picture.

The interesting widths are often the awkward ones. A layout that works at the ends of the range can break in the middle, where a sidebar competes with content for the same line. I note the width where something first looks wrong rather than averaging it away, because a defect in a narrow band is still a defect.

States are part of the view as well. Long words, missing data, a focused control, and an open menu all change the geometry that a screenshot captured at rest. I include at least one state that stresses the element I touched.

long-text.cssCSS
/* A long identifier must not force a horizontal scrollbar. */
.panel-title {
  overflow-wrap: anywhere;
}

Change one problem at a time

When typography, spacing, and navigation all seem off, I name the dominant problem before editing. A targeted adjustment is easier to attribute than a sweeping restyle. Visual evidence complements, rather than replaces, checks for semantics and keyboard use. An attractive still image cannot show whether focus disappears or content shifts when a state changes.

When several things look wrong, I rank them by how much they affect the task and fix the top one first. Mixing a typography change with a spacing change makes the result hard to attribute: if the page improves, I cannot say which adjustment did it, and if it regresses, I have two suspects.

Visual work also has a budget. Every extra screenshot and every extra state costs attention that the rest of the review needs. I spend it where the risk is: the viewport closest to a breakpoint, the state most likely to be hit by real content, the control a keyboard user will reach.

focus.cssCSS
/* Keyboard focus stays visible in every theme. */
:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

Recheck the affected state

After an adjustment I revisit the viewport and state that showed the issue, then look once at neighboring sizes for regressions. If capture tools are unavailable, I say so and avoid claiming visual confirmation. There is no universal score that proves a page is good; I can instead report the views examined, the defect addressed, and what remains unobserved.

A recheck is not a fresh review. It is a comparison against the observation that motivated the change: the same viewport, the same state, the same content, so that the only difference is my edit. I keep the earlier observation visible while I look at the new one, because memory is a poor diff.

I also keep a short record of what was observed, not just what was changed. The note names the viewport, the state, and the defect that motivated the edit, so a later reviewer can repeat the comparison instead of trusting my summary. When the tooling is missing, that record states the gap explicitly rather than leaving it implied.

capture.shShell
# Start the local preview, then capture one viewport at a time.
bun run preview --port 4321
# ready on http://localhost:4321

capture --url http://localhost:4321/ --width 360 --out narrow.png
capture --url http://localhost:4321/ --width 1280 --out wide.png