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.
| Variant | Looks like | When |
|---|---|---|
solid | filled with the color | the main action on the screen |
soft | a translucent tint of the color | a supporting action |
outline | a border, transparent background | a supporting action on a busy background |
surface | a border on a surface backdrop | an action over an image or a chart |
ghost | neither background nor border | an 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 asbrandin 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.
appearance | variant | color |
|---|---|---|
primary | solid | brand |
secondary | soft | brand |
tertiary | soft | neutral |
inverse | solid | inverse |
transparent | ghost | brand |
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.
| Slot | Description |
|---|---|
prepend | Content before the text. Replaces the icon from prepend-icon |
default | Content inside the button. Replaces the text from text |
append | Content after the text. Replaces the icon from append-icon |
loader | Loading indicator. Shown instead of the content when loading |
Link button
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
| Name | Type | Default | Description |
|---|---|---|---|
active | boolean | undefined | — | Controls the active state of the component |
activeColor | string | 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 |
appendIcon | IconValue | undefined | — | Icon in the append slot, after the content |
baseColor | string | undefined | — | Color of the component in its inactive state |
block | boolean | 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 |
content | string | number | undefined | — | Content displayed in the component. |
disabled | boolean | null | undefined | null | Disabled state |
exact | boolean | undefined | — | If true, the active state applies only on an exact route match |
height | string | number | undefined | — | Component height |
href | string | undefined | — | The href attribute of the link. When set, the component behaves as a regular link |
icon | boolean | IconValue | undefined | — | Icon to display; the component renders as an icon-only button |
loading | string | boolean | undefined | — | Loading indicator for the component |
maxHeight | string | number | undefined | — | Maximum component height |
maxWidth | string | number | undefined | — | Maximum component width |
minHeight | string | number | undefined | — | Minimum component height |
minWidth | string | number | undefined | — | Minimum component width |
prependIcon | IconValue | undefined | — | Icon in the prepend slot, before the content |
readonly | boolean | null | undefined | null | Read-only state |
replace | boolean | undefined | — | If true, navigation replaces the current history entry instead of pushing a new one |
selectedClass | string | undefined | — | CSS class applied in the selected state |
size | number | "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. |
stacked | boolean | undefined | — | Stacks the icon above the text instead of placing them side by side |
tag | string | JSXComponent<any> | undefined | 'button' | Custom HTML tag or component to render |
text | string | number | undefined | — | Text displayed in the component. |
theme | string | undefined | — | Component theme |
to | LinkTo | undefined | — | Target route or route location object for RouterLink. When set, the component behaves as a RouterLink |
value | any | — | Value of the component within the group |
variant | "solid" | "soft" | "outline" | "surface" | "ghost" | undefined | 'solid' | Component variant: solid, soft, outline, surface, ghost |
width | string | number | undefined | — | Component width |
Events
| Name | Type | Description |
|---|---|---|
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
| Name | Type | Description |
|---|---|---|
append | any | Content after the text |
default | any | Content inside the button |
loader | any | Loading indicator |
prepend | any | Content before the text |
Exposed
| Name | Type | Description |
|---|---|---|
group | GroupItemProvide | null | Returns the current group context when the button is used inside a group component (for example, CdsButtonGroup). |