React Theme Utilities

Theme

Style utilities that pair a themed surface with the text color that reads on it, so any element can be colored the way component variants are.

ClassStyles
.theme-contrastbackground-color: var(--cui-theme-bg);
color: var(--cui-theme-contrast);
.theme-subtlebackground-color: var(--cui-theme-bg-subtle);
color: var(--cui-theme-fg);
.theme-mutedbackground-color: var(--cui-theme-bg-muted);
color: var(--cui-theme-fg-emphasis);
.theme-borderborder: var(--cui-border-width) solid var(--cui-theme-border);

How it works

A .theme-{color} class sets the theme slot tokens — --cui-theme-bg, --cui-theme-fg, --cui-theme-bg-subtle and friends — without painting anything itself. Components read those slots on their own; for arbitrary markup, add one of the style utilities below to pair a themed surface with the text color that reads on it. .theme-border additionally draws a border in the theme’s border color and composes with any of the three surfaces.

See Theme for how the slots resolve and how to add a color of your own.

Contrast

.theme-contrast fills with the solid theme color and sets the text to the color that reads on it — the pairing behind solid component variants:

.theme-primary .theme-contrast
.theme-secondary .theme-contrast
.theme-success .theme-contrast
.theme-info .theme-contrast
.theme-warning .theme-contrast
.theme-danger .theme-contrast
.theme-inverse .theme-contrast
<div className="p-3 theme-primary theme-contrast">.theme-primary .theme-contrast</div>
<div className="p-3 theme-secondary theme-contrast">.theme-secondary .theme-contrast</div>
<div className="p-3 theme-success theme-contrast">.theme-success .theme-contrast</div>
<div className="p-3 theme-info theme-contrast">.theme-info .theme-contrast</div>
<div className="p-3 theme-warning theme-contrast">.theme-warning .theme-contrast</div>
<div className="p-3 theme-danger theme-contrast">.theme-danger .theme-contrast</div>
<div className="p-3 theme-inverse theme-contrast">.theme-inverse .theme-contrast</div>
<div className="p-3 theme-primary theme-contrast">.theme-primary .theme-contrast</div>
<div className="p-3 theme-secondary theme-contrast">.theme-secondary .theme-contrast</div>
<div className="p-3 theme-success theme-contrast">.theme-success .theme-contrast</div>
<div className="p-3 theme-info theme-contrast">.theme-info .theme-contrast</div>
<div className="p-3 theme-warning theme-contrast">.theme-warning .theme-contrast</div>
<div className="p-3 theme-danger theme-contrast">.theme-danger .theme-contrast</div>
<div className="p-3 theme-inverse theme-contrast">.theme-inverse .theme-contrast</div>

Subtle

.theme-subtle uses the theme’s subtle surface with its readable foreground. The pairing adjusts to the color mode on its own:

.theme-primary .theme-subtle
.theme-secondary .theme-subtle
.theme-success .theme-subtle
.theme-info .theme-subtle
.theme-warning .theme-subtle
.theme-danger .theme-subtle
.theme-inverse .theme-subtle
<div className="p-3 theme-primary theme-subtle">.theme-primary .theme-subtle</div>
<div className="p-3 theme-secondary theme-subtle">.theme-secondary .theme-subtle</div>
<div className="p-3 theme-success theme-subtle">.theme-success .theme-subtle</div>
<div className="p-3 theme-info theme-subtle">.theme-info .theme-subtle</div>
<div className="p-3 theme-warning theme-subtle">.theme-warning .theme-subtle</div>
<div className="p-3 theme-danger theme-subtle">.theme-danger .theme-subtle</div>
<div className="p-3 theme-inverse theme-subtle">.theme-inverse .theme-subtle</div>
<div className="p-3 theme-primary theme-subtle">.theme-primary .theme-subtle</div>
<div className="p-3 theme-secondary theme-subtle">.theme-secondary .theme-subtle</div>
<div className="p-3 theme-success theme-subtle">.theme-success .theme-subtle</div>
<div className="p-3 theme-info theme-subtle">.theme-info .theme-subtle</div>
<div className="p-3 theme-warning theme-subtle">.theme-warning .theme-subtle</div>
<div className="p-3 theme-danger theme-subtle">.theme-danger .theme-subtle</div>
<div className="p-3 theme-inverse theme-subtle">.theme-inverse .theme-subtle</div>

And with .theme-border:

.theme-primary .theme-subtle .theme-border
.theme-secondary .theme-subtle .theme-border
.theme-success .theme-subtle .theme-border
.theme-info .theme-subtle .theme-border
.theme-warning .theme-subtle .theme-border
.theme-danger .theme-subtle .theme-border
.theme-inverse .theme-subtle .theme-border
<div className="p-3 theme-primary theme-subtle theme-border">.theme-primary .theme-subtle .theme-border</div>
<div className="p-3 theme-secondary theme-subtle theme-border">.theme-secondary .theme-subtle .theme-border</div>
<div className="p-3 theme-success theme-subtle theme-border">.theme-success .theme-subtle .theme-border</div>
<div className="p-3 theme-info theme-subtle theme-border">.theme-info .theme-subtle .theme-border</div>
<div className="p-3 theme-warning theme-subtle theme-border">.theme-warning .theme-subtle .theme-border</div>
<div className="p-3 theme-danger theme-subtle theme-border">.theme-danger .theme-subtle .theme-border</div>
<div className="p-3 theme-inverse theme-subtle theme-border">.theme-inverse .theme-subtle .theme-border</div>
<div className="p-3 theme-primary theme-subtle theme-border">.theme-primary .theme-subtle .theme-border</div>
<div className="p-3 theme-secondary theme-subtle theme-border">.theme-secondary .theme-subtle .theme-border</div>
<div className="p-3 theme-success theme-subtle theme-border">.theme-success .theme-subtle .theme-border</div>
<div className="p-3 theme-info theme-subtle theme-border">.theme-info .theme-subtle .theme-border</div>
<div className="p-3 theme-warning theme-subtle theme-border">.theme-warning .theme-subtle .theme-border</div>
<div className="p-3 theme-danger theme-subtle theme-border">.theme-danger .theme-subtle .theme-border</div>
<div className="p-3 theme-inverse theme-subtle theme-border">.theme-inverse .theme-subtle .theme-border</div>

Muted

.theme-muted uses the theme’s muted surface with its emphasis foreground, for the quietest of the three pairings:

.theme-primary .theme-muted
.theme-secondary .theme-muted
.theme-success .theme-muted
.theme-info .theme-muted
.theme-warning .theme-muted
.theme-danger .theme-muted
.theme-inverse .theme-muted
<div className="p-3 theme-primary theme-muted">.theme-primary .theme-muted</div>
<div className="p-3 theme-secondary theme-muted">.theme-secondary .theme-muted</div>
<div className="p-3 theme-success theme-muted">.theme-success .theme-muted</div>
<div className="p-3 theme-info theme-muted">.theme-info .theme-muted</div>
<div className="p-3 theme-warning theme-muted">.theme-warning .theme-muted</div>
<div className="p-3 theme-danger theme-muted">.theme-danger .theme-muted</div>
<div className="p-3 theme-inverse theme-muted">.theme-inverse .theme-muted</div>
<div className="p-3 theme-primary theme-muted">.theme-primary .theme-muted</div>
<div className="p-3 theme-secondary theme-muted">.theme-secondary .theme-muted</div>
<div className="p-3 theme-success theme-muted">.theme-success .theme-muted</div>
<div className="p-3 theme-info theme-muted">.theme-info .theme-muted</div>
<div className="p-3 theme-warning theme-muted">.theme-warning .theme-muted</div>
<div className="p-3 theme-danger theme-muted">.theme-danger .theme-muted</div>
<div className="p-3 theme-inverse theme-muted">.theme-inverse .theme-muted</div>

Comparison

All three pairings side by side, per theme color:

Primary
Primary
Primary
Secondary
Secondary
Secondary
Success
Success
Success
Info
Info
Info
Warning
Warning
Warning
Danger
Danger
Danger
Inverse
Inverse
Inverse
<div className="d-flex gap-3 mb-3">
  <div className="theme-primary theme-contrast p-4 flex-fill text-center rounded">Primary</div>
  <div className="theme-primary theme-subtle p-4 flex-fill text-center rounded">Primary</div>
  <div className="theme-primary theme-muted p-4 flex-fill text-center rounded">Primary</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-secondary theme-contrast p-4 flex-fill text-center rounded">Secondary</div>
  <div className="theme-secondary theme-subtle p-4 flex-fill text-center rounded">Secondary</div>
  <div className="theme-secondary theme-muted p-4 flex-fill text-center rounded">Secondary</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-success theme-contrast p-4 flex-fill text-center rounded">Success</div>
  <div className="theme-success theme-subtle p-4 flex-fill text-center rounded">Success</div>
  <div className="theme-success theme-muted p-4 flex-fill text-center rounded">Success</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-info theme-contrast p-4 flex-fill text-center rounded">Info</div>
  <div className="theme-info theme-subtle p-4 flex-fill text-center rounded">Info</div>
  <div className="theme-info theme-muted p-4 flex-fill text-center rounded">Info</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-warning theme-contrast p-4 flex-fill text-center rounded">Warning</div>
  <div className="theme-warning theme-subtle p-4 flex-fill text-center rounded">Warning</div>
  <div className="theme-warning theme-muted p-4 flex-fill text-center rounded">Warning</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-danger theme-contrast p-4 flex-fill text-center rounded">Danger</div>
  <div className="theme-danger theme-subtle p-4 flex-fill text-center rounded">Danger</div>
  <div className="theme-danger theme-muted p-4 flex-fill text-center rounded">Danger</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-inverse theme-contrast p-4 flex-fill text-center rounded">Inverse</div>
  <div className="theme-inverse theme-subtle p-4 flex-fill text-center rounded">Inverse</div>
  <div className="theme-inverse theme-muted p-4 flex-fill text-center rounded">Inverse</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-primary theme-contrast p-4 flex-fill text-center rounded">Primary</div>
  <div className="theme-primary theme-subtle p-4 flex-fill text-center rounded">Primary</div>
  <div className="theme-primary theme-muted p-4 flex-fill text-center rounded">Primary</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-secondary theme-contrast p-4 flex-fill text-center rounded">Secondary</div>
  <div className="theme-secondary theme-subtle p-4 flex-fill text-center rounded">Secondary</div>
  <div className="theme-secondary theme-muted p-4 flex-fill text-center rounded">Secondary</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-success theme-contrast p-4 flex-fill text-center rounded">Success</div>
  <div className="theme-success theme-subtle p-4 flex-fill text-center rounded">Success</div>
  <div className="theme-success theme-muted p-4 flex-fill text-center rounded">Success</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-info theme-contrast p-4 flex-fill text-center rounded">Info</div>
  <div className="theme-info theme-subtle p-4 flex-fill text-center rounded">Info</div>
  <div className="theme-info theme-muted p-4 flex-fill text-center rounded">Info</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-warning theme-contrast p-4 flex-fill text-center rounded">Warning</div>
  <div className="theme-warning theme-subtle p-4 flex-fill text-center rounded">Warning</div>
  <div className="theme-warning theme-muted p-4 flex-fill text-center rounded">Warning</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-danger theme-contrast p-4 flex-fill text-center rounded">Danger</div>
  <div className="theme-danger theme-subtle p-4 flex-fill text-center rounded">Danger</div>
  <div className="theme-danger theme-muted p-4 flex-fill text-center rounded">Danger</div>
</div>
<div className="d-flex gap-3 mb-3">
  <div className="theme-inverse theme-contrast p-4 flex-fill text-center rounded">Inverse</div>
  <div className="theme-inverse theme-subtle p-4 flex-fill text-center rounded">Inverse</div>
  <div className="theme-inverse theme-muted p-4 flex-fill text-center rounded">Inverse</div>
</div>

Mixing colors

Each element carries its own .theme-{color}, so siblings can differ — the utility reads whichever theme is in scope:

Success
Warning
Danger
<div className="d-flex gap-3">
  <div className="theme-success theme-contrast p-4 rounded">Success</div>
  <div className="theme-warning theme-contrast p-4 rounded">Warning</div>
  <div className="theme-danger theme-contrast p-4 rounded">Danger</div>
</div>
<div className="d-flex gap-3">
  <div className="theme-success theme-contrast p-4 rounded">Success</div>
  <div className="theme-warning theme-contrast p-4 rounded">Warning</div>
  <div className="theme-danger theme-contrast p-4 rounded">Danger</div>
</div>

The theme can also come from any element above, so one wrapper themes every pairing inside it:

Contrast
Subtle
Muted
<div className="theme-primary d-flex gap-3">
  <div className="theme-contrast p-4 rounded">Contrast</div>
  <div className="theme-subtle p-4 rounded">Subtle</div>
  <div className="theme-muted p-4 rounded">Muted</div>
</div>
<div className="theme-primary d-flex gap-3">
  <div className="theme-contrast p-4 rounded">Contrast</div>
  <div className="theme-subtle p-4 rounded">Subtle</div>
  <div className="theme-muted p-4 rounded">Muted</div>
</div>

Reset

Added in v6.0.0

.theme-reset drops the theme a subtree inherits: it sets every --cui-theme-* slot back to initial, so components and utilities below it fall back to their defaults.

Primary badge Default badge
<div className="theme-primary p-4 rounded">
  <span className="badge">Primary badge</span>
  <span className="badge theme-reset">Default badge</span>
</div>
<div className="theme-primary p-4 rounded">
  <span className="badge">Primary badge</span>
  <span className="badge theme-reset">Default badge</span>
</div>
scss
@mixin theme-reset() {
  $slots: ();

  @each $slots-of-color in map.values($theme-colors) {
    @each $slot in map.keys($slots-of-color) {
      $slots: map.set($slots, $slot, true);
    }
  }

  @each $slot in map.keys(map.merge($slots, ("hover": true, "active": true))) {
    --cui-theme-#{$slot}: initial;
  }
}

@mixin generate-theme-reset() {
  .theme-reset {
    @include theme-reset();
  }
}

Customizing

Utilities API

Theme utilities are declared in our utilities API in scss/_utilities.scss. Learn how to use the utilities API.

scss
// Theme style utilities — pair with .theme-{color} to apply coordinated
// background and text colors
"theme-contrast": (
  property: (
    "background-color": var(--cui-theme-bg),
    "color": var(--cui-theme-contrast)
  ),
  class: theme-contrast,
  values: (null: null)
),
"theme-subtle": (
  property: (
    "background-color": var(--cui-theme-bg-subtle),
    "color": var(--cui-theme-fg)
  ),
  class: theme-subtle,
  values: (null: null)
),
"theme-muted": (
  property: (
    "background-color": var(--cui-theme-bg-muted),
    "color": var(--cui-theme-fg-emphasis)
  ),
  class: theme-muted,
  values: (null: null)
),
"theme-border": (
  property: border,
  class: theme-border,
  values: (null: var(--cui-border-width) solid var(--cui-theme-border))
),