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.
| Variant | Description |
|---|---|
primary | The default, highest-emphasis action. |
primary-soft | A tinted primary for a lower-emphasis branded action. |
neutral | A solid neutral action with no brand color. |
secondary | The standard lower-emphasis action. |
outline | A bordered action for secondary actions. |
outline-ghost | A bordered, transparent action for elevated surfaces. |
ghost | A borderless action for toolbars and dense UI. |
link | Renders as inline text, like a link. |
destructive | A destructive action such as delete. |
destructive-soft | A 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.
As Link
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.