Skip to main content

Variants

Buttons come in three variants: primary for main actions, secondary for alternatives, and ghost for subtle interactions.

Primary

Use for primary actions. High contrast with background fill.

"token attr-name">class="token tag"><button "token attr-name">class="btn btn-primary">
  Primary Button
"token attr-name">class="token tag"></button>

"token attr-name">class="token tag"><style>
  .btn-primary {
    background: var(--color-fg-primary);
    color: var(--color-bg-pure);
    border: none;
  }

  .btn-primary:hover {
    opacity: 0.9;
    transform: translateY(-1px);
  }

  .btn-primary:active {
    transform: translateY(0);
  }
"token attr-name">class="token tag"></style>

Secondary

Use for secondary actions. Outlined with transparent fill.

"token attr-name">class="token tag"><button "token attr-name">class="btn btn-secondary">
  Secondary Button
"token attr-name">class="token tag"></button>

"token attr-name">class="token tag"><style>
  .btn-secondary {
    background: transparent;
    color: var(--color-fg-primary);
    border: 1px solid var(--color-border-default);
  }

  .btn-secondary:hover {
    background: var(--color-hover);
    border-color: var(--color-border-emphasis);
  }

  .btn-secondary:active {
    background: var(--color-active);
  }
"token attr-name">class="token tag"></style>

Ghost

Use for tertiary actions. No border, minimal visual weight.

"token attr-name">class="token tag"><button "token attr-name">class="btn btn-ghost">
  Ghost Button
"token attr-name">class="token tag"></button>

"token attr-name">class="token tag"><style>
  .btn-ghost {
    background: transparent;
    color: var(--color-fg-secondary);
    border: none;
  }

  .btn-ghost:hover {
    background: var(--color-hover);
    color: var(--color-fg-primary);
  }

  .btn-ghost:active {
    background: var(--color-active);
  }
"token attr-name">class="token tag"></style>

Motion Tokens

All button interactions use Canon motion tokens for consistent, purposeful animation.

Hover Transition

transition: all var(--duration-micro) var(--ease-standard);

200ms transition for background, border, and color changes.

Transform on Hover

transform: translateY(-1px);

Subtle lift on primary buttons to indicate interactivity.

Active State

transform: translateY(0);

Return to baseline on click for tactile feedback.

Complete motion pattern
.btn {
  /* Base transition applies to all state changes */
  transition: all var(--duration-micro) var(--ease-standard);
}

.btn: hover {
  /* Lift effect for primary, background change for others */
  transform: translateY(-1px);
}

.btn: active {
  /* Press down effect */
  transform: translateY(0);
}

/* Respect user preferences */
@media (prefers-reduced-motion: reduce) {
  .btn {
    transition: none;
    transform: none !important;
  }
}

Token Reference

All button styles use Canon design tokens.

--duration-micro 200ms — Hover and focus transitions
--ease-standard cubic-bezier(0.4, 0.0, 0.2, 1) — Material Design easing
--color-hover rgba(255, 255, 255, 0.05) — Hover background overlay
--color-active rgba(255, 255, 255, 0.1) — Active state background
--color-border-default rgba(255, 255, 255, 0.1) — Default border color
--color-border-emphasis rgba(255, 255, 255, 0.2) — Hover border color