Status Badges for .astro Pages Where Shared Tone Styling Doesn't Block Local Overrides in Islands
Zero-Specificity Badges in Astro
The classic CSS-in-JS specificity trap: you write a Badge with a shared "loud" style for the success/warning/danger tones, then a consumer tries to override the font weight on one instance and finds their style loses. Salty CSS handles this with anyOfVariants — the shared rule is wrapped in :where() so it carries zero specificity and any later rule for the same property wins automatically.
The component
// /components/badge.css.ts import { styled } from "@salty-css/astro/styled"; export const Badge = styled("span", { base: { display: "inline-block", padding: "0.125rem 0.5rem", borderRadius: "999px", fontSize: "0.75rem", }, variants: { tone: { success: { background: "#16a34a", color: "white" }, warning: { background: "#eab308", color: "black" }, danger: { background: "#dc2626", color: "white" }, neutral: { background: "#e5e7eb", color: "#111" }, }, }, // Apply the same "loud weight" whenever the tone is brand-loud. // anyOfVariants emits :where(…) so this rule has zero specificity and // always loses to a per-instance override. anyOfVariants: [ { tone: "success", css: { fontWeight: 700, letterSpacing: "0.02em" } }, { tone: "warning", css: { fontWeight: 700, letterSpacing: "0.02em" } }, { tone: "danger", css: { fontWeight: 700, letterSpacing: "0.02em" } }, ], });
Why this beats the obvious alternatives
- Repeating
fontWeight: 700inside eachvariants.tonebranch works, but every new tone has to remember to copy it — and merging two of those into a compound override later is awkward. - Adding it to
baseand trying to "un-bold" the neutral tone via{ fontWeight: 400 }also works — until a parent style sheet (Tailwind reset, design-system base) wins on specificity.anyOfVariantsducks that fight entirely.
Per-instance override
Because the shared rule lives behind :where(), the override below wins without !important or extra class chaining:
<!-- Loud red badge, but this one needs to read as quiet emphasis. --> <Badge tone="danger" style="font-weight: 400; letter-spacing: 0;"> Optional </Badge>
The inline style is the simplest demonstration — inline declarations always win. But even a more disciplined override — a separate rule keyed off data-quiet="true" — wins too, because the shared rule is wrapped in :where(.badge-…) and carries zero specificity.
What it produces
For the four tones you get one base class, four tone branches, and one :where(...) rule covering the three "loud" tones at once. All of it is in saltygen/index.css after the build; nothing about specificity is computed at render time.
See also
anyOfVariantsin the styled API reference- Variants — the broader picture of variant composition.
- Overrides — when to reach for
priorityinstead.