Building HTML UI forced me to figure out how to write CSS classes that integrate deeply with Tailwind v4. I want 3 things: intellisense, tree shaking, and easy utility overrides. Here’s I make it all work 🧵

@​utility ui-badge {
:where(&) {
@​apply inline-flex items-center ...;

@​variant hover {
@​apply bg-primary/90;
}

@​variant focus-visible {
@​apply border-ring ring-ring/50;
}
}
}

Why this is better:
• @​utility → tree-shaking + autocomplete
• :where() → zero specificity, utilities always win
• @​variant → each state gets its own readable block
• @​apply → uses the user’s theme, not a parallel system
The ui- prefix matters too. When you see .btn you have no idea what you’re dealing with. Bootstrap? Old semantic class? Random utility? `ui-badge` signals intent: zero-specificity visual pattern designed to compose with utilities.

Tailwind v4’s @​utility, @​apply, and @​variant aren’t just new syntax.
Combined with :where(), they let you write semantic CSS that’s discoverable, tree-shakeable, readable, and composable.

Full write-up: https://fractaledmind.com/2026/01/02/writing-tailwind-compatible-semantic-css/

Writing Tailwind-compatible Semantic CSS | Fractaled Mind

This is my personal site, where I write about Ruby, programming, and any of my varied fascinations.