Button

Versatile button component with multiple variants and sizes

Overview

The s-btn attribute provides accessible, styled buttons with automatic dark mode support and auto-contrast text colors.

Import

/* Full framework (includes all components) */
@import "@shift-css/core";

/* Or import just the button component */
@import "@shift-css/core/components/button";

Note: When importing individual components, you also need @shift-css/core/reset and @shift-css/core/tokens for the base styles and design tokens.

Variants

Button variants

<div class="demo-row">
<button s-btn="primary">Primary</button>
<button s-btn="secondary">Secondary</button>
<button s-btn="outline">Outline</button>
<button s-btn="ghost">Ghost</button>
<button s-btn="link">Link</button>
</div>

State Variants

State variants for actions

<div class="demo-row">
<button s-btn="danger">Danger</button>
<button s-btn="success">Success</button>
<button s-btn="warning">Warning</button>
</div>

Sizes

Use the s-size attribute to change button size:

Size variants

<div class="demo-row">
<button s-btn="primary" s-size="sm">Small</button>
<button s-btn="primary">Medium</button>
<button s-btn="primary" s-size="lg">Large</button>
<button s-btn="primary" s-size="xl">Extra Large</button>
</div>

States & Modifiers

Disabled State

<button s-btn="primary" disabled>Disabled</button>

Loading State

<button s-btn="primary" s-loading>Loading...</button>

Icon-Only Button

<button s-btn="primary" s-icon aria-label="Add item">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
  <path d="M12 5v14M5 12h14"></path>
</svg>
</button>

Full Width

Block-level button

<button s-btn="primary" s-block>Full Width Button</button>

Button Groups

Group related buttons together:

Grouped buttons

<div s-btn-group>
<button s-btn="secondary">Left</button>
<button s-btn="secondary">Center</button>
<button s-btn="secondary">Right</button>
</div>

With Icons

Button with icon

<button s-btn="primary">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
  <path d="M12 5v14M5 12h14"></path>
</svg>
Add Item
</button>
<a href="#" s-btn="primary">Link Button</a>

How It Works

Buttons use the Layered Intent pattern with :where() for zero-specificity base styles:

/* Base styles - easily overridable */
:where([s-btn]) {
  --_btn-bg: var(--s-interactive-primary);
  --_btn-text: var(--s-text-inverse);
  --_btn-border: transparent;

  display: inline-flex;
  align-items: center;
  background-color: var(--_btn-bg);
  color: var(--_btn-text);

  /* Auto-contrast for custom backgrounds */
  @supports (color: oklch(from red l c h)) {
    color: oklch(
      from var(--_btn-bg) clamp(0.15, calc((0.6 - l) * 1000 + 0.15), 0.95) 0 0
    );
  }
}

/* Variant styles - intentional specificity */
[s-btn="primary"] {
  --_btn-bg: var(--s-interactive-primary);
}

CSS Custom Properties

PropertyDescription
--_btn-bgBackground color (private)
--_btn-textText color (private, auto-contrast)
--_btn-borderBorder color (private)

All Attributes

AttributePurposeValues
s-btnButton variantprimary, secondary, ghost, link, outline, danger, success, warning
s-sizeButton sizesm, lg, xl
s-iconIcon-only buttonBoolean
s-blockFull-width buttonBoolean
s-loadingLoading stateBoolean
s-btn-groupButton group containerN/A

Customization Examples

Override Primary Color

Change the primary hue to affect all primary buttons:

:root {
  --shift-hue-primary: 280; /* Purple */
}

Custom Button Style

[s-btn="primary"] {
  --_bg: var(--s-accent-500);
  border-radius: var(--s-radius-full);
}
Search