v150 · CSS · Color · UI States

State Feedback Colors

One brand token, every interactive state — hover, active, focus ring, and alert background — all derived at runtime via alpha(from var(--brand) / N%). Change the brand color above and every state color updates automatically. No preprocessor, no extra variables.

Checking alpha() function support…

pick a brand color

--brand:

buttons

Ghost variant — hover/active/focus via alpha()
Filled variant — hover softens via alpha()

alert boxes

Info: Brand-colored background via alpha(from var(--brand) / 8%).
Error: Same pattern, different semantic color.
Success: One expression, consistent tint.
Warning: No extra color variable needed per semantic level.

token derivation

code

:root {
  --brand: oklch(55% 0.18 250); /* one source of truth */
}

/* Ghost button — all states from one token */
.btn-ghost {
  border: 2px solid var(--brand);
  background: color-mix(in srgb, var(--brand) 12%, transparent); /* fallback */
  color: var(--brand);
}
.btn-ghost:hover {
  background: color-mix(in srgb, var(--brand) 22%, transparent);
}
.btn-ghost:active {
  background: color-mix(in srgb, var(--brand) 35%, transparent);
}
.btn-ghost:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--brand) 50%, transparent);
}

/* Alert box — tinted background from the semantic color */
.alert-info {
  background: color-mix(in srgb, var(--brand) 8%, transparent);
  border-left: 4px solid var(--brand);
}
.alert-danger {
  background: color-mix(in srgb, var(--danger) 8%, transparent);
  border-left: 4px solid var(--danger);
}
.alert-success {
  background: color-mix(in srgb, var(--success) 8%, transparent);
  border-left: 4px solid var(--success);
}

@supports (background-color: alpha(from red / 50%)) {
  .btn-ghost {
    background: alpha(from var(--brand) / 12%);
  }
  .btn-ghost:hover {
    background: alpha(from var(--brand) / 22%);
  }
  .btn-ghost:active {
    background: alpha(from var(--brand) / 35%);
  }
  .btn-ghost:focus-visible {
    outline: 3px solid alpha(from var(--brand) / 50%);
  }
  .alert-info {
    background: alpha(from var(--brand) / 8%);
  }
  .alert-danger {
    background: alpha(from var(--danger) / 8%);
  }
  .alert-success {
    background: alpha(from var(--success) / 8%);
  }
}

/* Before alpha(): required separate variables per semantic level
   --brand-hover-bg: oklch(55% 0.18 250 / 22%);  ← had to precompute this
   --brand-active-bg: oklch(55% 0.18 250 / 35%); ← or use JS to inject
   and had to update ALL of them when --brand changed. */

see also

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗