Architecture
Decide when a repeated pattern should become a real component.
Utilities
Utilities should be rare helpers, not a second styling system hiding in your HTML. If utilities become the architecture, the architecture has quietly left the building.
Ask:
Does this solve a universal accessibility problem?
→ Utility
Does this keep repeating as a UI pattern?
→ Component
Is this only visual presentation?
→ Theme or component, not utility A utility should have to justify its existence. Most spacing, layout, colour, and typography decisions belong in components, layout, or theme instead.
These are the utilities that fit naturally because they solve universal browser and assistive technology problems, not temporary design decisions.
.vh {}
.a11y-link {}
.a11y-link--focusable {} .vh {
position: absolute;
inline-size: 1px;
block-size: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
Use .vh for content that should remain available to
screen readers while staying visually hidden.
.a11y-link {
position: absolute;
inset-block-start: 0;
inset-inline-start: 0;
transform: translateY(-100%);
}
.a11y-link--focusable:focus,
.a11y-link--focusable:focus-visible {
transform: translateY(0);
}
Use .a11y-link with
.a11y-link--focusable for skip links that become visible
when focused.
If the same utility group keeps appearing together, it is not a utility pattern. It is a component asking to be named.
<article class="p-4 mb-4 bg-white rounded shadow text-center grid gap-4">
<h2 class="text-xl font-bold mb-2">Product title</h2>
<p class="text-sm text-muted mb-4">Product description</p>
</article> This pushes layout, spacing, colour, and typography decisions into the markup and turns HTML into a styling spreadsheet.
<article class="product-card">
<h2 class="title">Product title</h2>
<p class="description">Product description</p>
</article> Prefer semantic components when the markup represents a real UI pattern. Components scale. Utility soup spreads like ivy.