Context Class
How the .context class re-aims color CSS variables to a different palette, switching the look of a component — and everything inside it — with a single class.
The .context class is how Chassis CSS applies a color palette to a component. Components never hardcode color values; they read CSS custom properties such as --cx-fg-main and --cx-bg-main. The .context class re-aims those properties at a different palette, and any element nested inside picks up the new colors automatically.
How it works
Chassis CSS does not write color values directly on component classes. It uses repeating CSS custom properties, pairing them with Sass placeholder selectors that share the property declarations across components while keeping the color values flexible.
Three pieces work together:
- The
%contextplaceholder declares the full set of context-scoped variables and points them at the active body context. It iterates over every registered context color, generating one selector per palette (.context.primary,.context.success, …) that uses the context mixin to remap those variables. - Style placeholders (
%basic-context,%solid-context,%smooth-context,%outline-context) translate the context-scoped variables into the body variables that components actually read —--cx-fg-color,--cx-bg-color,--cx-border-color, and so on. Each style maps the palette tokens differently to produce a different visual treatment. - The
.contextclass extends%contextand the four style placeholders, which compiles into one class per color and style combination.
Placeholder selector
The %context placeholder declares the full set of context-scoped variables, iterates over $context-colors to generate one nested selector per color, and extends %basic-context so the basic style applies whenever .context is used without a style modifier. The shape of it:
%context {
// 36 context-scoped variables, each pointing at the active body context
--cx-fg-main: var(--cx-context-fg-main, var(--cx-{body-context}-fg-main));
--cx-bg-main: var(--cx-context-bg-main, var(--cx-{body-context}-bg-main));
// … one declaration per palette token
// One nested selector per context color, each remapping the variables above
@each $color in map-keys($context-colors) {
&.#{$color} { @include context($color); }
}
// Basic style is the default
@extend %basic-context;
}
The full source — including every variable declaration — lives under Sass mixins → Context placeholder.
Style placeholders
Each style placeholder maps the context-scoped variables onto the body variables differently. The basic style — also the default — looks like this:
%basic-context {
// Change body colors
--#{$prefix}fg-color: var(--#{$prefix}fg-main);
--#{$prefix}bg-color: var(--#{$prefix}bg-main);
--#{$prefix}border-color: var(--#{$prefix}border-subtle);
--#{$prefix}separator-color: var(--#{$prefix}border-subtle);
--#{$prefix}icon-color: var(--#{$prefix}icon-main);
--#{$prefix}bullet-color: var(--#{$prefix}icon-subtle);
--#{$prefix}cue-color: var(--#{$prefix}cue-main);
--#{$prefix}link-main-color: var(--#{$prefix}link-main);
--#{$prefix}link-hover-color: var(--#{$prefix}link-hover);
--#{$prefix}link-active-color: var(--#{$prefix}link-active);
--#{$prefix}link-visited-color: var(--#{$prefix}link-visited);
}
The full set is documented under Sass mixins.
Component class
The .context class extends the placeholders so every color × style combination is generated as a real, usable class:
.context {
@extend %context;
@include colors();
&.solid {
@extend %solid-context;
}
&.outline {
@extend %outline-context;
}
&.smooth {
@extend %smooth-context;
}
}
The compiled output ships ready to use:
This is the primary basic context.
This is the primary solid context.
This is the primary smooth context.
This is the primary outline context.
<p class="context primary">This is the primary basic context.</p>
<p class="context primary solid">This is the primary solid context.</p>
<p class="context primary smooth">This is the primary smooth context.</p>
<p class="context primary outline">This is the primary outline context.</p> Usage
Context colors
Adding a color name to .context switches the active palette. Each context color provides coordinated foreground, background, border, icon, link, and cue values, so a single class change propagates throughout the component and its descendants.
This is the body context with link, same as default.
This is the default context with link.
This is the alternate context with link.
This is the primary context with link.
This is the secondary context with link.
This is the neutral context with link.
This is the danger context with link.
This is the success context with link.
This is the warning context with link.
This is the info context with link.
This is the black context with link.
This is the white context with link.
<p class="p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is the body context <a href="#">with link</a>, same as default.
</p>
<p class="context default p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is the default context <a href="#">with link</a>.
</p>
<p class="context alternate p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is the alternate context <a href="#">with link</a>.
</p>
<p class="context primary p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is the primary context <a href="#">with link</a>.
</p>
<p class="context secondary p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is the secondary context <a href="#">with link</a>.
</p>
<p class="context neutral p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is the neutral context <a href="#">with link</a>.
</p>
<p class="context danger p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is the danger context <a href="#">with link</a>.
</p>
<p class="context success p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is the success context <a href="#">with link</a>.
</p>
<p class="context warning p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is the warning context <a href="#">with link</a>.
</p>
<p class="context info p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is the info context <a href="#">with link</a>.
</p>
<p class="context black p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is the black context <a href="#">with link</a>.
</p>
<p class="context white p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is the white context <a href="#">with link</a>.
</p> A few of the contexts can look similar at first glance but play distinct semantic roles and behave differently across light and dark modes:
default— the standard body context (light background with dark text in light mode, inverted in dark mode).alternate— emphasized regions such as sidebars or banners; may not invert in dark mode, depending on token configuration.neutral— a muted, low-emphasis surface drawn from the brandneutralhue.blackandwhite— absolute, fixed colors that do not adapt to light or dark mode.
This is the default basic context.
This is the alternate basic context.
This is the neutral basic context.
This is the black basic context.
This is the white basic context.
<p class="context default border">This is the default basic context.</p>
<p class="context alternate border">This is the alternate basic context.</p>
<p class="context neutral border">This is the neutral basic context.</p>
<p class="context black border">This is the black basic context.</p>
<p class="context white border">This is the white basic context.</p> Context styles
Adding a style modifier controls how the palette tokens are mapped onto each visual property. Four styles are available:
basic(default) — inherits the ambient background; switches foreground, border, and icon colors to the context.solid— fills with the context's primary background color and uses the inverted foreground for maximum contrast.smooth— fills with a tinted, low-opacity variant of the context background while keeping a readable foreground.outline— transparent background with the context color applied as a border and a tinted foreground.
This is a basic context component with link.
This is a solid context component with link.
This is a smooth context component with link.
This is an outline context component with link.
<p class="context primary p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is a basic context component <a href="#">with link</a>.
</p>
<p class="context primary solid p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is a solid context component <a href="#">with link</a>.
</p>
<p class="context primary smooth p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is a smooth context component <a href="#">with link</a>.
</p>
<p class="context primary outline p-xsmall">
<span class="icon icon-info-circle-solid"></span>
This is an outline context component <a href="#">with link</a>.
</p> Sass mixins
Context placeholder
The full source of %context — every variable declaration, the loop over $context-colors, and the @extend %basic-context — referenced from How it works above:
%context {
--#{$prefix}base-color: var(--#{$prefix}context-base-color, var(--#{$prefix}#{$body-context}-base-color));
--#{$prefix}contrast-color: var(--#{$prefix}context-contrast-color, var(--#{$prefix}#{$body-context}-contrast-color));
--#{$prefix}transparent-color: var(--#{$prefix}context-transparent-color, var(--#{$prefix}#{$body-context}-transparent-color));
--#{$prefix}fg-main: var(--#{$prefix}context-fg-main, var(--#{$prefix}#{$body-context}-fg-main));
--#{$prefix}fg-subtle: var(--#{$prefix}context-fg-subtle, var(--#{$prefix}#{$body-context}-fg-subtle));
--#{$prefix}fg-slight: var(--#{$prefix}context-fg-slight, var(--#{$prefix}#{$body-context}-fg-slight));
--#{$prefix}fg-inverse: var(--#{$prefix}context-fg-inverse, var(--#{$prefix}#{$body-context}-fg-inverse));
--#{$prefix}fg-solid: var(--#{$prefix}context-fg-solid, var(--#{$prefix}#{$body-context}-fg-solid));
--#{$prefix}fg-highlight: var(--#{$prefix}context-fg-highlight, var(--#{$prefix}#{$body-context}-fg-highlight));
--#{$prefix}bg-main: var(--#{$prefix}context-bg-main, var(--#{$prefix}#{$body-context}-bg-main));
--#{$prefix}bg-even: var(--#{$prefix}context-bg-even, var(--#{$prefix}#{$body-context}-bg-even));
--#{$prefix}bg-evident: var(--#{$prefix}context-bg-evident, var(--#{$prefix}#{$body-context}-bg-evident));
--#{$prefix}bg-inverse: var(--#{$prefix}context-bg-inverse, var(--#{$prefix}#{$body-context}-bg-inverse));
--#{$prefix}bg-solid: var(--#{$prefix}context-bg-solid, var(--#{$prefix}#{$body-context}-bg-solid));
--#{$prefix}bg-highlight: var(--#{$prefix}context-bg-highlight, var(--#{$prefix}#{$body-context}-bg-highlight));
--#{$prefix}border-main: var(--#{$prefix}context-border-main, var(--#{$prefix}#{$body-context}-border-main));
--#{$prefix}border-subtle: var(--#{$prefix}context-border-subtle, var(--#{$prefix}#{$body-context}-border-subtle));
--#{$prefix}icon-main: var(--#{$prefix}context-icon-main, var(--#{$prefix}#{$body-context}-icon-main));
--#{$prefix}icon-subtle: var(--#{$prefix}context-icon-subtle, var(--#{$prefix}#{$body-context}-icon-subtle));
--#{$prefix}icon-slight: var(--#{$prefix}context-icon-slight, var(--#{$prefix}#{$body-context}-icon-slight));
--#{$prefix}cue-main: var(--#{$prefix}context-cue-main, var(--#{$prefix}#{$body-context}-cue-main));
--#{$prefix}cue-slight: var(--#{$prefix}context-cue-slight, var(--#{$prefix}#{$body-context}-cue-slight));
--#{$prefix}link-main: var(--#{$prefix}context-link-main, var(--#{$prefix}#{$body-context}-link-main));
--#{$prefix}link-hover: var(--#{$prefix}context-link-hover, var(--#{$prefix}#{$body-context}-link-hover));
--#{$prefix}link-active: var(--#{$prefix}context-link-active, var(--#{$prefix}#{$body-context}-link-active));
--#{$prefix}link-visited: var(--#{$prefix}context-link-visited, var(--#{$prefix}#{$body-context}-link-visited));
--#{$prefix}dim-main: var(--#{$prefix}context-dim-main, var(--#{$prefix}#{$body-context}-dim-main));
--#{$prefix}dim-subtle: var(--#{$prefix}context-dim-subtle, var(--#{$prefix}#{$body-context}-dim-subtle));
--#{$prefix}dim-slight: var(--#{$prefix}context-dim-slight, var(--#{$prefix}#{$body-context}-dim-slight));
--#{$prefix}fg-idle: var(--#{$prefix}context-fg-idle, var(--#{$prefix}#{$body-context}-fg-idle));
--#{$prefix}fg-hover: var(--#{$prefix}context-fg-hover, var(--#{$prefix}#{$body-context}-fg-hover));
--#{$prefix}fg-press: var(--#{$prefix}context-fg-press, var(--#{$prefix}#{$body-context}-fg-press));
--#{$prefix}fg-disabled: var(--#{$prefix}context-fg-disabled, var(--#{$prefix}#{$body-context}-fg-disabled));
--#{$prefix}bg-idle: var(--#{$prefix}context-bg-idle, var(--#{$prefix}#{$body-context}-bg-idle));
--#{$prefix}bg-hover: var(--#{$prefix}context-bg-hover, var(--#{$prefix}#{$body-context}-bg-hover));
--#{$prefix}bg-press: var(--#{$prefix}context-bg-press, var(--#{$prefix}#{$body-context}-bg-press));
--#{$prefix}bg-disabled: var(--#{$prefix}context-bg-disabled, var(--#{$prefix}#{$body-context}-bg-disabled));
@each $color in map-keys($context-colors) {
&.#{$color} {
@include context($color);
}
}
@extend %basic-context;
}
Context mixin
The context() mixin generates the variable assignments for a single palette. Pass it a color name and it emits the CSS rules that point the context-scoped variables at that palette.
/// Activate a named context by mapping all context-scoped CSS custom properties to
/// a specific color palette. This overwrites every `--cx-context-*` variable on the
/// element so child components can consume `--cx-context-fg-main`, `--cx-context-bg-main`,
/// etc. without knowing which palette is active.
///
/// @param {String} $context - Context name corresponding to a registered color palette
/// (e.g., "primary", "success", "neutral")
/// @example
/// .my-component { @include context(primary); }
/// // => --cx-context-fg-main: var(--cx-primary-fg-main); etc.
@mixin context($context) {
--#{$prefix}context-base-color: var(--#{$prefix}#{$context}-base-color);
--#{$prefix}context-contrast-color: var(--#{$prefix}#{$context}-contrast-color);
--#{$prefix}context-transparent-color: var(--#{$prefix}#{$context}-transparent-color);
--#{$prefix}context-fg-main: var(--#{$prefix}#{$context}-fg-main);
--#{$prefix}context-fg-subtle: var(--#{$prefix}#{$context}-fg-subtle);
--#{$prefix}context-fg-slight: var(--#{$prefix}#{$context}-fg-slight);
--#{$prefix}context-fg-inverse: var(--#{$prefix}#{$context}-fg-inverse);
--#{$prefix}context-fg-solid: var(--#{$prefix}#{$context}-fg-solid);
--#{$prefix}context-fg-highlight: var(--#{$prefix}#{$context}-fg-highlight);
--#{$prefix}context-bg-main: var(--#{$prefix}#{$context}-bg-main);
--#{$prefix}context-bg-even: var(--#{$prefix}#{$context}-bg-even);
--#{$prefix}context-bg-evident: var(--#{$prefix}#{$context}-bg-evident);
--#{$prefix}context-bg-inverse: var(--#{$prefix}#{$context}-bg-inverse);
--#{$prefix}context-bg-solid: var(--#{$prefix}#{$context}-bg-solid);
--#{$prefix}context-bg-highlight: var(--#{$prefix}#{$context}-bg-highlight);
--#{$prefix}context-border-main: var(--#{$prefix}#{$context}-border-main);
--#{$prefix}context-border-subtle: var(--#{$prefix}#{$context}-border-subtle);
--#{$prefix}context-icon-main: var(--#{$prefix}#{$context}-icon-main);
--#{$prefix}context-icon-subtle: var(--#{$prefix}#{$context}-icon-subtle);
--#{$prefix}context-icon-slight: var(--#{$prefix}#{$context}-icon-slight);
--#{$prefix}context-cue-main: var(--#{$prefix}#{$context}-cue-main);
--#{$prefix}context-cue-slight: var(--#{$prefix}#{$context}-cue-slight);
--#{$prefix}context-link-main: var(--#{$prefix}#{$context}-link-main);
--#{$prefix}context-link-hover: var(--#{$prefix}#{$context}-link-hover);
--#{$prefix}context-link-active: var(--#{$prefix}#{$context}-link-active);
--#{$prefix}context-link-visited: var(--#{$prefix}#{$context}-link-visited);
--#{$prefix}context-dim-main: var(--#{$prefix}#{$context}-dim-main);
--#{$prefix}context-dim-subtle: var(--#{$prefix}#{$context}-dim-subtle);
--#{$prefix}context-dim-slight: var(--#{$prefix}#{$context}-dim-slight);
--#{$prefix}context-fg-idle: var(--#{$prefix}#{$context}-fg-idle);
--#{$prefix}context-fg-hover: var(--#{$prefix}#{$context}-fg-hover);
--#{$prefix}context-fg-press: var(--#{$prefix}#{$context}-fg-press);
--#{$prefix}context-fg-disabled: var(--#{$prefix}#{$context}-fg-disabled);
--#{$prefix}context-bg-idle: var(--#{$prefix}#{$context}-bg-idle);
--#{$prefix}context-bg-hover: var(--#{$prefix}#{$context}-bg-hover);
--#{$prefix}context-bg-press: var(--#{$prefix}#{$context}-bg-press);
--#{$prefix}context-bg-disabled: var(--#{$prefix}#{$context}-bg-disabled);
}
Style placeholders
The four style placeholders are available for @extend-ing inside any component that needs to react to a style modifier — for example, to give a button a .solid variant.
%basic-context {
// Change body colors
--#{$prefix}fg-color: var(--#{$prefix}fg-main);
--#{$prefix}bg-color: var(--#{$prefix}bg-main);
--#{$prefix}border-color: var(--#{$prefix}border-subtle);
--#{$prefix}separator-color: var(--#{$prefix}border-subtle);
--#{$prefix}icon-color: var(--#{$prefix}icon-main);
--#{$prefix}bullet-color: var(--#{$prefix}icon-subtle);
--#{$prefix}cue-color: var(--#{$prefix}cue-main);
--#{$prefix}link-main-color: var(--#{$prefix}link-main);
--#{$prefix}link-hover-color: var(--#{$prefix}link-hover);
--#{$prefix}link-active-color: var(--#{$prefix}link-active);
--#{$prefix}link-visited-color: var(--#{$prefix}link-visited);
}
%solid-context {
--#{$prefix}fg-main: #{$solid-fg-color};
--#{$prefix}fg-subtle: #{to-opacity($solid-fg-color, var(--#{$prefix}opacity-fg-subtle))};
--#{$prefix}fg-slight: #{to-opacity($solid-fg-color, var(--#{$prefix}opacity-fg-slight))};
--#{$prefix}fg-inverse: var(--#{$prefix}context-fg-inverse);
--#{$prefix}fg-solid: var(--#{$prefix}context-fg-solid);
--#{$prefix}fg-highlight: var(--#{$prefix}context-fg-inverse);
--#{$prefix}bg-main: #{$solid-bg-color};
--#{$prefix}bg-even: #{$solid-bg-even};
--#{$prefix}bg-evident: #{$solid-bg-evident};
--#{$prefix}bg-inverse: var(--#{$prefix}context-bg-inverse);
--#{$prefix}bg-solid: var(--#{$prefix}context-bg-solid);
--#{$prefix}bg-highlight: var(--#{$prefix}context-bg-inverse);
--#{$prefix}border-main: #{to-opacity($solid-border-color, var(--#{$prefix}opacity-border-main))};
--#{$prefix}border-subtle: #{to-opacity($solid-border-color, var(--#{$prefix}opacity-border-subtle))};
--#{$prefix}icon-main: #{$solid-icon-color};
--#{$prefix}icon-subtle: #{to-opacity($solid-icon-color, var(--#{$prefix}opacity-icon-subtle))};
--#{$prefix}icon-slight: #{to-opacity($solid-icon-color, var(--#{$prefix}opacity-icon-slight))};
--#{$prefix}cue-main: #{$solid-cue-color};
--#{$prefix}cue-slight: #{to-opacity($solid-cue-color, var(--#{$prefix}opacity-cue-slight))};
--#{$prefix}link-main: var(--#{$prefix}context-fg-solid);
--#{$prefix}link-hover: var(--#{$prefix}context-contrast-color);
--#{$prefix}link-active: var(--#{$prefix}context-fg-solid);
--#{$prefix}link-visited: var(--#{$prefix}context-fg-solid);
--#{$prefix}dim-main: #{to-opacity(var(--#{$prefix}context-bg-inverse), var(--#{$prefix}opacity-dim-main))};
--#{$prefix}dim-subtle: #{to-opacity(var(--#{$prefix}context-bg-inverse), var(--#{$prefix}opacity-dim-subtle))};
--#{$prefix}dim-slight: #{to-opacity(var(--#{$prefix}context-bg-inverse), var(--#{$prefix}opacity-dim-slight))};
// Class properties
// No borders for solid components
border: 0;
}
%smooth-context {
--#{$prefix}fg-main: #{$smooth-fg-color};
--#{$prefix}fg-subtle: #{to-opacity($smooth-fg-color, var(--#{$prefix}opacity-fg-subtle))};
--#{$prefix}fg-slight: #{to-opacity($smooth-fg-color, var(--#{$prefix}opacity-fg-slight))};
--#{$prefix}fg-inverse: var(--#{$prefix}context-fg-inverse);
--#{$prefix}fg-solid: var(--#{$prefix}context-fg-solid);
--#{$prefix}fg-highlight: var(--#{$prefix}context-fg-highlight);
--#{$prefix}bg-main: #{$smooth-bg-color};
--#{$prefix}bg-even: #{$smooth-bg-even};
--#{$prefix}bg-evident: #{$smooth-bg-evident};
--#{$prefix}bg-inverse: var(--#{$prefix}context-bg-inverse);
--#{$prefix}bg-solid: var(--#{$prefix}context-bg-solid);
--#{$prefix}bg-highlight: var(--#{$prefix}context-bg-inverse);
--#{$prefix}border-main: #{to-opacity($smooth-border-color, var(--#{$prefix}opacity-border-main))};
--#{$prefix}border-subtle: #{to-opacity($smooth-border-color, var(--#{$prefix}opacity-border-subtle))};
--#{$prefix}icon-main: #{$smooth-icon-color};
--#{$prefix}icon-subtle: #{to-opacity($smooth-icon-color, var(--#{$prefix}opacity-icon-subtle))};
--#{$prefix}icon-slight: #{to-opacity($smooth-icon-color, var(--#{$prefix}opacity-icon-slight))};
--#{$prefix}cue-main: #{$smooth-cue-color};
--#{$prefix}cue-slight: #{to-opacity($smooth-cue-color, var(--#{$prefix}opacity-cue-slight))};
--#{$prefix}link-main: var(--#{$prefix}context-link-main);
--#{$prefix}link-hover: var(--#{$prefix}context-link-hover);
--#{$prefix}link-active: var(--#{$prefix}context-link-active);
--#{$prefix}link-visited: var(--#{$prefix}context-link-visited);
--#{$prefix}dim-main: var(--#{$prefix}context-dim-main);
--#{$prefix}dim-subtle: var(--#{$prefix}context-dim-subtle);
--#{$prefix}dim-slight: var(--#{$prefix}context-dim-slight);
// Class properties
// No borders for solid components
border: 0;
}
%outline-context {
// @extend %basic-context;
--#{$prefix}fg-main: #{$outline-fg-color};
--#{$prefix}fg-subtle: #{to-opacity($outline-fg-color, var(--#{$prefix}opacity-fg-subtle))};
--#{$prefix}fg-slight: #{to-opacity($outline-fg-color, var(--#{$prefix}opacity-fg-slight))};
--#{$prefix}fg-inverse: var(--#{$prefix}context-fg-inverse);
--#{$prefix}fg-solid: var(--#{$prefix}context-fg-solid);
--#{$prefix}fg-highlight: var(--#{$prefix}context-fg-highlight);
--#{$prefix}bg-main: #{$outline-bg-color};
--#{$prefix}bg-even: #{$outline-bg-even};
--#{$prefix}bg-evident: #{$outline-bg-evident};
--#{$prefix}bg-inverse: var(--#{$prefix}context-bg-inverse);
--#{$prefix}bg-solid: var(--#{$prefix}context-bg-solid);
--#{$prefix}bg-highlight: var(--#{$prefix}context-bg-inverse);
--#{$prefix}border-main: #{to-opacity($outline-border-color, var(--#{$prefix}opacity-border-main))};
--#{$prefix}border-subtle: #{to-opacity($outline-border-color, var(--#{$prefix}opacity-border-subtle))};
--#{$prefix}icon-main: #{$outline-icon-color};
--#{$prefix}icon-subtle: #{to-opacity($outline-icon-color, var(--#{$prefix}opacity-icon-subtle))};
--#{$prefix}icon-slight: #{to-opacity($outline-icon-color, var(--#{$prefix}opacity-icon-slight))};
--#{$prefix}cue-main: #{$outline-cue-color};
--#{$prefix}cue-slight: #{to-opacity($outline-cue-color, var(--#{$prefix}opacity-cue-slight))};
--#{$prefix}link-main: var(--#{$prefix}context-link-main);
--#{$prefix}link-hover: var(--#{$prefix}context-link-hover);
--#{$prefix}link-active: var(--#{$prefix}context-link-active);
--#{$prefix}link-visited: var(--#{$prefix}context-link-visited);
--#{$prefix}dim-main: var(--#{$prefix}context-dim-main);
--#{$prefix}dim-subtle: var(--#{$prefix}context-dim-subtle);
--#{$prefix}dim-slight: var(--#{$prefix}context-dim-slight);
// Class properties
// Increase border width for outline components
--#{$prefix}border-width: #{$outline-border-width};
--#{$prefix}border-color: #{$outline-border-color};
--#{$prefix}separator-color: #{$outline-border-color};
@include border();
}
Component placeholder
Components such as badges and notifications also extend the %component placeholder, which assigns the spacing, typography, and color CSS variables to the actual properties:
// Comprehensive base styling for components.
//
// Applies a complete set of foundational styles that most components need:
// - Typography via font mixin
// - Color scheme via colors mixin (text, background, border colors)
// - Border radius for consistent corner styling
// - Border properties with appropriate fallbacks
//
// Use this placeholder when creating new components that need the full
// set of Chassis styling fundamentals.
%component {
@include font();
@include colors();
@include border-radius();
@include border();
}
Custom components
The same building blocks let you write your own context-aware components. The three examples below progress from a simple fallback chain to a fully context-aware component with a .solid modifier.
Custom property with a fallback
.example declares a single CSS custom property with a built-in fallback chain. Override the property where you need a specific value; everywhere else it falls back to a context-aware token.
:root {
--example-fg: #282;
}
.example {
color: var(--example-fg, var(--cx-fg-subtle));
}
The custom property can be overridden inline, falls back to --cx-fg-highlight when the override is invalid, and ultimately adapts to the active context via that token.
--example-fg
--example-fg is --cx-fg-highlight
--example-fg falls back to --cx-fg-subtle
--example-fg
--example-fg falls back to --cx-fg-subtle
--cx-fg-main
<div>
<p class="example">--example-fg</p>
</div>
<div style="--example-fg: var(--cx-fg-highlight);">
<p class="example">--example-fg is --cx-fg-highlight</p>
</div>
<div style="--example-fg: var(--no-color);">
<p class="example">--example-fg falls back to --cx-fg-subtle</p>
</div>
<div class="context primary">
<p class="example">--example-fg</p>
</div>
<div class="context primary" style="--example-fg: var(--no-color);">
<p class="example">--example-fg falls back to --cx-fg-subtle</p>
</div>
<div class="context primary">
<p>--cx-fg-main</p>
</div> Intercepting style overrides
.example-2 is a context component that uses --cx-fg-subtle for its color. It reserves a component-scoped custom property as a hook for future overrides.
.example-2 {
@extend %context;
// %solid-context will override --cx-fg-color with --cx-fg-solid.
--cx-fg-color: var(--example-fg-color, var(--cx-fg-subtle));
// --cx-bg-color: var(--example-bg-color, var(--cx-bg-even));
// Override the override of %solid-context.
--cx-solid-fg-color: var(--cx-fg-subtle);
color: var(--cx-fg-color);
background-color: var(--cx-bg-color);
&.solid {
@extend %solid-context;
}
}
The %solid-context placeholder normally overrides --cx-fg-color with --cx-fg-main. Setting --cx-fg-subtle as --cx-fg-color first lets us intercept that override and keep the subtle foreground intact in the solid style.
--cx-fg-subtle
--cx-fg-subtle
--cx-fg-subtle
<p class="example-2">--cx-fg-subtle</p>
<p class="example-2 primary">--cx-fg-subtle</p>
<p class="example-2 primary solid">--cx-fg-subtle</p> Full context component
.example-3 is a fully context-aware component. It maps component-scoped custom properties onto body color variables and supports the solid style modifier:
.example-3 {
@extend %context, %basic-context;
--component-fg-color: var(--example-fg-color, var(--cx-fg-main));
--component-bg-color: var(--example-bg-color, var(--cx-bg-even));
color: var(--component-fg-color);
// This will break solid style background.
background-color: var(--component-bg-color);
&.solid {
@extend %solid-context;
// Restoring solid style background.
background-color: var(--example-solid-bg-color, var(--cx-bg-solid));
}
}
--cx-fg-main
--cx-fg-main
--cx-fg-main
<p class="example-3 p-xsmall">--cx-fg-main</p>
<p class="example-3 primary p-xsmall">--cx-fg-main</p>
<p class="example-3 primary solid p-xsmall">--cx-fg-main</p> See also
- Color System — how primitive scales, context palettes, and body variables are layered.
- Colors utility —
fg-*foreground utility classes. - Background utility —
bg-*background utility classes.