One primary action per view

One filled primary per view; the rest outlined, text or quiet.

From refactoring-ui, after Refactoring UI by Adam Wathan and Steve Schoger.

Save, Cancel, Delete

Click each button in both dialogs, including Delete.

Three filled buttonsBad

Edit invoice INV-1042

3 filled
One primaryGood

Edit invoice INV-1042

1 filled · 1 outlined · 1 text
<button class="text-red-600">Delete</button>
<span class="flex-1"></span>
<button class="border border-gray-300">Cancel</button>
<button class="bg-blue-600 text-white">Save</button>

Pick the primary

Click any action to make it primary.

Everything filledBad
5 filled
TieredGood
1 filled · 2 outlined · 2 text
const rest = actions.filter(a => a.id !== primaryId).sort((a, b) => a.rank - b.rank);
const tiers = [...rest.slice(2).map(tertiary), ...rest.slice(0, 2).map(secondary), primary];

"The button doesn't pop"

Raise the fill until both ratios pass.

Upgrade promptWeak

Storage almost full

9.2 of 10 GB used

filllabel
.btn { background: var(--blue-600); color: #fff; box-shadow: var(--shadow-sm); }

Why it matters, pros and cons

Why it matters

Weight only works against lighter neighbours. A filled red Delete makes a rare action the loudest thing.

Pros

  • The next step is obvious.
  • Fewer destructive mis-clicks.
  • Three tiers cover almost every view.

Cons

  • Some views have two equal paths.
  • Text-only buttons are easy to miss and tap.
  • On a confirm dialog, Delete is the primary.