Components

Button

Trigger actions with UiButton — variants, colors, sizes, and groups.

UiButton is the primary action trigger. Style it with variant, color it with color, and scale it with size.

Add a button

<template>
  <UiButton variant="filled" color="primary" text="Save" />
</template>

Choose a variant

<template>
  <UiButton variant="filled" text="Filled" />
  <UiButton variant="tonal" color="primary" text="Tonal" />
  <UiButton variant="outline" text="Outline" />
  <UiButton variant="text" text="Text" />
  <UiButton variant="gradient" text="Gradient" />
</template>

Apply a color

color applies to the filled and tonal variants; the others keep their own colors.

<template>
  <UiButton variant="filled" color="success" text="Success" />
  <UiButton variant="filled" color="warning" text="Warning" />
  <UiButton variant="filled" color="danger" text="Danger" />
</template>

Size, state, and width

<template>
  <UiButton variant="filled" size="sm" text="Small" />
  <UiButton variant="filled" size="lg" text="Large" />
  <UiButton variant="filled" :loading="true" text="Saving" />
  <UiButton variant="filled" :disabled="true" text="Disabled" />
  <UiButton variant="filled" fluid text="Full width" />
</template>

Add an icon

Use the #icon slot; set iconTrailing to place it after the label:

<template>
  <UiButton variant="filled" text="Download" :icon-trailing="true">
    <template #icon>
      <!-- any Material Symbols code point -->
      <UiIconMaterial icon-code="&#xf090;" />
    </template>
  </UiButton>
</template>

Pass to or href to render button styling on a link instead of a <button>. Without either, UiButton always renders its native <button> markup — as alone has no effect.

<template>
  <!-- Plain / external link (renders <a>) -->
  <UiButton variant="filled" color="primary" text="Docs" href="https://colorffy.com" />

  <!-- Internal path (also renders <a> by default) -->
  <UiButton variant="outline" text="Dashboard" to="/dashboard" />

  <!-- Router-aware component -->
  <UiButton variant="text" text="Profile" to="/profile" as="router-link" />

  <!-- Disabled link: no href, aria-disabled, click is blocked -->
  <UiButton variant="filled" text="Locked" href="/dashboard" :disabled="true" />
</template>

Link resolution mirrors IBaseLinkProps-style components (UiNavbarLink, UiBreadcrumb): a string to/href renders a plain <a> (or forces <a> when the URL looks external), an object to defers to as. disabled in link mode removes href, sets aria-disabled, adds a .disabled class, and blocks the click handler — since disabled isn't a real attribute on non-form elements.

Group buttons

<template>
  <UiButtonGroup connected>
    <UiButton variant="outline" text="Left" />
    <UiButton variant="outline" text="Middle" />
    <UiButton variant="outline" text="Right" />
  </UiButtonGroup>
</template>

Props

PropTypeDefaultDescription
textstring | null—Button label.
idstring | null—Rendered unchanged on the <button> or link.
titlestring | null—Native title attribute; also the accessible name of an icon-only button.
variant'filled' | 'tonal' | 'outline' | 'text' | 'link' | 'chip' | 'cta' | 'gradient' | 'frosted''filled'Visual style.
color'primary' | 'secondary' | 'accent' | 'neutral' | 'success' | 'warning' | 'danger' | 'info' | 'white' | 'black' | 'transparent'—Semantic color (with filled / tonal).
size'sm' | 'md' | 'lg'—Button size.
iconbooleanfalseIcon-only mode (no label required): a circle, or a square when --cffy-shape-control is 0.
iconVariant'shape-sm' | 'shape-md' | 'compact-sm' | 'compact'—Icon-button shape, used with icon.
iconTrailingbooleanfalsePlace the icon after the label.
loadingbooleanfalseShow a spinner and block interaction.
disabledbooleanfalseDisable the button.
roundedbooleanfalseFully rounded shape.
fluidbooleanfalseFull-width (btn-block).
customClassstring | string[] | Record<string, boolean> | null—Extra classes.
type'button' | 'submit' | 'reset''button'Native <button> type. Ignored in link mode.
tostring | object—Navigation target. Setting to (or href) switches to link mode.
hrefstring—External/plain href. Setting href (or to) switches to link mode.
asstring | object'a'Tag/component for link mode. Only used when to or href is set.

Emits: click (with the MouseEvent), from the <button> or, in link mode, the rendered link. A disabled or loading button never emits it. Slots: #icon. There is no default slot; the label is text.

Related: UiButtonMenu (dropdown), UiButtonToggleGroup (segmented toggles), UiButtonFabGroup (floating actions), and UiButtonTooltip.

CSS variables

These set the shape, size and type shared by every variant. Colors come from the theme tokens (--cffy-color-brand-*). The sm / lg sizes, icon buttons, FABs, rounded and the outline, tonal, text and link variants keep their own values.

:root {
  --cffy-btn-radius: var(--cffy-radius-full);
  --cffy-btn-font-weight: var(--cffy-fw-700);
  --cffy-btn-padding-inline: var(--cffy-space-16);
}
VariableDefaultControls
--cffy-btn-radius--cffy-shape-control (8px)Corners
--cffy-btn-height--cffy-control-height-md (2.25rem)Minimum height of the default size; sm and lg use --cffy-control-height-sm / -lg, which follow the density
--cffy-btn-padding-inline / --cffy-btn-padding-block--cffy-space-12 / --cffy-space-6Padding of the default size
--cffy-btn-font-size / --cffy-btn-font-weight.75rem / --cffy-fw-600Label text
--cffy-btn-icon-size1.15remIcon size of the default size
--cffy-btn-shadow--cffy-shadow-smShadow of filled and plain buttons
--cffy-btn-easing / --cffy-btn-duration--cffy-ease-decelerate / --cffy-duration-300Hover and press transitions
Copyright © 2026