Primitives
Primitive

Button

Clickable button with various styles and sizes

Buttons trigger an action or event: submitting a form, opening a dialog, or confirming a choice. Use them for in-page actions, not for navigation between pages.

Preview

Installation

Usage

Examples

Variants

Use variant to change the button's visual weight and color.

VariantDescription
primaryThe default, highest-emphasis action.
primary-softA tinted primary for a lower-emphasis branded action.
neutralA solid neutral action with no brand color.
secondaryThe standard lower-emphasis action.
outlineA bordered action for secondary actions.
outline-ghostA bordered, transparent action for elevated surfaces.
ghostA borderless action for toolbars and dense UI.
linkRenders as inline text, like a link.
destructiveA destructive action such as delete.
destructive-softA tinted destructive for a lower-emphasis warning.

Sizes

Use size to set the button's height and padding.

With Icons

Use leadingIcon and trailingIcon (renamed from leftSection and rightSection) to place an icon beside the label. The button automatically tightens the padding on the icon side, since an icon is visually lighter than a text edge.

Loading

Use loading to show a spinner while an action is in flight. The label stays mounted but invisible, so the button keeps its size and nothing shifts around it.

Use the render prop to render as a Next.js Link, and set nativeButton to false.

Custom Colors

The button paints its background from three CSS variables, one per interaction state: --btn-bg (rest), --btn-bg-hover, and --btn-bg-active. Each variant sets them and the button switches between them internally, so recoloring a button one-off is just overriding the variables, with no hover: or active: prefixes needed. Override the variables instead of bg-* classes: root-level bg-* paints behind the fill layer, so it is hidden by opaque variants and blended by transparent ones, which is rarely what you want:

Any variable you don't override keeps the variant's color for that state, so set all three for a full recolor. The border color is --btn-border; note that the destructive variant sets its dark-mode border with a dark: class, so overriding it there takes both [--btn-border:...] and dark:[--btn-border:...].

The same layering applies to border style and width: the border lives on the button's paint pseudo-element, so use before: classes to restyle it, for example before:border-dashed or before:border-2.

Accessibility

Label icon-only buttons

An icon-only button has no text for a screen reader to announce. Give it an aria-label describing the action.

Loading state

The loading prop disables the button but keeps it focusable (focusableWhenDisabled), so keyboard users don't lose their place while an action is in flight.

API Reference

The Button component is built on top of Base UI's Button. All Base UI props are supported. The documentation below only covers custom props and modified defaults specific to our implementation.

For the complete Base UI API, see the Base UI Button documentation.

Props

Button

Clickable element that triggers actions. Wraps Base UI's Button.

Prop