Skip to main content

Theme config

Theme mode

Color palette

Grays

Border radii/radiuses/radiopedes/you know
Border radius
Field border radius
Button border radius
All
Components
Guides
API
Recent

    Components

    Button

    Full supportSupported since v125.Full supportSupported since v128.Full supportSupported since v18.

    Anatomy

    • .ui-button

      Container element.

    • <svg>

      An optional icon.

    • <span>

      The label.

    Variants

    Change the button variant with the .ui-outlined, .ui-tonal, and .ui-filled classes.

    Link
    Link
    Link
    Link
    <div class="example-row">
    <button class="ui-button">Text</button>
    <button class="ui-button" disabled>Disabled</button>
    <a class="ui-button" href="#">Link</a>
    </div>
    <div class="example-row">
    <button class="ui-button ui-outlined">Outlined</button>
    <button class="ui-button ui-outlined" disabled>Disabled</button>
    <a class="ui-button ui-outlined" href="#">Link</a>
    </div>
    <div class="example-row">
    <button class="ui-button ui-tonal">Tonal</button>
    <button class="ui-button ui-tonal" disabled>Disabled</button>
    <a class="ui-button ui-tonal" href="#">Link</a>
    </div>
    <div class="example-row">
    <button class="ui-button ui-filled">Filled</button>
    <button class="ui-button ui-filled" disabled>Disabled</button>
    <a class="ui-button ui-filled" href="#">Link</a>
    </div>

    Colors

    Add a .ui-primary or .ui-critical class to apply a brand or destructive color. The default is a neutral gray.

    <div class="example-row">
    <button class="ui-button ui-primary">Primary</button>
    <button class="ui-button ui-primary ui-outlined">Outlined</button>
    <button class="ui-button ui-primary ui-tonal">Tonal</button>
    <button class="ui-button ui-primary ui-filled">Filled</button>
    </div>
    <div class="example-row">
    <button class="ui-button ui-critical">Critical</button>
    <button class="ui-button ui-critical ui-outlined">Outlined</button>
    <button class="ui-button ui-critical ui-tonal">Tonal</button>
    <button class="ui-button ui-critical ui-filled">Filled</button>
    </div>

    Buttons with icon and label

    Include an icon alongside text by nesting an SVG element within the button.

    <div class="example-row">
    <button class="ui-button">
    Text
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    </button>
    <button class="ui-button ui-outlined">
    Outlined
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    </button>
    <button class="ui-button ui-tonal">
    Tonal
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    </button>
    <button class="ui-button ui-filled">
    Filled
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    </button>
    </div>
    <div class="example-row">
    <button class="ui-button">
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    Text
    </button>
    <button class="ui-button ui-outlined">
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    Outlined
    </button>
    <button class="ui-button ui-tonal">
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    Tonal
    </button>
    <button class="ui-button ui-filled">
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    Filled
    </button>
    </div>

    Keyboard

    Use the <kbd> element to provide keyboard hints within a button.

    <button class="ui-button">Search <kbd>⌘K</kbd></button>
    <button class="ui-button ui-outlined">Save <kbd>⌘S</kbd></button>
    <button class="ui-button ui-tonal">Copy <kbd>⌘C</kbd></button>
    <button class="ui-button ui-filled">Delete <kbd>⌘⌫</kbd></button>

    Icon-only

    See Icon button documentation.

    Sizes

    Resize any button with the .ui-small and .ui-largeclasses.

    <div class="example-row">
    <button class="ui-button ui-small">Small</button>
    <button class="ui-button">Default</button>
    <button class="ui-button ui-large">Large</button>
    </div>
    <div class="example-row">
    <button class="ui-button ui-filled ui-small">Small</button>
    <button class="ui-button ui-filled">Default</button>
    <button class="ui-button ui-filled ui-large">Large</button>
    </div>
    <div class="example-row">
    <button class="ui-button ui-outlined ui-small">
    Small
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    </button>
    <button class="ui-button ui-outlined">
    Default
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    </button>
    <button class="ui-button ui-outlined ui-large">
    Large
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    </button>
    </div>

    Disabled

    Add disabled styling with the disabled attribute or the .ui-disabled class.

    <div class="example-row">
    <button class="ui-button" disabled>Text</button>
    <button class="ui-button ui-outlined" disabled>Outlined</button>
    <button class="ui-button ui-tonal" disabled>Tonal</button>
    <button class="ui-button ui-filled" disabled>Filled</button>
    </div>
    <div class="example-row">
    <button class="ui-button" disabled>
    Text
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    </button>
    <button class="ui-button ui-outlined" disabled>
    Outlined
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    </button>
    <button class="ui-button ui-tonal" disabled>
    Tonal
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    </button>
    <button class="ui-button ui-filled" disabled>
    Filled
    <svg
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    viewBox="0 0 24 24"
    >
    <path
    fill="currentColor"
    d="M11.75 3a.75.75 0 0 1 .743.648l.007.102l.001 7.25h7.253a.75.75 0 0 1 .102 1.493l-.102.007h-7.253l.002 7.25a.75.75 0 0 1-1.493.101l-.007-.102l-.002-7.249H3.752a.75.75 0 0 1-.102-1.493L3.752 11h7.25L11 3.75a.75.75 0 0 1 .75-.75"
    ></path>
    </svg>
    </button>
    </div>

    File upload

    Is it a button? Is it an input? You can find the docs for it here at least.

    API

    Button API

    TypeModifiersDefaultDescription
    Colors.ui-critical, .ui-primary-Optional colors.
    Sizes.ui-large, .ui-small, .ui-x-small-The size of the element.
    State[disabled]-Disables the button.
    Variants.ui-filled, .ui-outlined, .ui-tonal-The variant to use.

    Parts

    PartDescription
    .ui-buttonContainer element.
    <svg>An optional icon.
    <span>The label.

    Browser support

    Full supportSupported since v125.Full supportSupported since v128.Full supportSupported since v18.

    See also the full browser support guide.

    Installation

    @layer components.root {
    :where(.ui-button) {
    --_motion: var(--motion, 1);
    --_color: light-dark(var(--color-16), var(--color-1));
    --_color-contrast: light-dark(var(--color-1), var(--color-16));
    --_color-tonal: var(--surface-tonal);
    --_accent: var(--_color);
    --_accent-contrast: var(--_color-contrast);
    --_accent-tonal: var(--_color-tonal);
    --_accent-tonal-contrast: var(--_color);
    --_default-hover-bg-color: light-dark(
    oklch(from var(--_accent) l 0.01 h / 10%),
    oklch(from var(--_accent) l 0.01 h / 20%)
    );
    --_default-active-bg-color: light-dark(
    oklch(from var(--_accent) l 0.06 h / 20%),
    oklch(from var(--_accent) l 0.06 h / 30%)
    );
    --_filled-hover-bg-color: light-dark(
    oklch(from var(--_accent) calc(l + 0.2) c h),
    oklch(from var(--_accent) calc(l - 0.1) c h)
    );
    --_filled-active-bg-color: light-dark(
    oklch(from var(--_accent) calc(l + 0.3) c h),
    oklch(from var(--_accent) calc(l - 0.15) c h)
    );
    --_outlined-active-bg-color: var(--_filled-active-bg-color);
    --_bg-color: transparent;
    --_border-color: transparent;
    --_border-width: var(--border-size-1);
    --_font-size: var(--font-size-1);
    --_min-height: var(--button-size);
    --_border-radius: var(--button-border-radius, var(--radius-2));
    --_text-color: var(--_accent);
    -webkit-tap-highlight-color: transparent;
    -webkit-touch-callout: none;
    align-items: center;
    background-color: var(--_bg-color);
    border: var(--_border-width) solid var(--_border-color);
    border-radius: var(--_border-radius);
    color: var(--_text-color);
    display: inline-flex;
    font-size: var(--_font-size);
    font-weight: 700;
    gap: var(--size-2);
    justify-content: center;
    min-block-size: var(--_min-height);
    padding-block: 0.5ex;
    padding-inline: 1.5ex;
    text-align: center;
    text-decoration: none;
    transition:
    background-color calc(0.1s * var(--_motion)) ease,
    color calc(0.1s * var(--_motion)) ease,
    border-color calc(0.1s * var(--_motion)) ease,
    box-shadow calc(0.1s * var(--_motion)) ease;
    user-select: none;
    &.ui-critical,
    &.ui-primary {
    --_color-contrast: var(--gray-1);
    --_color-tonal: var(--color-6);
    --_accent-tonal-contrast: var(--text-primary-contrast);
    --_default-hover-bg-color: oklch(from var(--_accent) l c h / 15%);
    --_default-active-bg-color: oklch(from var(--_accent) l c h / 25%);
    --_filled-hover-bg-color: oklch(from var(--_accent) calc(l - 0.1) c h);
    --_filled-active-bg-color: oklch(from var(--_accent) calc(l - 0.15) c h);
    --_outlined-active-bg-color: oklch(from var(--_accent) calc(l - 0.1) c h);
    }
    &.ui-critical {
    --_color: var(--critical);
    }
    &.ui-primary {
    --_color: var(--primary);
    }
    /* Disabled */
    &:where([disabled]) {
    --_text-color: color-mix(
    in oklch,
    var(--text-muted) 50%,
    var(--surface-default)
    );
    cursor: not-allowed;
    opacity: 0.64;
    }
    /* Hover & Active */
    &:where(:not([disabled])) {
    &:where(:not(:active):hover) {
    --_bg-color: var(--_default-hover-bg-color);
    }
    &:where(:hover:active),
    &[aria-current="page"] {
    --_bg-color: var(--_default-active-bg-color);
    }
    }
    /* Icons / Keyboard */
    &:where(:has(svg), &.ui-icon-only) {
    gap: 1ex;
    svg {
    color: currentColor;
    max-block-size: 0.7lh;
    }
    }
    /* Keyboard input */
    :is(kbd) {
    background-color: oklch(from currentColor l c h / 10%);
    border: 0;
    color: oklch(from currentColor l c h / 80%);
    font-size: 0.8em;
    font-weight: 400;
    line-height: 1.2;
    }
    /* Sizes */
    &.ui-x-small {
    --_min-height: var(--button-size-x-small);
    --_font-size: var(--font-size-0);
    padding-block: 0;
    padding-inline: 0.5ex;
    }
    &.ui-small {
    --_min-height: var(--button-size-small);
    --_font-size: var(--font-size-05);
    padding-block: 0;
    padding-inline: 0.75ex;
    }
    &.ui-large {
    --_min-height: var(--button-size-large);
    padding-inline: 4ex;
    }
    /* Variants */
    &.ui-outlined {
    --_bg-color: transparent;
    --_border-color: var(--_accent);
    --_text-color: var(--_accent);
    &:where(:not([disabled])) {
    &:where(:not(:active):hover) {
    --_bg-color: var(--_accent);
    --_border-color: var(--_accent);
    --_text-color: var(--_accent-contrast);
    }
    &:where(:active) {
    --_bg-color: var(--_outlined-active-bg-color);
    --_border-color: var(--_outlined-active-bg-color);
    --_text-color: var(--_accent-contrast);
    }
    }
    }
    &.ui-tonal {
    --_bg-color: var(--_accent-tonal);
    --_text-color: var(--_accent-tonal-contrast);
    &:where(:not([disabled])) {
    &:where(:not(:active):hover) {
    --_bg-color: var(--_accent);
    --_text-color: var(--_accent-contrast);
    }
    &:where(:active) {
    --_bg-color: var(--_outlined-active-bg-color);
    --_text-color: var(--_accent-contrast);
    }
    }
    }
    &.ui-filled {
    --_bg-color: var(--_accent);
    --_text-color: var(--_accent-contrast);
    &:where(:not([disabled])) {
    &:where(:not(:active):hover) {
    --_bg-color: var(--_filled-hover-bg-color);
    }
    &:where(:active) {
    --_bg-color: var(--_filled-active-bg-color);
    }
    }
    }
    }
    /* File input */
    :where(input[type="file"]) {
    align-self: flex-start;
    border: var(--border-size-1) solid var(--surface-filled);
    border-radius: var(--radius-2);
    box-shadow: var(--inner-shadow-4);
    color: var(--text-muted-contrast);
    cursor: initial;
    max-inline-size: 100%;
    padding: 0;
    }
    :where(input[type="file"])::-webkit-file-upload-button,
    :where(input[type="file"])::file-selector-button {
    cursor: pointer;
    margin-inline-end: var(--size-relative-6);
    }
    }