Skip to main contentSkip to docs navigation

Foreground color utilities based on the Chassis context color system, with opacity control.

@layer utilities

Accessibility tip: Color alone shouldn't convey meaning as it's not perceived by assistive technology users. Ensure clarity through text with adequate contrast, ARIA attributes where needed, and consider using .visually-hidden for screen reader content.

Color utilities cover two sub-systems: context colors and opacity control. Both integrate with the color system.

Color

Color utilities set the CSS color property using the Chassis context color palette. They do not set background-color, so .bg-* background utilities may be needed for colored regions. For link colorization with interactive states (:hover, :focus, :active, :visited), see the .link-* utilities.

Body colors

Body color classes draw from the default context palette.

.fg-main

.fg-subtle

.fg-slight

.fg-inverse

.fg-solid

.fg-highlight

HTML
<p class="fg-main">.fg-main</p>
<p class="fg-subtle">.fg-subtle</p>
<p class="fg-slight">.fg-slight</p>
<p class="fg-inverse bg-inverse">.fg-inverse</p>
<p class="fg-solid">.fg-solid</p>
<p class="fg-highlight">.fg-highlight</p>

Context foreground colors

Context colors are available as foreground utilities via the .fg-{context} class pattern.

.fg-default

.fg-alternate

.fg-primary

.fg-secondary

.fg-neutral

.fg-danger

.fg-success

.fg-warning

.fg-info

.fg-black

.fg-white

HTML
<p class="fg-default bg-contrast">.fg-default</p>
<p class="fg-alternate bg-contrast">.fg-alternate</p>
<p class="fg-primary bg-contrast">.fg-primary</p>
<p class="fg-secondary bg-contrast">.fg-secondary</p>
<p class="fg-neutral bg-contrast">.fg-neutral</p>
<p class="fg-danger bg-contrast">.fg-danger</p>
<p class="fg-success bg-contrast">.fg-success</p>
<p class="fg-warning bg-contrast">.fg-warning</p>
<p class="fg-info bg-contrast">.fg-info</p>
<p class="fg-black bg-contrast">.fg-black</p>
<p class="fg-white bg-contrast">.fg-white</p>

Context palette colors

Each context color exposes a set of foreground roles through a {context}-fg-{role} prefixed class pattern.

.primary-fg-main

.primary-fg-subtle

.primary-fg-slight

.primary-fg-inverse

.primary-fg-highlight

HTML
<p class="primary-fg-main">.primary-fg-main</p>
<p class="primary-fg-subtle">.primary-fg-subtle</p>
<p class="primary-fg-slight">.primary-fg-slight</p>
<p class="primary-fg-inverse primary-bg-inverse">.primary-fg-inverse</p>
<p class="primary-fg-highlight">.primary-fg-highlight</p>

Opacity

Opacity utilities control the alpha channel of any context color foreground through the --cx-fg-opacity custom property.

How it works

Each .fg-{context} class writes an OKLCH relative color expression into --cx-fg-color, using --cx-fg-opacity as the alpha channel. A shared selector applies color: var(--cx-fg-color). --cx-fg-opacity defaults to 1.

CSS
.fg-primary {
  --cx-fg-color: oklch(from var(--cx-primary) l c h / var(--cx-fg-opacity, 1));
}

/* shared selector */
.fg-primary, .fg-secondary, /* … */ {
  color: var(--cx-fg-color);
}

.fg-opacity-50 {
  --cx-fg-opacity: 0.5;
}

Opacity override

Override --cx-fg-opacity with an inline style or a .fg-opacity-* utility class.

This is default primary text
This is 60% opacity primary text
HTML
<div class="fg-primary">This is default primary text</div>
<div style="--cx-fg-opacity: .6;" class="fg-primary">This is 60% opacity primary text</div>

Or, choose from any of the .fg-opacity-* utilities:

fg-opacity-solid

fg-opacity-95

fg-opacity-90

fg-opacity-80

fg-opacity-70

fg-opacity-60

fg-opacity-50

fg-opacity-40

fg-opacity-30

fg-opacity-20

fg-opacity-10

fg-opacity-05

fg-opacity-zero

HTML
<p class="fg-primary fg-opacity-solid">fg-opacity-solid</p>
<p class="fg-primary fg-opacity-95">fg-opacity-95</p>
<p class="fg-primary fg-opacity-90">fg-opacity-90</p>
<p class="fg-primary fg-opacity-80">fg-opacity-80</p>
<p class="fg-primary fg-opacity-70">fg-opacity-70</p>
<p class="fg-primary fg-opacity-60">fg-opacity-60</p>
<p class="fg-primary fg-opacity-50">fg-opacity-50</p>
<p class="fg-primary fg-opacity-40">fg-opacity-40</p>
<p class="fg-primary fg-opacity-30">fg-opacity-30</p>
<p class="fg-primary fg-opacity-20">fg-opacity-20</p>
<p class="fg-primary fg-opacity-10">fg-opacity-10</p>
<p class="fg-primary fg-opacity-05">fg-opacity-05</p>
<p class="fg-primary fg-opacity-zero">fg-opacity-zero</p>

Context opacities

.fg-opacity-subtle and .fg-opacity-slight match the alpha values of the pre-computed fg-subtle and fg-slight body color tokens, and can be applied to any context color.

fg-opacity-subtle
fg-opacity-slight
HTML
<div class="fg-primary fg-opacity-subtle p-2xsmall">fg-opacity-subtle</div>
<div class="fg-primary fg-opacity-slight p-2xsmall">fg-opacity-slight</div>

Reset color

.fg-reset removes any foreground color override, causing the element to inherit its color from the nearest ancestor.

Secondary body text with a reset link.

Secondary body text with a normal link.

HTML
<p class="fg-subtle">
  Secondary body text with a <a href="#" class="fg-reset">reset link</a>.
</p>
<p class="fg-subtle">
  Secondary body text with a <a href="#">normal link</a>.
</p>

CSS

Foreground color utilities are generated from Sass maps built on design token values via the utilities API.

Reference

All foreground color utilities set color through the shared --cx-fg-color custom property. Context color foregrounds embed --cx-fg-opacity in the color expression; body and palette foregrounds reference a pre-computed token and are not affected by opacity utilities.

The tables list all foreground color utilities and their CSS properties.

Foreground colors:

ClassProperties
.fg-default--cx-fg-color: oklch(from var(--cx-default) l c h / var(--cx-fg-opacity, 1));
.fg-alternate--cx-fg-color: oklch(from var(--cx-alternate) l c h / var(--cx-fg-opacity, 1));
.fg-primary--cx-fg-color: oklch(from var(--cx-primary) l c h / var(--cx-fg-opacity, 1));
.fg-secondary--cx-fg-color: oklch(from var(--cx-secondary) l c h / var(--cx-fg-opacity, 1));
.fg-neutral--cx-fg-color: oklch(from var(--cx-neutral) l c h / var(--cx-fg-opacity, 1));
.fg-warning--cx-fg-color: oklch(from var(--cx-warning) l c h / var(--cx-fg-opacity, 1));
.fg-success--cx-fg-color: oklch(from var(--cx-success) l c h / var(--cx-fg-opacity, 1));
.fg-danger--cx-fg-color: oklch(from var(--cx-danger) l c h / var(--cx-fg-opacity, 1));
.fg-info--cx-fg-color: oklch(from var(--cx-info) l c h / var(--cx-fg-opacity, 1));
.fg-black--cx-fg-color: oklch(from var(--cx-black) l c h / var(--cx-fg-opacity, 1));
.fg-white--cx-fg-color: oklch(from var(--cx-white) l c h / var(--cx-fg-opacity, 1));
.fg-default-contrast--cx-fg-color: oklch(from var(--cx-default-contrast) l c h / var(--cx-fg-opacity, 1));
.fg-alternate-contrast--cx-fg-color: oklch(from var(--cx-alternate-contrast) l c h / var(--cx-fg-opacity, 1));
.fg-primary-contrast--cx-fg-color: oklch(from var(--cx-primary-contrast) l c h / var(--cx-fg-opacity, 1));
.fg-secondary-contrast--cx-fg-color: oklch(from var(--cx-secondary-contrast) l c h / var(--cx-fg-opacity, 1));
.fg-neutral-contrast--cx-fg-color: oklch(from var(--cx-neutral-contrast) l c h / var(--cx-fg-opacity, 1));
.fg-warning-contrast--cx-fg-color: oklch(from var(--cx-warning-contrast) l c h / var(--cx-fg-opacity, 1));
.fg-success-contrast--cx-fg-color: oklch(from var(--cx-success-contrast) l c h / var(--cx-fg-opacity, 1));
.fg-danger-contrast--cx-fg-color: oklch(from var(--cx-danger-contrast) l c h / var(--cx-fg-opacity, 1));
.fg-info-contrast--cx-fg-color: oklch(from var(--cx-info-contrast) l c h / var(--cx-fg-opacity, 1));
.fg-black-contrast--cx-fg-color: oklch(from var(--cx-black-contrast) l c h / var(--cx-fg-opacity, 1));
.fg-white-contrast--cx-fg-color: oklch(from var(--cx-white-contrast) l c h / var(--cx-fg-opacity, 1));
.fg-main--cx-fg-color: var(--cx-fg-main);
.fg-subtle--cx-fg-color: var(--cx-fg-subtle);
.fg-slight--cx-fg-color: var(--cx-fg-slight);
.fg-active--cx-fg-color: var(--cx-fg-active);
.fg-inverse--cx-fg-color: var(--cx-fg-inverse);
.fg-solid--cx-fg-color: var(--cx-fg-solid);
.fg-highlight--cx-fg-color: var(--cx-fg-highlight);
.fg-idle--cx-fg-color: var(--cx-fg-idle);
.fg-disabled--cx-fg-color: var(--cx-fg-disabled);
.fg-hover--cx-fg-color: var(--cx-fg-hover);
.fg-press--cx-fg-color: var(--cx-fg-press);
.fg-reset--cx-fg-color: inherit;

Foreground opacities:

ClassProperties
.fg-opacity-solid--cx-fg-opacity: var(--cx-opacity-solid);
.fg-opacity-95--cx-fg-opacity: var(--cx-opacity-95);
.fg-opacity-90--cx-fg-opacity: var(--cx-opacity-90);
.fg-opacity-80--cx-fg-opacity: var(--cx-opacity-80);
.fg-opacity-70--cx-fg-opacity: var(--cx-opacity-70);
.fg-opacity-60--cx-fg-opacity: var(--cx-opacity-60);
.fg-opacity-50--cx-fg-opacity: var(--cx-opacity-50);
.fg-opacity-40--cx-fg-opacity: var(--cx-opacity-40);
.fg-opacity-30--cx-fg-opacity: var(--cx-opacity-30);
.fg-opacity-20--cx-fg-opacity: var(--cx-opacity-20);
.fg-opacity-10--cx-fg-opacity: var(--cx-opacity-10);
.fg-opacity-05--cx-fg-opacity: var(--cx-opacity-05);
.fg-opacity-zero--cx-fg-opacity: var(--cx-opacity-zero);
.fg-opacity-subtle--cx-fg-opacity: var(--cx-opacity-fg-subtle);
.fg-opacity-slight--cx-fg-opacity: var(--cx-opacity-fg-slight);

Contextual foregrounds:

ClassProperties
.default-fg-main--cx-fg-color: var(--cx-default-fg-main);
.alternate-fg-main--cx-fg-color: var(--cx-alternate-fg-main);
.primary-fg-main--cx-fg-color: var(--cx-primary-fg-main);
.secondary-fg-main--cx-fg-color: var(--cx-secondary-fg-main);
.neutral-fg-main--cx-fg-color: var(--cx-neutral-fg-main);
.danger-fg-main--cx-fg-color: var(--cx-danger-fg-main);
.success-fg-main--cx-fg-color: var(--cx-success-fg-main);
.warning-fg-main--cx-fg-color: var(--cx-warning-fg-main);
.info-fg-main--cx-fg-color: var(--cx-info-fg-main);
.black-fg-main--cx-fg-color: var(--cx-black-fg-main);
.white-fg-main--cx-fg-color: var(--cx-white-fg-main);
.default-fg-subtle--cx-fg-color: var(--cx-default-fg-subtle);
.alternate-fg-subtle--cx-fg-color: var(--cx-alternate-fg-subtle);
.primary-fg-subtle--cx-fg-color: var(--cx-primary-fg-subtle);
.secondary-fg-subtle--cx-fg-color: var(--cx-secondary-fg-subtle);
.neutral-fg-subtle--cx-fg-color: var(--cx-neutral-fg-subtle);
.danger-fg-subtle--cx-fg-color: var(--cx-danger-fg-subtle);
.success-fg-subtle--cx-fg-color: var(--cx-success-fg-subtle);
.warning-fg-subtle--cx-fg-color: var(--cx-warning-fg-subtle);
.info-fg-subtle--cx-fg-color: var(--cx-info-fg-subtle);
.black-fg-subtle--cx-fg-color: var(--cx-black-fg-subtle);
.white-fg-subtle--cx-fg-color: var(--cx-white-fg-subtle);
.default-fg-slight--cx-fg-color: var(--cx-default-fg-slight);
.alternate-fg-slight--cx-fg-color: var(--cx-alternate-fg-slight);
.primary-fg-slight--cx-fg-color: var(--cx-primary-fg-slight);
.secondary-fg-slight--cx-fg-color: var(--cx-secondary-fg-slight);
.neutral-fg-slight--cx-fg-color: var(--cx-neutral-fg-slight);
.danger-fg-slight--cx-fg-color: var(--cx-danger-fg-slight);
.success-fg-slight--cx-fg-color: var(--cx-success-fg-slight);
.warning-fg-slight--cx-fg-color: var(--cx-warning-fg-slight);
.info-fg-slight--cx-fg-color: var(--cx-info-fg-slight);
.black-fg-slight--cx-fg-color: var(--cx-black-fg-slight);
.white-fg-slight--cx-fg-color: var(--cx-white-fg-slight);
.default-fg-active--cx-fg-color: var(--cx-default-fg-active);
.alternate-fg-active--cx-fg-color: var(--cx-alternate-fg-active);
.primary-fg-active--cx-fg-color: var(--cx-primary-fg-active);
.secondary-fg-active--cx-fg-color: var(--cx-secondary-fg-active);
.neutral-fg-active--cx-fg-color: var(--cx-neutral-fg-active);
.danger-fg-active--cx-fg-color: var(--cx-danger-fg-active);
.success-fg-active--cx-fg-color: var(--cx-success-fg-active);
.warning-fg-active--cx-fg-color: var(--cx-warning-fg-active);
.info-fg-active--cx-fg-color: var(--cx-info-fg-active);
.black-fg-active--cx-fg-color: var(--cx-black-fg-active);
.white-fg-active--cx-fg-color: var(--cx-white-fg-active);
.default-fg-inverse--cx-fg-color: var(--cx-default-fg-inverse);
.alternate-fg-inverse--cx-fg-color: var(--cx-alternate-fg-inverse);
.primary-fg-inverse--cx-fg-color: var(--cx-primary-fg-inverse);
.secondary-fg-inverse--cx-fg-color: var(--cx-secondary-fg-inverse);
.neutral-fg-inverse--cx-fg-color: var(--cx-neutral-fg-inverse);
.danger-fg-inverse--cx-fg-color: var(--cx-danger-fg-inverse);
.success-fg-inverse--cx-fg-color: var(--cx-success-fg-inverse);
.warning-fg-inverse--cx-fg-color: var(--cx-warning-fg-inverse);
.info-fg-inverse--cx-fg-color: var(--cx-info-fg-inverse);
.black-fg-inverse--cx-fg-color: var(--cx-black-fg-inverse);
.white-fg-inverse--cx-fg-color: var(--cx-white-fg-inverse);
.default-fg-solid--cx-fg-color: var(--cx-default-fg-solid);
.alternate-fg-solid--cx-fg-color: var(--cx-alternate-fg-solid);
.primary-fg-solid--cx-fg-color: var(--cx-primary-fg-solid);
.secondary-fg-solid--cx-fg-color: var(--cx-secondary-fg-solid);
.neutral-fg-solid--cx-fg-color: var(--cx-neutral-fg-solid);
.danger-fg-solid--cx-fg-color: var(--cx-danger-fg-solid);
.success-fg-solid--cx-fg-color: var(--cx-success-fg-solid);
.warning-fg-solid--cx-fg-color: var(--cx-warning-fg-solid);
.info-fg-solid--cx-fg-color: var(--cx-info-fg-solid);
.black-fg-solid--cx-fg-color: var(--cx-black-fg-solid);
.white-fg-solid--cx-fg-color: var(--cx-white-fg-solid);
.default-fg-highlight--cx-fg-color: var(--cx-default-fg-highlight);
.alternate-fg-highlight--cx-fg-color: var(--cx-alternate-fg-highlight);
.primary-fg-highlight--cx-fg-color: var(--cx-primary-fg-highlight);
.secondary-fg-highlight--cx-fg-color: var(--cx-secondary-fg-highlight);
.neutral-fg-highlight--cx-fg-color: var(--cx-neutral-fg-highlight);
.danger-fg-highlight--cx-fg-color: var(--cx-danger-fg-highlight);
.success-fg-highlight--cx-fg-color: var(--cx-success-fg-highlight);
.warning-fg-highlight--cx-fg-color: var(--cx-warning-fg-highlight);
.info-fg-highlight--cx-fg-color: var(--cx-info-fg-highlight);
.black-fg-highlight--cx-fg-color: var(--cx-black-fg-highlight);
.white-fg-highlight--cx-fg-color: var(--cx-white-fg-highlight);
.default-fg-idle--cx-fg-color: var(--cx-default-fg-idle);
.alternate-fg-idle--cx-fg-color: var(--cx-alternate-fg-idle);
.primary-fg-idle--cx-fg-color: var(--cx-primary-fg-idle);
.secondary-fg-idle--cx-fg-color: var(--cx-secondary-fg-idle);
.neutral-fg-idle--cx-fg-color: var(--cx-neutral-fg-idle);
.danger-fg-idle--cx-fg-color: var(--cx-danger-fg-idle);
.success-fg-idle--cx-fg-color: var(--cx-success-fg-idle);
.warning-fg-idle--cx-fg-color: var(--cx-warning-fg-idle);
.info-fg-idle--cx-fg-color: var(--cx-info-fg-idle);
.black-fg-idle--cx-fg-color: var(--cx-black-fg-idle);
.white-fg-idle--cx-fg-color: var(--cx-white-fg-idle);
.default-fg-disabled--cx-fg-color: var(--cx-default-fg-disabled);
.alternate-fg-disabled--cx-fg-color: var(--cx-alternate-fg-disabled);
.primary-fg-disabled--cx-fg-color: var(--cx-primary-fg-disabled);
.secondary-fg-disabled--cx-fg-color: var(--cx-secondary-fg-disabled);
.neutral-fg-disabled--cx-fg-color: var(--cx-neutral-fg-disabled);
.danger-fg-disabled--cx-fg-color: var(--cx-danger-fg-disabled);
.success-fg-disabled--cx-fg-color: var(--cx-success-fg-disabled);
.warning-fg-disabled--cx-fg-color: var(--cx-warning-fg-disabled);
.info-fg-disabled--cx-fg-color: var(--cx-info-fg-disabled);
.black-fg-disabled--cx-fg-color: var(--cx-black-fg-disabled);
.white-fg-disabled--cx-fg-color: var(--cx-white-fg-disabled);
.default-fg-hover--cx-fg-color: var(--cx-default-fg-hover);
.alternate-fg-hover--cx-fg-color: var(--cx-alternate-fg-hover);
.primary-fg-hover--cx-fg-color: var(--cx-primary-fg-hover);
.secondary-fg-hover--cx-fg-color: var(--cx-secondary-fg-hover);
.neutral-fg-hover--cx-fg-color: var(--cx-neutral-fg-hover);
.danger-fg-hover--cx-fg-color: var(--cx-danger-fg-hover);
.success-fg-hover--cx-fg-color: var(--cx-success-fg-hover);
.warning-fg-hover--cx-fg-color: var(--cx-warning-fg-hover);
.info-fg-hover--cx-fg-color: var(--cx-info-fg-hover);
.black-fg-hover--cx-fg-color: var(--cx-black-fg-hover);
.white-fg-hover--cx-fg-color: var(--cx-white-fg-hover);
.default-fg-press--cx-fg-color: var(--cx-default-fg-press);
.alternate-fg-press--cx-fg-color: var(--cx-alternate-fg-press);
.primary-fg-press--cx-fg-color: var(--cx-primary-fg-press);
.secondary-fg-press--cx-fg-color: var(--cx-secondary-fg-press);
.neutral-fg-press--cx-fg-color: var(--cx-neutral-fg-press);
.danger-fg-press--cx-fg-color: var(--cx-danger-fg-press);
.success-fg-press--cx-fg-color: var(--cx-success-fg-press);
.warning-fg-press--cx-fg-color: var(--cx-warning-fg-press);
.info-fg-press--cx-fg-color: var(--cx-info-fg-press);
.black-fg-press--cx-fg-color: var(--cx-black-fg-press);
.white-fg-press--cx-fg-color: var(--cx-white-fg-press);

Sass variables

Foreground color tokens are part of the color system color system in scss/tokens/ and not listed here.

Sass maps

Foreground color maps are part of the color system in scss/maps/ and not listed here. Foreground opacity utilities are generated from two Sass maps in scss/maps/_opacities.scss.

$opacities defines the full token-named opacity scale for .fg-opacity-{level} utilities.

$opacities: (
  "solid":                $opacity-solid,
  "95":                   $opacity-95,
  "90":                   $opacity-90,
  "80":                   $opacity-80,
  "70":                   $opacity-70,
  "60":                   $opacity-60,
  "50":                   $opacity-50,
  "40":                   $opacity-40,
  "30":                   $opacity-30,
  "20":                   $opacity-20,
  "10":                   $opacity-10,
  "05":                   $opacity-05,
  "zero":                 $opacity-zero,
);

$fg-opacities defines two semantic foreground opacity levels.

$fg-opacities: (
  "subtle": $opacity-fg-subtle,
  "slight": $opacity-fg-slight,
);

Utilities API

Foreground color utilities are declared in scss/utilities/_index.scss using the utilities API.

"fg-color": (
  property: (
    "color": var(--fg-color),
    "--fg-color": null
  ),
  class: null,
  group: true,
  values: map-merge-multiple(
    map-rename-keys(map-loop($context-colors, opacity-var, #{"$key"}, #{"fg"}), "fg-", "start"),
    map-rename-keys(map-loop($contrast-colors, opacity-var, #{"$key"}, #{"fg"}), "fg-", "start"),
    map-loop($context-fg-colors, varify, #{"$key"}),
    map-loop($body-fg-colors, varify, #{"$key"}),
    ( "fg-reset": inherit )
  )
),
"fg-opacity": (
  property: --fg-opacity,
  class: fg-opacity,
  enabled: $enable-property-opacities,
  values: map-merge-multiple(
    map-loop($opacities, varify, "$key", "opacity"),
    map-loop($fg-opacities, varify, "$key", "opacity-fg")
  )
),