Skip to content

CdsButton

A button is the primary way to trigger an action: submit a form, open a modal, confirm a choice. Its variant (variant) and color (color) signal the role it plays: a filled solid button is the main action on the screen, soft, outline and ghost are the supporting ones.

Storybook GitLab Figma
Test coverage: 97% — good coverage
API in specs
37 / 38 props, events, slots and exposed members with a test
Test cases
59 unit · 2 browser
Known bugs
2 pinned by an it.fails test
Code coverage
98% lines · 97.7% branches measured in v4.0.0-alpha.13
A11y (axe)
11 recommendations in 14 stories measured in v4.0.0-alpha.11

For a link styled as text inside a paragraph, use CdsLink; to pick one option out of several, use CdsButtonToggle.

Anatomy ​

A button consists of a container and three content areas. Icons come from the prepend-icon / append-icon props or from the slots of the same name; while loading is on, the content is replaced by the indicator from the loader slot.

Variations ​

Variant ​

The variant prop sets how the button is drawn. The default is solid.

VariantLooks likeWhen
solidfilled with the colorthe main action on the screen
softa translucent tint of the colora supporting action
outlinea border, transparent backgrounda supporting action on a busy background
surfacea border on a surface backdropan action over an image or a chart
ghostneither background nor borderan action inside a panel, table or toast

Color ​

The color prop sets the color in any variant. The default is brand. It accepts:

  • a role: brand — the brand color, accent — the accent button (the same as brand in the design system, a theme can repaint it), neutral — a neutral button, danger — an irreversible action, inverse — for dark backgrounds;
  • a palette alias: red, green, cyan, … black, white;
  • a theme token name: status-success-surface, other-lime-fill;
  • any CSS color: #7c3aed, oklch(…).

The state film builds hover, press and disabled for any color, so no per-color tokens are needed.

The deprecated appearance prop ​

appearance still works and resolves into a variant + color pair, logging [CDS UPGRADE] to the development console once per value. Explicit variant and color take precedence over appearance.

appearancevariantcolor
primarysolidbrand
secondarysoftbrand
tertiarysoftneutral
inversesolidinverse
transparentghostbrand

Sizes ​

The size prop changes the height and the paddings of the button. The default size is md.

Icons ​

The prepend-icon and append-icon props add an icon before and after the text from text.

The icon prop turns the button into an icon button: the text is hidden and a square button with a single icon remains.

Layout ​

The block prop stretches the button to the full width of its parent container.

The stacked prop places the icon above the text. Such a button is twice as tall as a regular one of the same size, and its minimum width equals its height.

The spaced prop pushes the prepend and append slots to the edges of the button. The value decides on which side of the content the free space appears: start moves the content towards append, end moves it towards prepend, both keeps it centered. The effect shows up only when the button is wider than its content, so spaced usually goes together with block or an explicit width.

Slots ​

Slots replace the content coming from props when you need full control over the markup.

SlotDescription
prependContent before the text. Replaces the icon from prepend-icon
defaultContent inside the button. Replaces the text from text
appendContent after the text. Replaces the icon from append-icon
loaderLoading indicator. Shown instead of the content when loading

Pass href (or to with a RouteLocationRaw object from vue-router) and the button renders as an a tag with all the link attributes, keeping the look and the props of a button.

Guidelines ​

Scenarios ​

Submitting a form ​

The filled button triggers the main action of the form. The loading prop shows the request in progress and guards against a double submit, while the neighboring soft button in the neutral color gives a way to back out.

Action bar ​

Repeating actions on a record — edit, duplicate, delete — fit nicely into a compact bar of icon buttons. The icon prop drops the text and size="sm" saves space. Do not forget aria-label: without text it stays the only name of the action.

Step navigation ​

In wizards and multi-step forms the filled button moves forward and the soft one moves back. Chevron icons in prepend-icon and append-icon reinforce the direction, and disabled blocks moving past the first and the last step.

API ​

Props

NameTypeDefaultDescription
activeboolean | undefined—Controls the active state of the component
activeColorstring | undefined—Color of the component in its active state
appearancedeprecated"inverse" | "primary" | "secondary" | "tertiary" | "transparent" | undefined—Visual appearance of the component. Deprecated: use variant and color
appendIconIconValue | undefined—Icon in the append slot, after the content
baseColorstring | undefined—Color of the component in its inactive state
blockboolean | undefined—Stretches the button to the full width of its container
color(string & {}) | "neutral" | "brand" | "accent" | "danger" | "inverse" | undefined'brand'Component color: a role, a palette alias, a theme token or a CSS color
contentstring | number | undefined—Content displayed in the component.
disabledboolean | null | undefinednullDisabled state
exactboolean | undefined—If true, the active state applies only on an exact route match
heightstring | number | undefined—Component height
hrefstring | undefined—The href attribute of the link. When set, the component behaves as a regular link
iconboolean | IconValue | undefined—Icon to display; the component renders as an icon-only button
loadingstring | boolean | undefined—Loading indicator for the component
maxHeightstring | number | undefined—Maximum component height
maxWidthstring | number | undefined—Maximum component width
minHeightstring | number | undefined—Minimum component height
minWidthstring | number | undefined—Minimum component width
prependIconIconValue | undefined—Icon in the prepend slot, before the content
readonlyboolean | null | undefinednullRead-only state
replaceboolean | undefined—If true, navigation replaces the current history entry instead of pushing a new one
selectedClassstring | undefined—CSS class applied in the selected state
sizenumber | "xs" | "sm" | "md" | "lg" | "xl" | undefined'md'Size of the component
spaced"both" | "start" | "end" | undefined—Pushes the prepend and append slots apart to the edges of the button.
stackedboolean | undefined—Stacks the icon above the text instead of placing them side by side
tagstring | JSXComponent<any> | undefined'button'Custom HTML tag or component to render
textstring | number | undefined—Text displayed in the component.
themestring | undefined—Component theme
toLinkTo | undefined—Target route or route location object for RouterLink. When set, the component behaves as a RouterLink
valueany—Value of the component within the group
variant"solid" | "soft" | "outline" | "surface" | "ghost" | undefined'solid'Component variant: solid, soft, outline, surface, ghost
widthstring | number | undefined—Component width

Events

NameTypeDescription
group:selected[value: { value: boolean; }]Fires when the button is selected inside a group. value is a boolean that tells whether the button is now selected (true) or not (false).

Slots

NameTypeDescription
appendanyContent after the text
defaultanyContent inside the button
loaderanyLoading indicator
prependanyContent before the text

Exposed

NameTypeDescription
groupGroupItemProvide | nullReturns the current group context when the button is used inside a group component (for example, CdsButtonGroup).