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
3 filledOne primaryGood
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 filledTieredGood
1 filled · 2 outlined · 2 textconst 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
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.