Skip to content

Visual Hierarchy

Every screen has one thing it wants you to see first. When every line is bold and dark, nothing gets to be that thing, and you have to read each word to find it.

The instinct is to make the important part louder. That starts an arms race: a bigger name, a bolder price, and now the row is loud in two places instead of one.

Quiet the rest instead of making the important thing louder.

  • Linen ShirtSand, size M
    $6812 left
  • Wool HoodieCharcoal, size L
    $1453 left
  • Canvas ToteNatural
    $3240 left

Step through the three versions, then press Squint. The quiet one never changes a size. Names and prices stay at 14px and 500; the details drop to 400 and lighter tones. Blurred, the bold list is a grey stripe per row, while the quiet one still leads with what matters. It is the same blur test as in optical alignment, aimed at emphasis.

Tone and weight before size

Size is the bluntest tool. It costs space, breaks alignment, and needs its own letter spacing. Color and weight do most of the work for less. Three text tones are enough: one for the thing, one for its details, one for metadata. Two weights, 400 and 500, cover almost everything else.

Keep even the quietest tone at 4.5:1 or more. Here it is neutral-500 on white, which lands at 4.7:1.

Labels are a last resort

A label is more text to read before you reach the value. Formatted well, most values explain themselves. "12 left" says what "Stock: 12" says, in one glance.

Wrong
Name: Linen ShirtColor: SandPrice: $68Stock: 12
Label: value
Right
Linen ShirtSand$6812 left
Values explain themselves

Actions have ranks

Buttons follow the same rule. One solid primary action, a quiet secondary one, and a destructive action that is not the main job can be plain text that turns red on hover. Save the big red button for the confirmation step.

Project nameShown in the sidebar and on invoices.
Spring catalog

Usage

app.tsx
<li class="flex items-center justify-between text-sm">
  <div>
    <p class="font-medium text-neutral-900">Linen Shirt</p>
    <p class="text-neutral-600">Sand, size M</p>
  </div>
  <div class="text-right tabular-nums">
    <p class="font-medium text-neutral-900">$68</p>
    <p class="text-neutral-500">12 left</p>
  </div>
</li>
:root {
  --text-primary: #171717;   /* the thing */
  --text-secondary: #525252; /* its details */
  --text-tertiary: #737373;  /* metadata, 4.7:1 on white */
}

.title {
  font-weight: 500;
  color: var(--text-primary);
}

.meta {
  font-weight: 400;
  color: var(--text-tertiary);
}

These greys are tuned for a white surface. On a colored background, grey text looks washed out and can fall under 4.5:1. Pick lighter or darker shades of the background's own hue instead.

Resources

Search concepts

Search for a command to run...