Skip to main content Skip to docs navigation

Explore Chassis CSS's button components — precision-crafted controls that seamlessly bridge your Figma designs and code implementation through design tokens.

Introduction

Buttons in Chassis CSS are designed to provide consistent interactive controls across your interface while maintaining pixel-perfect fidelity with your Figma designs. Unlike other frameworks that provide generic button styles, Chassis buttons are built on design tokens that synchronize directly with your Figma components, ensuring design-to-development coherence.

Foundation class

Chassis CSS provides a foundational .button class that establishes the core interactive behavior, layout parameters, and typographic treatment for all button variants. This class serves as the structural backbone upon which all button variants are built.

html
<button type="button" class="button">Foundation class</button>
<button type="button" class="button default">Default Button</button>
<button type="button" class="button primary">Primary Button</button>
<button type="button" class="button link">Link</button>

The .button foundation class is designed to be extended with contextual classes that define purpose-specific styling, or to serve as a starting point for your own custom button implementations.

Accessibility: The foundational .button class already includes built-in focus styles that ensure proper keyboard navigation and accessibility compliance.

Button variants

Chassis CSS provides a range of purpose-driven button variants, each mapped to a specific design token context. These variants ensure consistent semantics across your interface.

html
<button type="button" class="button default">Default</button>
<button type="button" class="button alternate">Alternate</button>
<button type="button" class="button primary">Primary</button>
<button type="button" class="button secondary">Secondary</button>
<button type="button" class="button neutral">Neutral</button>
<button type="button" class="button danger">Danger</button>
<button type="button" class="button success">Success</button>
<button type="button" class="button warning">Warning</button>
<button type="button" class="button info">Info</button>
<button type="button" class="button black">Black</button>
<button type="button" class="button white">White</button>

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.

Outline variants

For interfaces requiring more subtle interaction elements, the .outline modifier transforms any button into a borderline-focused variant with a transparent background while retaining its semantic color context.

html
<button type="button" class="button default outline">Default</button>
<button type="button" class="button alternate outline">Alternate</button>
<button type="button" class="button primary outline">Primary</button>
<button type="button" class="button secondary outline">Secondary</button>
<button type="button" class="button neutral outline">Neutral</button>
<button type="button" class="button danger outline">Danger</button>
<button type="button" class="button success outline">Success</button>
<button type="button" class="button warning outline">Warning</button>
<button type="button" class="button info outline">Info</button>
<button type="button" class="button black outline">Black</button>
<button type="button" class="button white outline">White</button>

Some button variants use lighter foreground colors and are optimized for dark backgrounds to ensure proper contrast ratios.

Smooth variants

The .smooth modifier applies a subdued background to buttons, creating a softer presence in the interface while maintaining their contextual meaning.

html
<button type="button" class="button default smooth">Default</button>
<button type="button" class="button alternate smooth">Alternate</button>
<button type="button" class="button primary smooth">Primary</button>
<button type="button" class="button secondary smooth">Secondary</button>
<button type="button" class="button neutral smooth">Neutral</button>
<button type="button" class="button danger smooth">Danger</button>
<button type="button" class="button success smooth">Success</button>
<button type="button" class="button warning smooth">Warning</button>
<button type="button" class="button info smooth">Info</button>
<button type="button" class="button black smooth">Black</button>
<button type="button" class="button white smooth">White</button>

Element compatibility

While the .button classes are optimized for the semantic <button> element, they work equally well with alternative elements:

Link
html
<button class="button primary" type="submit">Button</button>
<input class="button primary" type="button" value="Input">
<input class="button primary" type="submit" value="Submit">
<input class="button primary" type="reset" value="Reset">
<a class="button primary" href="" role="button">Link</a>

When using button classes on <a> elements for in-page functionality rather than navigation, include role="button" to ensure proper semantic meaning for assistive technologies.

Icon integration

Chassis CSS provides purpose-built classes for icon placement within buttons. Both SVG icons and icon fonts can be used within buttons.

html
<button type="button" class="button default">
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
  <span>Default</span>
</button>
<button type="button" class="button primary">
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
  <span>Primary</span>
</button>
<button type="button" class="button default">
  <span>Default</span>
  <span class="icon icon-info-circle-solid" aria-hidden="true"></span>
</button>
<button type="button" class="button primary">
  <span>Primary</span>
  <span class="icon icon-info-circle-solid" aria-hidden="true"></span>
</button>

Icon spacing is automatically applied using :first-child and :last-child pseudo selectors. To ensure proper spacing, wrap the chip text in a <span> element.

Icon-only buttons

For buttons that consist solely of an icon, Chassis CSS provides built-in support to ensure proper sizing and alignment. Simply include the icon element within the button without any accompanying text.

html
<button type="button" class="button default">
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
</button>
<button type="button" class="button primary">
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
</button>
<button type="button" class="button small default">
  <span class="icon icon-info-circle-solid" aria-hidden="true"></span>
</button>
<button type="button" class="button small primary">
  <span class="icon icon-info-circle-solid" aria-hidden="true"></span>
</button>
<button type="button" class="button large default">
  <span class="icon icon-info-circle-solid" aria-hidden="true"></span>
</button>
<button type="button" class="button default large">
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
</button>
<button type="button" class="button large primary">
  <span class="icon icon-info-circle-solid" aria-hidden="true"></span>
</button>

Size variants

Chassis provides three predefined size variants through the .large and .small modifier classes, with the default size applied when no modifier is present.

html
<button type="button" class="button default large">
  Default
</button>
<button type="button" class="button default large">
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
  <span>Default</span>
</button>
<button type="button" class="button primary large">
  Primary
</button>
<button type="button" class="button primary large">
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
  <span>Primary</span>
</button>
html
<button type="button" class="button default small">
  Default
</button>
<button type="button" class="button default small">
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
  <span>Default</span>
</button>
<button type="button" class="button primary small">
  Primary
</button>
<button type="button" class="button primary small">
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
  <span>Primary</span>
</button>

Custom sizing

Beyond the predefined sizes, Chassis's token-based architecture enables precise sizing control through CSS variables:

html
<button type="button" class="button primary"
  style="--cx-button-padding-y: .75rem; --cx-button-padding-x: 1.5rem; --cx-button-font-size: .75rem;">
  Custom-sized button
</button>

Disabled state

Chassis CSS handles button disabling in a semantically appropriate way. For native button elements, use the disabled attribute:

html
<button type="button" class="button default" disabled>
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
  <span>Default Button</span>
</button>
<button type="button" class="button default outline" disabled>
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
  <span>Default button</span>
</button>
<button type="button" class="button default smooth" disabled>
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
  <span>Default button</span>
</button>
<button type="button" class="button primary" disabled>
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
  <span>Primary Button</span>
</button>
<button type="button" class="button primary outline" disabled>
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
  <span>Primary Button</span>
</button>
<button type="button" class="button primary smooth" disabled>
  <svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
  <span>Primary Button</span>
</button>

For link-based buttons using the <a> element, Chassis provides a different approach:

html
<a class="button default disabled" role="button" aria-disabled="true">Default Link</a>
<a class="button primary disabled" role="button" aria-disabled="true">Primary Link</a>
<a class="button secondary disabled" role="button" aria-disabled="true">Secondary Link</a>

When implementing disabled link buttons, follow these guidelines:

  1. Add the .disabled class to apply the visual disabled state
  2. Include aria-disabled="true" to communicate the disabled state to assistive technologies
  3. Omit the href attribute when possible to prevent navigation

For cases where the href must be retained:

html
<a href="#" class="button default disabled" tabindex="-1" role="button" aria-disabled="true">Default Link</a>
<a href="#" class="button primary disabled" tabindex="-1" role="button" aria-disabled="true">Primary Link</a>
<a href="#" class="button secondary disabled" tabindex="-1" role="button" aria-disabled="true">Secondary Link</a>

In these instances, the .disabled class applies pointer-events: none which disables mouse interaction in modern browsers. However, since keyboard navigation remains possible, add tabindex="-1" to prevent keyboard focus and implement JavaScript to fully disable the functionality.

Layout patterns

Chassis CSS leverages its utility system for flexible button layouts rather than providing specific button-container classes. This approach provides greater control over spacing, alignment, and responsive behavior.

Full-width buttons

Create responsive stacks of full-width buttons using Chassis's grid utilities:

html
<div class="d-grid gap-xsmall">
  <button class="button default" type="button">Default</button>
  <button class="button primary" type="button">Primary</button>
</div>

Responsive buttons

Transform button layouts at different breakpoints using Chassis's responsive utilities:

html
<div class="d-grid gap-xsmall medium:d-block">
  <button class="button default" type="button">Default</button>
  <button class="button primary" type="button">Primary</button>
</div>

Width control

Apply grid column utilities to control button width precisely:

html
<div class="d-grid gap-xsmall col-6 mx-auto">
  <button class="button default" type="button">Default</button>
  <button class="button primary" type="button">Primary</button>
</div>

Alignment control

Use flex utilities to control button alignment within groups:

html
<div class="d-grid gap-xsmall medium:d-flex medium:justify-content-end">
  <button class="button default" type="button">Default</button>
  <button class="button primary" type="button">Primary</button>
</div>

Text handling

By default, button text will wrap to accommodate its container. To prevent text wrapping, add the .text-nowrap utility class. For global control in your Sass build, configure the $button-white-space: nowrap variable.

html
<div style="max-width: 200px;">
  <p><button type="button" class="button primary">Button with a longer text that will wrap</button></p>
  <p><button type="button" class="button primary text-nowrap">While no-wrap text will extend beyond boundaries</button><p>
</div>

Toggle functionality

Chassis includes a toggle button plugin for implementing stateful buttons. These differ from checkbox toggles in how they're communicated to assistive technologies (announced as "button"/"button pressed" rather than "checked"/"not checked").

Toggle states

Add data-cx-toggle="button" to enable toggle functionality. For pre-toggled buttons, add both the .active class and aria-pressed="true" attribute:

html
<p class="d-inline-flex gap-xsmall">
  <button type="button" class="button default" data-cx-toggle="button" aria-pressed="false">Toggle button</button>
  <button type="button" class="button default active" data-cx-toggle="button" aria-pressed="true">Active toggle</button>
  <button type="button" class="button default" disabled data-cx-toggle="button" aria-pressed="false">Disabled toggle</button>
  <button type="button" class="button default active" disabled data-cx-toggle="button" aria-pressed="true">Disabled active</button>
</p>
<p class="d-inline-flex gap-xsmall">
  <button type="button" class="button primary" data-cx-toggle="button" aria-pressed="false">Toggle button</button>
  <button type="button" class="button primary active" data-cx-toggle="button" aria-pressed="true">Active toggle</button>
  <button type="button" class="button primary" disabled data-cx-toggle="button" aria-pressed="false">Disabled toggle</button>
  <button type="button" class="button primary active" disabled data-cx-toggle="button" aria-pressed="true">Disabled active</button>
</p>

Toggle functionality is also available for link buttons:

html
<p class="d-inline-flex gap-xsmall">
  <a href="#" class="button default" role="button" data-cx-toggle="button" aria-pressed="false">Toggle link</a>
  <a href="#" class="button default active" role="button" data-cx-toggle="button" aria-pressed="true">Active toggle</a>
  <a href="#" class="button default disabled" aria-disabled="true" role="button" data-cx-toggle="button" aria-pressed="false">Disabled toggle</a>
  <a href="#" class="button default active disabled" aria-disabled="true" role="button" data-cx-toggle="button" aria-pressed="true">Disabled active</a>
</p>
<p class="d-inline-flex gap-xsmall">
  <a href="#" class="button primary" role="button" data-cx-toggle="button" aria-pressed="false">Toggle link</a>
  <a href="#" class="button primary active" role="button" data-cx-toggle="button" aria-pressed="true">Active toggle</a>
  <a href="#" class="button primary disabled" aria-disabled="true" role="button" data-cx-toggle="button" aria-pressed="false">Disabled toggle</a>
  <a href="#" class="button primary active disabled" aria-disabled="true" role="button" data-cx-toggle="button" aria-pressed="true">Disabled active</a>
</p>

JavaScript API

The Button component provides a JavaScript API for programmatic control:

const cxButton = new chassis.Button('#myButton')
MethodDescription
disposeCleans up a button instance and removes associated DOM data
getInstanceStatic method that retrieves the button instance associated with a DOM element: chassis.Button.getInstance(element)
getOrCreateInstanceStatic method that returns an existing button instance or creates one if none exists: chassis.Button.getOrCreateInstance(element)
toggleToggles the button's active state

Example of toggling all buttons programmatically:

document.querySelectorAll('.button').forEach(buttonElement => {
  const button = chassis.Button.getOrCreateInstance(buttonElement)
  button.toggle()
})

CSS

This component can be customized using CSS variables, allowing for styles to be modified dynamically on the page. These CSS variables are part of Chassis CSS's design token system, giving design teams control over component appearance. See the design tokens page for more details.

Custom properties

These CSS variables control the component's appearance and can be modified dynamically on the page. Components use cascading variables, allowing seamless variations in size, color, and style without redundant style declarations through component inheritance and the context class system.


Common variables:

--#{$prefix}border-width: var(--#{$prefix}button-border-width, #{$button-border-width});
--#{$prefix}box-shadow: var(--#{$prefix}button-box-shadow, #{$button-box-shadow});
--#{$prefix}focus-box-shadow: var(--#{$prefix}button-focus-box-shadow, #{$button-focus-box-shadow});
--#{$prefix}transition: var(--#{$prefix}button-transition, $button-transition);

Sizing:

--#{$prefix}min-size: var(--#{$prefix}button-min-size, #{$button-medium-min-size});
--#{$prefix}padding-y: var(--#{$prefix}button-padding-y, #{$button-medium-padding-y});
--#{$prefix}padding-x: var(--#{$prefix}button-padding-x, #{$button-medium-padding-x + $button-medium-nudge});
--#{$prefix}gap: var(--#{$prefix}button-gap, #{$button-medium-gap});
--#{$prefix}nudge: var(--#{$prefix}button-nudge, #{$button-medium-nudge});
--#{$prefix}border-radius: var(--#{$prefix}button-border-radius, #{$button-medium-border-radius});
--#{$prefix}icon-size: var(--#{$prefix}button-icon-size, #{$button-medium-icon-size});
@include map-font($button-medium-font, button);
--#{$prefix}dropdown-caret-size: var(--#{$prefix}button-dropdown-caret-size, #{$button-medium-caret-size});

Idle (default) state:

--#{$prefix}fg-color: var(--#{$prefix}button-idle-fg-color, var(--#{$prefix}fg-idle));
--#{$prefix}bg-color: var(--#{$prefix}button-idle-bg-color, var(--#{$prefix}bg-idle));
--#{$prefix}icon-color: var(--#{$prefix}button-idle-icon-color, var(--#{$prefix}fg-idle));
--#{$prefix}border-color: var(--#{$prefix}button-idle-border-color, var(--#{$prefix}border-idle));

Hover state:

--#{$prefix}fg-color: var(--#{$prefix}button-hover-fg-color, var(--#{$prefix}fg-hover));
--#{$prefix}bg-color: var(--#{$prefix}button-hover-bg-color, var(--#{$prefix}bg-hover));
--#{$prefix}icon-color: var(--#{$prefix}button-hover-icon-color, var(--#{$prefix}fg-hover));
--#{$prefix}border-color: var(--#{$prefix}button-hover-border-color, var(--#{$prefix}border-hover));

Press (active) state:

--#{$prefix}fg-color: var(--#{$prefix}button-press-fg-color, var(--#{$prefix}fg-press));
--#{$prefix}bg-color: var(--#{$prefix}button-press-bg-color, var(--#{$prefix}bg-press));
--#{$prefix}icon-color: var(--#{$prefix}button-press-icon-color, var(--#{$prefix}fg-press));
--#{$prefix}border-color: var(--#{$prefix}button-press-border-color, var(--#{$prefix}border-press));

Focus state:

--#{$prefix}fg-color: var(--#{$prefix}button-disabled-fg-color, var(--#{$prefix}fg-disabled));
--#{$prefix}bg-color: var(--#{$prefix}button-disabled-bg-color, var(--#{$prefix}bg-disabled));
--#{$prefix}icon-color: var(--#{$prefix}button-disabled-icon-color, var(--#{$prefix}fg-disabled));
--#{$prefix}border-color: var(--#{$prefix}button-disabled-border-color, var(--#{$prefix}border-disabled));

Sass variables

These Sass variables control the component's appearance and can be modified in the project's variables file before compilation.

$button-transition:                   color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
$button-white-space:                  null; // Set to `nowrap` to prevent text wrapping
$button-box-shadow:                   inset 0 $utility-pixel-1 0 #{to-opacity($white, .15)}, 0 $utility-pixel-1 $utility-pixel-1 #{to-opacity($black, .075)};
$button-focus-width:                  $focus-ring-width;
$button-focus-box-shadow:             $focus-ring-box-shadow;
$button-disabled-opacity:             1;
$button-press-box-shadow:             inset 0 (2 * $utility-pixel-1) (4 * $utility-pixel-1) #{to-opacity($black, .125)};
$button-link-color:                   var(--#{$prefix}link-main);
$button-hover-color:                  var(--#{$prefix}link-hover);

Sass mixins

Chassis CSS automatically applies these specialized mixins to each semantic context color to generate the complete suite of button variants while maintaining design token consistency:


Solid button mixin:

/// Set all state-specific CSS custom properties for a solid (filled) button variant.
/// Reads from `$button-colors` map for fallback values, with per-color CSS variable overrides.
///
/// @param {String} $color - Button color name (e.g., "primary", "danger") matching a key prefix in `$button-colors`
@mixin solid-button($color) {
  // Idle
  --#{$prefix}fg-idle: var(--#{$prefix}button-#{$color}-fg-idle, #{map-get($button-colors, #{#{$color}-fg-idle})});
  --#{$prefix}bg-idle: var(--#{$prefix}button-#{$color}-bg-idle, #{map-get($button-colors, #{#{$color}-bg-idle})});
  --#{$prefix}border-idle: var(--#{$prefix}button-#{$color}-border-idle, #{map-get($button-colors, #{#{$color}-border-idle})});
  // Hover
  --#{$prefix}fg-hover: var(--#{$prefix}button-#{$color}-fg-hover, #{map-get($button-colors, #{#{$color}-fg-hover})});
  --#{$prefix}bg-hover: var(--#{$prefix}button-#{$color}-bg-hover, #{map-get($button-colors, #{#{$color}-bg-hover})});
  --#{$prefix}border-hover: var(--#{$prefix}button-#{$color}-border-hover, #{map-get($button-colors, #{#{$color}-border-hover})});
  // Press
  --#{$prefix}fg-press: var(--#{$prefix}button-#{$color}-fg-press, #{map-get($button-colors, #{#{$color}-fg-press})});
  --#{$prefix}bg-press: var(--#{$prefix}button-#{$color}-bg-press, #{map-get($button-colors, #{#{$color}-bg-press})});
  --#{$prefix}border-press: var(--#{$prefix}button-#{$color}-border-press, #{map-get($button-colors, #{#{$color}-border-press})});
  // Disabled
  --#{$prefix}fg-disabled: var(--#{$prefix}button-#{$color}-fg-disabled, #{map-get($button-colors, #{#{$color}-fg-disabled})});
  --#{$prefix}bg-disabled: var(--#{$prefix}button-#{$color}-bg-disabled, #{map-get($button-colors, #{#{$color}-bg-disabled})});
  --#{$prefix}border-disabled: var(--#{$prefix}button-#{$color}-border-disabled, #{map-get($button-colors, #{#{$color}-border-disabled})});
}

Outline button mixin;

/// Set all state-specific CSS custom properties for an outline button variant.
/// Idle state uses the base context color for foreground and border; hover inverts to solid fill.
/// Reads from `$button-colors` map for press/disabled states.
///
/// @param {String} $color - Button color name (e.g., "primary", "danger")
@mixin outline-button($color) {
  // Idle
  --#{$prefix}fg-idle: var(--#{$prefix}button-outline-#{$color}-fg-idle, var(--#{$prefix}#{$color}-base-color));
  --#{$prefix}bg-idle: var(--#{$prefix}button-outline-#{$color}-bg-idle, transparent);
  --#{$prefix}border-idle: var(--#{$prefix}button-outline-#{$color}-border-idle, var(--#{$prefix}#{$color}-base-color));
  // Hover
  --#{$prefix}fg-hover: var(--#{$prefix}button-outline-#{$color}-fg-hover, var(--#{$prefix}#{$color}-contrast-color));
  --#{$prefix}bg-hover: var(--#{$prefix}button-outline-#{$color}-bg-hover, var(--#{$prefix}#{$color}-base-color));
  --#{$prefix}border-hover: var(--#{$prefix}button-outline-#{$color}-border-hover, transparent);
  // Press
  --#{$prefix}fg-press: var(--#{$prefix}button-outline-#{$color}-fg-press, #{map-get($button-colors, #{#{$color}-fg-press})});
  --#{$prefix}bg-press: var(--#{$prefix}button-outline-#{$color}-bg-press, #{map-get($button-colors, #{#{$color}-bg-press})});
  --#{$prefix}border-press: var(--#{$prefix}button-outline-#{$color}-border-press, transparent);
  // Disabled
  --#{$prefix}fg-disabled: var(--#{$prefix}button-outline-#{$color}-bg-disabled, #{map-get($button-colors, #{#{$color}-bg-disabled})});
  --#{$prefix}bg-disabled: var(--#{$prefix}button-outline-#{$color}-bg-disabled, transparent);
  --#{$prefix}border-disabled: var(--#{$prefix}button-outline-#{$color}-bg-disabled, #{map-get($button-colors, #{#{$color}-bg-disabled})});
  // Custom border width
  --#{$prefix}border-width: var(--#{$prefix}border-width-large);
}

Smooth button mixin:

/// Set all state-specific CSS custom properties for a smooth (subtle/tonal) button variant.
/// Uses light background tones derived from the context palette with transparent borders.
///
/// @param {String} $color - Button color name (e.g., "primary", "danger")
@mixin smooth-button($color) {
  // Idle
  --#{$prefix}fg-idle: var(--#{$prefix}button-subtle-#{$color}-fg-idle, var(--#{#{$prefix}#{$color}-fg-main}));
  --#{$prefix}bg-idle: var(--#{$prefix}button-subtle-#{$color}-bg-idle, var(--#{#{$prefix}#{$color}-bg-even}));
  --#{$prefix}border-idle: var(--#{$prefix}button-subtle-#{$color}-border-idle, transparent);
  // Hover
  --#{$prefix}fg-hover: var(--#{$prefix}button-subtle-#{$color}-fg-hover, var(--#{#{$prefix}#{$color}-fg-main}));
  --#{$prefix}bg-hover: var(--#{$prefix}button-subtle-#{$color}-bg-hover, var(--#{#{$prefix}#{$color}-bg-main}));
  --#{$prefix}border-hover: var(--#{$prefix}button-subtle-#{$color}-border-hover, transparent);
  // Press
  --#{$prefix}fg-press: var(--#{$prefix}button-subtle-#{$color}-fg-press, var(--#{#{$prefix}#{$color}-fg-main}));
  --#{$prefix}bg-press: var(--#{$prefix}button-subtle-#{$color}-bg-press, var(--#{#{$prefix}#{$color}-bg-evident}));
  --#{$prefix}border-press: var(--#{$prefix}button-subtle-#{$color}-border-press, transparent);
  // Disabled
  --#{$prefix}fg-disabled: var(--#{$prefix}button-subtle-#{$color}-fg-disabled, var(--#{#{$prefix}#{$color}-fg-slight}));
  --#{$prefix}bg-disabled: var(--#{$prefix}button-subtle-#{$color}-bg-disabled, var(--#{#{$prefix}#{$color}-bg-main}));
  --#{$prefix}border-disabled: var(--#{$prefix}button-subtle-#{$color}-border-disabled, transparent);
}

Sass maps

Color map that drives the generation of all button variants through button mixins.

$button-colors: (
  // Default
  "default-fg-idle":              $button-default-fg-idle,
  "default-fg-hover":             $button-default-fg-hover,
  "default-fg-press":             $button-default-fg-press,
  "default-fg-disabled":          $button-default-fg-disabled,
  "default-bg-idle":              $button-default-bg-idle,
  "default-bg-hover":             $button-default-bg-hover,
  "default-bg-press":             $button-default-bg-press,
  "default-bg-disabled":          $button-default-bg-disabled,
  "default-border-idle":          $button-default-border-idle,
  "default-border-hover":         $button-default-border-hover,
  "default-border-press":         $button-default-border-press,
  "default-border-disabled":      $button-default-border-disabled,
  // Alternate
  "alternate-fg-idle":            $button-alternate-fg-idle,
  "alternate-fg-hover":           $button-alternate-fg-hover,
  "alternate-fg-press":           $button-alternate-fg-press,
  "alternate-fg-disabled":        $button-alternate-fg-disabled,
  "alternate-bg-idle":            $button-alternate-bg-idle,
  "alternate-bg-hover":           $button-alternate-bg-hover,
  "alternate-bg-press":           $button-alternate-bg-press,
  "alternate-bg-disabled":        $button-alternate-bg-disabled,
  "alternate-border-idle":        $button-alternate-border-idle,
  "alternate-border-hover":       $button-alternate-border-hover,
  "alternate-border-press":       $button-alternate-border-press,
  "alternate-border-disabled":    $button-alternate-border-disabled,
  // Primary
  "primary-fg-idle":              $button-primary-fg-idle,
  "primary-fg-hover":             $button-primary-fg-hover,
  "primary-fg-press":             $button-primary-fg-press,
  "primary-fg-disabled":          $button-primary-fg-disabled,
  "primary-bg-idle":              $button-primary-bg-idle,
  "primary-bg-hover":             $button-primary-bg-hover,
  "primary-bg-press":             $button-primary-bg-press,
  "primary-bg-disabled":          $button-primary-bg-disabled,
  "primary-border-idle":          $button-primary-border-idle,
  "primary-border-hover":         $button-primary-border-hover,
  "primary-border-press":         $button-primary-border-press,
  "primary-border-disabled":      $button-primary-border-disabled,
  // Secondary
  "secondary-fg-idle":            $button-secondary-fg-idle,
  "secondary-fg-hover":           $button-secondary-fg-hover,
  "secondary-fg-press":           $button-secondary-fg-press,
  "secondary-fg-disabled":        $button-secondary-fg-disabled,
  "secondary-bg-idle":            $button-secondary-bg-idle,
  "secondary-bg-hover":           $button-secondary-bg-hover,
  "secondary-bg-press":           $button-secondary-bg-press,
  "secondary-bg-disabled":        $button-secondary-bg-disabled,
  "secondary-border-idle":        $button-secondary-border-idle,
  "secondary-border-hover":       $button-secondary-border-hover,
  "secondary-border-press":       $button-secondary-border-press,
  "secondary-border-disabled":    $button-secondary-border-disabled,
  // Neutral
  "neutral-fg-idle":              $button-neutral-fg-idle,
  "neutral-fg-hover":             $button-neutral-fg-hover,
  "neutral-fg-press":             $button-neutral-fg-press,
  "neutral-fg-disabled":          $button-neutral-fg-disabled,
  "neutral-bg-idle":              $button-neutral-bg-idle,
  "neutral-bg-hover":             $button-neutral-bg-hover,
  "neutral-bg-press":             $button-neutral-bg-press,
  "neutral-bg-disabled":          $button-neutral-bg-disabled,
  "neutral-border-idle":          $button-neutral-border-idle,
  "neutral-border-hover":         $button-neutral-border-hover,
  "neutral-border-press":         $button-neutral-border-press,
  "neutral-border-disabled":      $button-neutral-border-disabled,
  // Danger
  "danger-fg-idle":               $button-danger-fg-idle,
  "danger-fg-hover":              $button-danger-fg-hover,
  "danger-fg-press":              $button-danger-fg-press,
  "danger-fg-disabled":           $button-danger-fg-disabled,
  "danger-bg-idle":               $button-danger-bg-idle,
  "danger-bg-hover":              $button-danger-bg-hover,
  "danger-bg-press":              $button-danger-bg-press,
  "danger-bg-disabled":           $button-danger-bg-disabled,
  "danger-border-idle":           $button-danger-border-idle,
  "danger-border-hover":          $button-danger-border-hover,
  "danger-border-press":          $button-danger-border-press,
  "danger-border-disabled":       $button-danger-border-disabled,
  // Success
  "success-fg-idle":              $button-success-fg-idle,
  "success-fg-hover":             $button-success-fg-hover,
  "success-fg-press":             $button-success-fg-press,
  "success-fg-disabled":          $button-success-fg-disabled,
  "success-bg-idle":              $button-success-bg-idle,
  "success-bg-hover":             $button-success-bg-hover,
  "success-bg-press":             $button-success-bg-press,
  "success-bg-disabled":          $button-success-bg-disabled,
  "success-border-idle":          $button-success-border-idle,
  "success-border-hover":         $button-success-border-hover,
  "success-border-press":         $button-success-border-press,
  "success-border-disabled":      $button-success-border-disabled,
  // Warning
  "warning-fg-idle":              $button-warning-fg-idle,
  "warning-fg-hover":             $button-warning-fg-hover,
  "warning-fg-press":             $button-warning-fg-press,
  "warning-fg-disabled":          $button-warning-fg-disabled,
  "warning-bg-idle":              $button-warning-bg-idle,
  "warning-bg-hover":             $button-warning-bg-hover,
  "warning-bg-press":             $button-warning-bg-press,
  "warning-bg-disabled":          $button-warning-bg-disabled,
  "warning-border-idle":          $button-warning-border-idle,
  "warning-border-hover":         $button-warning-border-hover,
  "warning-border-press":         $button-warning-border-press,
  "warning-border-disabled":      $button-warning-border-disabled,
  // Info
  "info-fg-idle":                 $button-info-fg-idle,
  "info-fg-hover":                $button-info-fg-hover,
  "info-fg-press":                $button-info-fg-press,
  "info-fg-disabled":             $button-info-fg-disabled,
  "info-bg-idle":                 $button-info-bg-idle,
  "info-bg-hover":                $button-info-bg-hover,
  "info-bg-press":                $button-info-bg-press,
  "info-bg-disabled":             $button-info-bg-disabled,
  "info-border-idle":             $button-info-border-idle,
  "info-border-hover":            $button-info-border-hover,
  "info-border-press":            $button-info-border-press,
  "info-border-disabled":         $button-info-border-disabled,
  // Black
  "black-fg-idle":                $button-black-fg-idle,
  "black-fg-hover":               $button-black-fg-hover,
  "black-fg-press":               $button-black-fg-press,
  "black-fg-disabled":            $button-black-fg-disabled,
  "black-bg-idle":                $button-black-bg-idle,
  "black-bg-hover":               $button-black-bg-hover,
  "black-bg-press":               $button-black-bg-press,
  "black-bg-disabled":            $button-black-bg-disabled,
  "black-border-idle":            $button-black-border-idle,
  "black-border-hover":           $button-black-border-hover,
  "black-border-press":           $button-black-border-press,
  "black-border-disabled":        $button-black-border-disabled,
  // White
  "white-fg-idle":                $button-white-fg-idle,
  "white-fg-hover":               $button-white-fg-hover,
  "white-fg-press":               $button-white-fg-press,
  "white-fg-disabled":            $button-white-fg-disabled,
  "white-bg-idle":                $button-white-bg-idle,
  "white-bg-hover":               $button-white-bg-hover,
  "white-bg-press":               $button-white-bg-press,
  "white-bg-disabled":            $button-white-bg-disabled,
  "white-border-idle":            $button-white-border-idle,
  "white-border-hover":           $button-white-border-hover,
  "white-border-press":           $button-white-border-press,
  "white-border-disabled":        $button-white-border-disabled,
);

Design tokens

These design tokens with $cx prefixes are managed by design teams in Figma using the Tokens Studio plugin. See the design tokens page for more details.

$button-medium-font:                      $cx-font-button-medium;
$button-large-font:                       $cx-font-button-large;
$button-small-font:                       $cx-font-button-small;

$button-medium-min-size:                 $cx-size-button-medium-main;
$button-medium-padding-y:                 $cx-space-button-medium-padding-y;
$button-medium-padding-x:                 $cx-space-button-medium-padding-x;
$button-medium-gap:                       $cx-space-button-medium-gap;
$button-medium-nudge:                      $cx-space-button-medium-nudge;

$button-large-min-size:                  $cx-size-button-large-main;
$button-large-padding-y:                  $cx-space-button-large-padding-y;
$button-large-padding-x:                  $cx-space-button-large-padding-x;
$button-large-gap:                        $cx-space-button-large-gap;
$button-large-nudge:                       $cx-space-button-large-nudge;

$button-small-min-size:                  $cx-size-button-small-main;
$button-small-padding-y:                  $cx-space-button-small-padding-y;
$button-small-padding-x:                  $cx-space-button-small-padding-x;
$button-small-gap:                        $cx-space-button-small-gap;
$button-small-nudge:                       $cx-space-button-small-nudge;

$button-medium-icon-size:                 $cx-size-button-medium-icon;
$button-large-icon-size:                  $cx-size-button-large-icon;
$button-small-icon-size:                  $cx-size-button-small-icon;

$button-caret-icon:                       svg-icon($cx-icon-button-caret);
$button-medium-caret-size:                $cx-size-button-medium-caret;
$button-large-caret-size:                 $cx-size-button-large-caret;
$button-small-caret-size:                 $cx-size-button-small-caret;

$button-border-width:                     $cx-border-width-button-main;
$button-medium-border-radius:             $cx-border-radius-button-medium;
$button-large-border-radius:              $cx-border-radius-button-medium;
$button-small-border-radius:              $cx-border-radius-button-small;
$button-default-fg-idle:                  $cx-color-button-default-fg-idle;
$button-default-fg-hover:                 $cx-color-button-default-fg-hover;
$button-default-fg-press:                 $cx-color-button-default-fg-press;
$button-default-fg-disabled:              $cx-color-button-default-fg-disabled;
$button-default-bg-idle:                  $cx-color-button-default-bg-idle;
$button-default-bg-hover:                 $cx-color-button-default-bg-hover;
$button-default-bg-press:                 $cx-color-button-default-bg-press;
$button-default-bg-disabled:              $cx-color-button-default-bg-disabled;
$button-default-border-idle:              $cx-color-button-default-border-idle;
$button-default-border-hover:             $cx-color-button-default-border-hover;
$button-default-border-press:             $cx-color-button-default-border-press;
$button-default-border-disabled:          $cx-color-button-default-border-disabled;

$button-alternate-fg-idle:                $cx-color-button-alternate-fg-idle;
$button-alternate-fg-hover:               $cx-color-button-alternate-fg-hover;
$button-alternate-fg-press:               $cx-color-button-alternate-fg-press;
$button-alternate-fg-disabled:            $cx-color-button-alternate-fg-disabled;
$button-alternate-bg-idle:                $cx-color-button-alternate-bg-idle;
$button-alternate-bg-hover:               $cx-color-button-alternate-bg-hover;
$button-alternate-bg-press:               $cx-color-button-alternate-bg-press;
$button-alternate-bg-disabled:            $cx-color-button-alternate-bg-disabled;
$button-alternate-border-idle:            $cx-color-button-alternate-border-idle;
$button-alternate-border-hover:           $cx-color-button-alternate-border-hover;
$button-alternate-border-press:           $cx-color-button-alternate-border-press;
$button-alternate-border-disabled:        $cx-color-button-alternate-border-disabled;

$button-primary-fg-idle:                  $cx-color-button-primary-fg-idle;
$button-primary-fg-hover:                 $cx-color-button-primary-fg-hover;
$button-primary-fg-press:                 $cx-color-button-primary-fg-press;
$button-primary-fg-disabled:              $cx-color-button-primary-fg-disabled;
$button-primary-bg-idle:                  $cx-color-button-primary-bg-idle;
$button-primary-bg-hover:                 $cx-color-button-primary-bg-hover;
$button-primary-bg-press:                 $cx-color-button-primary-bg-press;
$button-primary-bg-disabled:              $cx-color-button-primary-bg-disabled;
$button-primary-border-idle:              $cx-color-button-primary-border-idle;
$button-primary-border-hover:             $cx-color-button-primary-border-hover;
$button-primary-border-press:             $cx-color-button-primary-border-press;
$button-primary-border-disabled:          $cx-color-button-primary-border-disabled;

$button-secondary-fg-idle:                $cx-color-button-secondary-fg-idle;
$button-secondary-fg-hover:               $cx-color-button-secondary-fg-hover;
$button-secondary-fg-press:               $cx-color-button-secondary-fg-press;
$button-secondary-fg-disabled:            $cx-color-button-secondary-fg-disabled;
$button-secondary-bg-idle:                $cx-color-button-secondary-bg-idle;
$button-secondary-bg-hover:               $cx-color-button-secondary-bg-hover;
$button-secondary-bg-press:               $cx-color-button-secondary-bg-press;
$button-secondary-bg-disabled:            $cx-color-button-secondary-bg-disabled;
$button-secondary-border-idle:            $cx-color-button-secondary-border-idle;
$button-secondary-border-hover:           $cx-color-button-secondary-border-hover;
$button-secondary-border-press:           $cx-color-button-secondary-border-press;
$button-secondary-border-disabled:        $cx-color-button-secondary-border-disabled;

$button-neutral-fg-idle:                  $cx-color-button-neutral-fg-idle;
$button-neutral-fg-hover:                 $cx-color-button-neutral-fg-hover;
$button-neutral-fg-press:                 $cx-color-button-neutral-fg-press;
$button-neutral-fg-disabled:              $cx-color-button-neutral-fg-disabled;
$button-neutral-bg-idle:                  $cx-color-button-neutral-bg-idle;
$button-neutral-bg-hover:                 $cx-color-button-neutral-bg-hover;
$button-neutral-bg-press:                 $cx-color-button-neutral-bg-press;
$button-neutral-bg-disabled:              $cx-color-button-neutral-bg-disabled;
$button-neutral-border-idle:              $cx-color-button-neutral-border-idle;
$button-neutral-border-hover:             $cx-color-button-neutral-border-hover;
$button-neutral-border-press:             $cx-color-button-neutral-border-press;
$button-neutral-border-disabled:          $cx-color-button-neutral-border-disabled;

$button-danger-fg-idle:                   $cx-color-button-danger-fg-idle;
$button-danger-fg-hover:                  $cx-color-button-danger-fg-hover;
$button-danger-fg-press:                  $cx-color-button-danger-fg-press;
$button-danger-fg-disabled:               $cx-color-button-danger-fg-disabled;
$button-danger-bg-idle:                   $cx-color-button-danger-bg-idle;
$button-danger-bg-hover:                  $cx-color-button-danger-bg-hover;
$button-danger-bg-press:                  $cx-color-button-danger-bg-press;
$button-danger-bg-disabled:               $cx-color-button-danger-bg-disabled;
$button-danger-border-idle:               $cx-color-button-danger-border-idle;
$button-danger-border-hover:              $cx-color-button-danger-border-hover;
$button-danger-border-press:              $cx-color-button-danger-border-press;
$button-danger-border-disabled:           $cx-color-button-danger-border-disabled;

$button-success-fg-idle:                  $cx-color-button-success-fg-idle;
$button-success-fg-hover:                 $cx-color-button-success-fg-hover;
$button-success-fg-press:                 $cx-color-button-success-fg-press;
$button-success-fg-disabled:              $cx-color-button-success-fg-disabled;
$button-success-bg-idle:                  $cx-color-button-success-bg-idle;
$button-success-bg-hover:                 $cx-color-button-success-bg-hover;
$button-success-bg-press:                 $cx-color-button-success-bg-press;
$button-success-bg-disabled:              $cx-color-button-success-bg-disabled;
$button-success-border-idle:              $cx-color-button-success-border-idle;
$button-success-border-hover:             $cx-color-button-success-border-hover;
$button-success-border-press:             $cx-color-button-success-border-press;
$button-success-border-disabled:          $cx-color-button-success-border-disabled;

$button-warning-fg-idle:                  $cx-color-button-warning-fg-idle;
$button-warning-fg-hover:                 $cx-color-button-warning-fg-hover;
$button-warning-fg-press:                 $cx-color-button-warning-fg-press;
$button-warning-fg-disabled:              $cx-color-button-warning-fg-disabled;
$button-warning-bg-idle:                  $cx-color-button-warning-bg-idle;
$button-warning-bg-hover:                 $cx-color-button-warning-bg-hover;
$button-warning-bg-press:                 $cx-color-button-warning-bg-press;
$button-warning-bg-disabled:              $cx-color-button-warning-bg-disabled;
$button-warning-border-idle:              $cx-color-button-warning-border-idle;
$button-warning-border-hover:             $cx-color-button-warning-border-hover;
$button-warning-border-press:             $cx-color-button-warning-border-press;
$button-warning-border-disabled:          $cx-color-button-warning-border-disabled;

$button-info-fg-idle:                     $cx-color-button-info-fg-idle;
$button-info-fg-hover:                    $cx-color-button-info-fg-hover;
$button-info-fg-press:                    $cx-color-button-info-fg-press;
$button-info-fg-disabled:                 $cx-color-button-info-fg-disabled;
$button-info-bg-idle:                     $cx-color-button-info-bg-idle;
$button-info-bg-hover:                    $cx-color-button-info-bg-hover;
$button-info-bg-press:                    $cx-color-button-info-bg-press;
$button-info-bg-disabled:                 $cx-color-button-info-bg-disabled;
$button-info-border-idle:                 $cx-color-button-info-border-idle;
$button-info-border-hover:                $cx-color-button-info-border-hover;
$button-info-border-press:                $cx-color-button-info-border-press;
$button-info-border-disabled:             $cx-color-button-info-border-disabled;

$button-black-fg-idle:                    $cx-color-button-black-fg-idle;
$button-black-fg-hover:                   $cx-color-button-black-fg-hover;
$button-black-fg-press:                   $cx-color-button-black-fg-press;
$button-black-fg-disabled:                $cx-color-button-black-fg-disabled;
$button-black-bg-idle:                    $cx-color-button-black-bg-idle;
$button-black-bg-hover:                   $cx-color-button-black-bg-hover;
$button-black-bg-press:                   $cx-color-button-black-bg-press;
$button-black-bg-disabled:                $cx-color-button-black-bg-disabled;
$button-black-border-idle:                $cx-color-button-black-border-idle;
$button-black-border-hover:               $cx-color-button-black-border-hover;
$button-black-border-press:               $cx-color-button-black-border-press;
$button-black-border-disabled:            $cx-color-button-black-border-disabled;

$button-white-fg-idle:                    $cx-color-button-white-fg-idle;
$button-white-fg-hover:                   $cx-color-button-white-fg-hover;
$button-white-fg-press:                   $cx-color-button-white-fg-press;
$button-white-fg-disabled:                $cx-color-button-white-fg-disabled;
$button-white-bg-idle:                    $cx-color-button-white-bg-idle;
$button-white-bg-hover:                   $cx-color-button-white-bg-hover;
$button-white-bg-press:                   $cx-color-button-white-bg-press;
$button-white-bg-disabled:                $cx-color-button-white-bg-disabled;
$button-white-border-idle:                $cx-color-button-white-border-idle;
$button-white-border-hover:               $cx-color-button-white-border-hover;
$button-white-border-press:               $cx-color-button-white-border-press;
$button-white-border-disabled:            $cx-color-button-white-border-disabled;