Version 0.1.0 just released! Check out the release notes from GitHub Releases

Share Loud Styles Across Brand, Warning, and Danger Tones Without Beating Per-Instance Customisation

Zero-Specificity Status Badges in React

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/react/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: 700 inside each variants.tone branch 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 base and 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. anyOfVariants ducks 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=>
  Optional
</Badge>

The style prop is an inline declaration, which always wins; but even a more disciplined override — a className rule keyed off data-quiet="true" — would win, because the shared rule is :where(.badge-…).

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