The action control: five tones, three sizes, with optional leading and trailing icons or an icon alone, a small avatar before the label or a count after it.
Options
| Choice | Values | Default | What it does |
|---|---|---|---|
tonesmbk-btn--tone-<value> | brandsecondaryoutlineghostdanger | brand | Which action color family the button draws from. Figma calls this axis "Variant". |
sizesmbk-btn--size-<value> | lgmdsmxs | md | Control height, padding, radius, label and icon size step together, one recipe per height. md fits apps and forms; a marketing page may place lg. xs is for a ghost icon-only button beside text, such as a help button in a table heading, and is refused on any other. |
icon-onlysmbk-btn--icon-only | On or off | Off | A square button holding one icon and no label. Needs an accessible name. |
loadingsmbk-btn--loading | On or off | Off | The action is running: a turning ring over the hidden label, the same width, and presses do nothing. It says it is busy. |
full-widthsmbk-btn--full-width | On or off | Off | The button takes the whole width of its space, with its label centered: the one action of a narrow form or of a dialog on a phone. |
Examples
Usage
The brand tone at the medium size, the default.
Tones
One color family per tone: brand for the primary action, secondary and outline beside it, ghost in dense chrome, danger for the destructive one.
Sizes
Three heights, 48, 40 and 32, each with its own padding, label and icon.
With icons
An icon before the label, after it, or both. Icons are content and are placed by the markup.
Icon only
One icon and no label, the same icon as a labeled button of its size. The button is square and needs an accessible name.
Disabled
Every tone has a disabled look. The button stays in the tab order and announces itself as unavailable.
Guidelines
Purpose
The control a person presses to make something happen: submit, confirm, open, delete. It is the only component that carries an action's full color family — fill, border and label, with hover, pressed and disabled states — which is what separates it from a link, which is text that goes somewhere, and from a chip, which is a small selectable token.
When to use
- A primary action on a page or in a form: one brand button, so the eye finds it.
- Secondary and outline for actions beside a primary one, ghost for actions in dense chrome where a filled button would shout.
- Danger for an action that destroys or cannot be undone, always with a confirming step somewhere.
When not to use
- For navigation. Use a link; if it must look like a button, the wrapper renders a link with button classes when given an address, and it stays a link to assistive technology.
- For a small selectable token in a list or a filter row. Use a chip.
- For grouping several related actions. Use the button group, which handles the shared edges.
Usage rules
Do
- Use one brand button per view. Everything else is secondary, outline or ghost.
- Give an icon-only button an accessible name that says what it does, as a verb phrase.
- Mark a button as loading while its action runs, rather than disabling it, so the reader keeps the label and the focus.
- Keep the label short and start it with a verb.
Don't
- Nest a button inside a link or a link inside a button.
- Change a button's colors with extra classes. The tones are the whole palette; a new tone is a Figma decision.
- Set a width on an icon-only button. It is square by its size.
- Set a width to stretch a button. Use the full-width flag, which keeps its content centered.
- Put anything that can be pressed in the leading content, or more than a short number in the count.
- Use the extra-small size for anything but a ghost icon-only button beside text.
Use one brand button per view, so the main action is obvious.
Two brand buttons side by side leave the reader guessing which matters.
Start the label with a verb and keep it short, so the reader knows what will happen.
A long label that does not start with a verb reads like a sentence, not an action.
Anatomy
- The block, an inline row that centers its content and fixes its own height by size.
- The label part, the text. Required unless the button is icon-only.
- The icon part, a Phosphor glyph before the label, after it, or both. Optional. An icon-only button has exactly one icon and no label, and is square.
- The leading content part, something small before the label and after the leading icon, such as an avatar at the icon's size. Optional.
- The count part, a number after the label, such as unread messages, drawn as the badge's small neutral pill. Optional.
- The spinner part, the spinner's turning ring, drawn in the middle of a busy button over its hidden label and icons. Present only while the loading flag is on.
Leading and trailing icons are content, not options: they are placed by the markup, and the size axis sets their size. An icon-only button uses the same icon size as a labeled button of its size. The order in the row is leading icon, leading content, label, count, trailing icon.
The full-width flag stretches the button across the whole width of its space, with its content still centered: the one action at the foot of a narrow form, or the actions of a dialog on a phone.
Sizes
Three heights, each with its own padding, label and icon: small is 32 tall, medium 40, large 48, and in the compact density 28, 32 and 40. Medium is the default. Which one a page places depends on what the page is:
- An app or a dashboard uses the compact density: 40 for the page's one main action and for forms, 32 for toolbars and filters (the size used most), 28 for actions inside table rows and cards.
- A marketing page may place the large button for its main call to action.
- On a touch screen every size keeps these heights; one shorter than the comfortable touch target takes an invisible press area out to it.
A fourth, extra-small size is for one thing only: a ghost icon-only button beside text, such as a help button in a table heading or the "more" crumb in a breadcrumb trail. It is a 24 pixel square with a small icon. On any other tone or with a label the wrapper draws the small size instead and warns in development. On a touch screen it keeps its square and takes an invisible press area round it, out to the comfortable touch target, as every size does.
Behavior
Hover and pressed change the fill and border; the brand tone also gains an inset shadow when hovered or pressed, which reads as the button sinking. While pressed, the fill and its edge also draw in by a hairline on every side, so the button reads as pushed in at any width; its size, its place and its focus ring stay as they are. Buttons fused into a segmented bar or a split button, and a toggle button that is on, keep their pressed look without drawing in. The toggle button is this button with its pressed attribute and the toggle's mark, and the button's stylesheet draws it on as well: sunken into the page, the same size as off. A disabled button of any tone takes the same faint fill, edge and label, always fainter than an enabled one; it keeps its footprint and drops pointer events. Nothing animates: state changes are immediate.
While its action runs, a button can be marked as loading. The spinner's ring turns in its middle, in the button's own label color, while the label and icons stay in place but unseen, so the button keeps its width and the row around it does not jump. It keeps its resting look, with no hover or pressed look, and shows a waiting pointer. A busy button stays focusable, and a click, Enter or Space does nothing: no handler runs, no form is sent, and a link goes nowhere. When the action ends, the page clears the flag and says how it went.
Desktop and mobile are the same implementation; the button does not change shape with the viewport, only with density through its control-size tokens.
A ref given to the wrapper reaches the native button, or the link when the button has an address.
Accessibility
What it does for you
- It is a real button, or a real link when it has an address, so Enter and Space press a button and Enter follows a link, with no script of yours.
- Its label is its name. Icons beside the label are hidden from assistive technology. A count is read after the label, as in "Inbox 12".
- Its focus ring is the system's: an outline in the focus color, set off from its edge, which survives forced-color modes.
- While loading, it keeps its label as its name, tells assistive technology it is busy, keeps focus and ignores presses. The turning ring is hidden from assistive technology.
- Disabled, it uses the native disabled attribute. Marked with the aria-disabled attribute instead, it stays in the tab order and does nothing when clicked or pressed with Enter or Space. The stylesheet draws both the same.
- On a touch screen every size takes a press out to the comfortable touch target through an invisible area round it, halfway to the next button where buttons stand closer. The button and its focus ring keep their own edge.
What you must do
- Hide an avatar in the leading content from assistive technology when it only repeats the label, since everything inside the button is read as its name.
- Give an icon-only button an accessible name that says what it does, as a verb phrase. Without one the wrapper warns in development and names it by its icon's words, such as "Magnifying glass", which say what it shows, not what it does.
- When a loading button's action ends, say once how it went, from the page. The button does not announce it.
- Use aria-disabled rather than disabled when a disabled button should stay focusable and explain itself.
- In markup written by hand, add the busy attribute and block presses yourself while it loads.
How to test
- Tab to it: the focus ring shows, in both themes and in a forced-color mode.
- Press Enter, then Space: each runs the action once. While it loads, neither does anything and focus stays on it.
- With a screen reader, it is read as a button, or a link, by its label; an icon-only button by what it does; a loading one as busy.
- With text at 200% and the page 320 pixels wide, its label stays whole.
- Automated checks find a missing name. A check by hand, with a keyboard and a screen reader, finds what they cannot.
Keyboard
| Key | What it does |
|---|---|
| Tab | Moves focus to the button. A disabled button is skipped; one marked aria-disabled is not. |
| Enter | Presses the button, or follows its address when it is a link. |
| Space | Presses the button. A button with an address is a link, which Space does not follow. |
Source
The files the button is made of. Its folder on GitHub (opens in a new tab) holds them with its wrapper and its document.
Stylesheet
/* smbk-btn — Button.
* Figma "Button" 4136:5058. Semantic tokens only; states are pseudo-classes.
* The focus ring is the system rule. Hover and press change at once.
* The loading flag draws the spinner's ring over the hidden label; hover and press do not apply then.
* A label drawn as a button round a native input, as the file upload's is, takes that input's focus ring and
* disabled look. */
.smbk-btn {
box-sizing: border-box;
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--smbk-space-inline-md);
height: var(--smbk-size-control-md);
padding: 0 var(--smbk-space-inset-xl);
border: var(--smbk-border-width-hairline) solid transparent;
border-radius: var(--smbk-radius-control-sm);
background: var(--smbk-color-action-brand-background);
border-color: var(--smbk-color-action-brand-border);
color: var(--smbk-color-action-brand-foreground);
font-family: var(--smbk-typography-label-lg-font-family);
font-size: var(--smbk-typography-label-lg-font-size);
font-weight: var(--smbk-typography-label-lg-font-weight);
line-height: var(--smbk-typography-label-lg-line-height);
letter-spacing: var(--smbk-typography-label-lg-letter-spacing);
text-transform: var(--smbk-typography-label-lg-text-transform);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
-webkit-user-select: none;
user-select: none;
appearance: none;
-webkit-tap-highlight-color: transparent;
touch-action: manipulation;
}
.smbk-btn:focus-visible,
.smbk-btn:has(> input:focus-visible) {
outline: var(--smbk-focus-ring-width) solid var(--smbk-color-border-focus);
outline-offset: var(--smbk-focus-ring-offset);
}
.smbk-btn:disabled,
.smbk-btn[aria-disabled="true"],
.smbk-btn:has(> input:disabled) {
cursor: not-allowed;
pointer-events: none;
}
/* ---- parts ---- */
.smbk-btn__icon {
font-size: var(--smbk-size-icon-md);
}
.smbk-btn__label {
display: inline-block;
}
/* Leading content (a small avatar) keeps its own size and sits on the label's line. */
.smbk-btn__leading-content {
display: inline-flex;
flex-shrink: 0;
align-items: center;
}
/* The count is the badge's small neutral pill (its own classes draw it), right after the label. In a disabled
button its number takes the disabled label color with the rest. */
.smbk-btn__count {
flex-shrink: 0;
}
.smbk-btn:is(:disabled, [aria-disabled="true"]) .smbk-btn__count {
color: var(--smbk-color-action-disabled-foreground);
}
/* ---- tone: brand (the default) ---- */
@media (hover: hover) {
.smbk-btn--tone-brand:hover:where(:not(.smbk-btn--loading)) {
background: var(--smbk-color-action-brand-background-hover);
border-color: var(--smbk-color-action-brand-border-hover);
box-shadow: var(--smbk-elevation-inset);
}
}
.smbk-btn--tone-brand:active:where(:not(.smbk-btn--loading)) {
background: var(--smbk-color-action-brand-background-pressed);
border-color: var(--smbk-color-action-brand-border-hover);
box-shadow: var(--smbk-elevation-inset);
--smbk-btn-pressed-edge: var(--smbk-color-action-brand-border-hover);
}
/* ---- tone: secondary — a filled button with no border ---- */
.smbk-btn--tone-secondary {
background: var(--smbk-color-action-secondary-background);
border-color: transparent;
color: var(--smbk-color-action-secondary-foreground);
}
@media (hover: hover) {
.smbk-btn--tone-secondary:hover:where(:not(.smbk-btn--loading)) {
background: var(--smbk-color-action-secondary-background-hover);
}
}
.smbk-btn--tone-secondary:active:where(:not(.smbk-btn--loading)) {
background: var(--smbk-color-action-secondary-background-pressed);
}
/* ---- tone: outline — transparent with a visible border ---- */
.smbk-btn--tone-outline {
background: transparent;
border-color: var(--smbk-color-action-outline-border);
color: var(--smbk-color-action-outline-foreground);
}
@media (hover: hover) {
.smbk-btn--tone-outline:hover:where(:not(.smbk-btn--loading)) {
background: var(--smbk-color-action-outline-background-hover);
border-color: var(--smbk-color-action-outline-border-hover);
}
}
.smbk-btn--tone-outline:active:where(:not(.smbk-btn--loading)) {
background: var(--smbk-color-action-outline-background-pressed);
border-color: var(--smbk-color-action-outline-border-pressed);
--smbk-btn-pressed-edge: var(--smbk-color-action-outline-border-pressed);
}
/* ---- tone: ghost — no chrome at rest, keeps the full hit area ---- */
.smbk-btn--tone-ghost {
background: transparent;
border-color: transparent;
color: var(--smbk-color-action-ghost-foreground);
}
@media (hover: hover) {
.smbk-btn--tone-ghost:hover:where(:not(.smbk-btn--loading)) {
background: var(--smbk-color-action-ghost-background-hover);
}
}
.smbk-btn--tone-ghost:active:where(:not(.smbk-btn--loading)) {
background: var(--smbk-color-action-ghost-background-pressed);
}
/* ---- tone: danger — the destructive family ---- */
.smbk-btn--tone-danger {
background: var(--smbk-color-action-danger-background);
border-color: var(--smbk-color-action-danger-border);
color: var(--smbk-color-action-danger-foreground);
}
@media (hover: hover) {
.smbk-btn--tone-danger:hover:where(:not(.smbk-btn--loading)) {
background: var(--smbk-color-action-danger-background-hover);
border-color: var(--smbk-color-action-danger-border-hover);
color: var(--smbk-color-action-danger-foreground-hover);
}
}
.smbk-btn--tone-danger:active:where(:not(.smbk-btn--loading)) {
background: var(--smbk-color-action-danger-background-pressed);
border-color: var(--smbk-color-action-danger-border-hover);
color: var(--smbk-color-action-danger-foreground-hover);
--smbk-btn-pressed-edge: var(--smbk-color-action-danger-border-hover);
}
/* ---- pressed: the surface draws in a hairline on every side ----
While pressed, the fill, the edge and the brand tone's inset shadow are drawn a hairline inside the button's
box on every side, so the button reads as pushed in, whatever its width (a scale would shrink a wide button
far more across than down). The fill stops at the inside of the button's own edge and the edge goes clear;
the tone's pressed edge, carried by --smbk-btn-pressed-edge, is drawn again as an inset ring just inside, with
the corners rounded one hairline less. The box, the layout, the focus ring and the press area do not change.
Like every other change of the button's look, it comes and goes at once (no fade, so a theme change or a
hover never fades either). Not while loading or disabled, not for a toggle button that is on, which is
already drawn pressed in, and not in a segmented or merged bar (the split button is one): the bar is one
surface, its hairlines between buttons stay where they are, and a button drawn in would leave a stray
line beside them. */
.smbk-btn:active:where(:not(.smbk-btn--loading, :disabled, [aria-disabled="true"], [aria-pressed="true"], .smbk-btn-group--type-segmented > *, .smbk-btn-group--type-segmented > * > *)) {
border-color: transparent;
background-clip: padding-box;
}
.smbk-btn:active:where(:not(.smbk-btn--loading, :disabled, [aria-disabled="true"], [aria-pressed="true"], .smbk-btn-group--type-segmented > *, .smbk-btn-group--type-segmented > * > *)):where(.smbk-btn--tone-outline, .smbk-btn--tone-danger) {
box-shadow: inset 0 0 0 var(--smbk-border-width-hairline) var(--smbk-btn-pressed-edge);
}
.smbk-btn--tone-brand:active:where(:not(.smbk-btn--loading, :disabled, [aria-disabled="true"], [aria-pressed="true"], .smbk-btn-group--type-segmented > *, .smbk-btn-group--type-segmented > * > *)) {
box-shadow: inset 0 0 0 var(--smbk-border-width-hairline) var(--smbk-btn-pressed-edge), var(--smbk-elevation-inset);
}
/* ---- disabled: one look in every tone ----
The shared disabled fill, edge and label, fainter than any enabled button. The secondary tone has no edge
and the ghost tone no fill, disabled as at rest. */
.smbk-btn:disabled,
.smbk-btn[aria-disabled="true"],
.smbk-btn:has(> input:disabled) {
background: var(--smbk-color-action-disabled-background);
border-color: var(--smbk-color-action-disabled-border);
color: var(--smbk-color-action-disabled-foreground);
box-shadow: none;
}
.smbk-btn--tone-secondary:disabled,
.smbk-btn--tone-secondary[aria-disabled="true"],
.smbk-btn--tone-secondary:has(> input:disabled) {
border-color: transparent;
}
.smbk-btn--tone-ghost:disabled,
.smbk-btn--tone-ghost[aria-disabled="true"],
.smbk-btn--tone-ghost:has(> input:disabled) {
background: transparent;
border-color: transparent;
}
/* ---- on: a toggle button that is pressed (Figma "Toggle button" 7125:4263) ----
A toggle button is this button with aria-pressed: the outline button, or the ghost button for a toolbar's tool,
when off, and sunken into the page when on. On is the button's own aria-pressed, never a class, so the look and
what a screen reader hears cannot disagree. For now the on look also asks for the toggle button's mark,
smbk-toggle-button, so a plain button a page marks pressed keeps its own look; a later Release draws it from
aria-pressed alone.
On: the sunken fill, the rim for its edge and the strong inset shadow over both, in every state, as Figma draws
it: the shadow falls across the rim at the top and the trailing side, so the rim shows only along the bottom and
the leading side and the button reads as pressed in, not outlined. A box shadow is drawn inside the border, so
the shadow is a layer of its own laid over the whole button, edge included. The edge keeps its width, so the
button is the same size on and off. A native button's on look outweighs the button group's merged and segmented
edges (button-group.css), which come later in the bundle; markup that is not a native button keeps the class
rule's weight. */
:where(.smbk-btn.smbk-toggle-button) {
position: relative;
}
button.smbk-btn.smbk-toggle-button[aria-pressed="true"],
button.smbk-btn.smbk-toggle-button[aria-pressed="true"]:is(:hover, :active),
.smbk-btn.smbk-toggle-button[aria-pressed="true"],
.smbk-btn.smbk-toggle-button[aria-pressed="true"]:is(:hover, :active) {
background: var(--smbk-color-surface-sunken);
border-color: var(--smbk-color-border-rim);
box-shadow: none;
}
button.smbk-btn.smbk-toggle-button[aria-pressed="true"]::before,
.smbk-btn.smbk-toggle-button[aria-pressed="true"]::before {
content: '';
position: absolute;
inset: calc(-1 * var(--smbk-border-width-hairline));
border-radius: inherit;
box-shadow: var(--smbk-elevation-inset-strong);
pointer-events: none;
}
/* On and disabled: the shared disabled fill and label, the rim kept, no shadow. */
button.smbk-btn.smbk-toggle-button[aria-pressed="true"]:is(:disabled, [aria-disabled="true"]),
.smbk-btn.smbk-toggle-button[aria-pressed="true"]:is(:disabled, [aria-disabled="true"]) {
background: var(--smbk-color-action-disabled-background);
border-color: var(--smbk-color-border-rim);
box-shadow: none;
}
button.smbk-btn.smbk-toggle-button[aria-pressed="true"]:is(:disabled, [aria-disabled="true"])::before,
.smbk-btn.smbk-toggle-button[aria-pressed="true"]:is(:disabled, [aria-disabled="true"])::before {
box-shadow: none;
}
/* ---- size: md is the base above; one recipe per height ---- */
.smbk-btn--size-lg {
height: var(--smbk-size-control-lg);
padding: 0 var(--smbk-space-inset-2xl);
border-radius: var(--smbk-radius-control-md);
}
.smbk-btn--size-sm {
gap: var(--smbk-space-inline-sm);
height: var(--smbk-size-control-sm);
padding: 0 var(--smbk-space-inset-lg);
font-family: var(--smbk-typography-label-md-font-family);
font-size: var(--smbk-typography-label-md-font-size);
font-weight: var(--smbk-typography-label-md-font-weight);
line-height: var(--smbk-typography-label-md-line-height);
letter-spacing: var(--smbk-typography-label-md-letter-spacing);
text-transform: var(--smbk-typography-label-md-text-transform);
}
.smbk-btn--size-sm .smbk-btn__icon {
font-size: var(--smbk-size-icon-sm);
}
/* ---- icon only: a square, with the same icon as a labeled button of its size ---- */
.smbk-btn--icon-only {
width: var(--smbk-size-control-md);
padding: 0;
gap: 0;
}
.smbk-btn--icon-only.smbk-btn--size-lg {
width: var(--smbk-size-control-lg);
}
.smbk-btn--icon-only.smbk-btn--size-sm {
width: var(--smbk-size-control-sm);
}
/* ---- size xs: the ghost icon button only, a 24 square with a 12 icon ----
Figma's Icon button draws xs in the ghost tone alone; the wrapper refuses it on any other tone or with a
label. The box is the smallest target size; on a touch screen it takes a press area round it (below). */
.smbk-btn--size-xs {
gap: var(--smbk-space-inline-xs);
height: var(--smbk-size-control-xs);
padding: 0 var(--smbk-space-inset-md);
border-radius: var(--smbk-radius-control-sm);
}
.smbk-btn--size-xs .smbk-btn__icon {
font-size: var(--smbk-size-icon-xs);
}
.smbk-btn--icon-only.smbk-btn--size-xs {
width: var(--smbk-size-control-xs);
padding: 0;
}
/* ---- full width: the button takes the whole width of its space ----
The label and its icons stay centered. After the icon-only rules, so a stretched icon button stretches too. */
.smbk-btn--full-width {
width: 100%;
}
/* ---- loading: the action is running ----
The spinner's ring turns in the middle of the button, in the tone's own foreground, at the button's icon
size. The label and icons stay in place, unseen, so the button keeps its width and its name. It keeps the
tone's resting look: no hover or pressed look, and a waiting pointer. It is never disabled, so focus stays
on it; the wrapper makes a press do nothing. */
.smbk-btn--loading {
position: relative;
cursor: progress;
}
.smbk-btn--loading > :not(.smbk-btn__spinner) {
opacity: 0;
}
.smbk-btn--loading > .smbk-btn__spinner {
position: absolute;
inset: 0;
justify-content: center;
color: inherit;
}
/* ---- touch: every size keeps its look and takes an invisible press area ----
On a touch screen an invisible area, centred on the button, takes the press out to the comfortable target in
each direction the button falls short of it; the button, its focus ring and its place stay as drawn. A component
that sets buttons closer together than that stops their areas halfway to the next one. The position is
written with no weight, so a component that places a button absolutely keeps doing so. */
@media (pointer: coarse) {
:where(.smbk-btn) {
position: relative;
}
.smbk-btn::after {
content: '';
position: absolute;
inset: min(0%, (100% - var(--smbk-size-target-comfortable)) / 2);
}
}Tokens it reads
| Token and CSS | Value | Preview | Foundation |
|---|---|---|---|
| space.inline.md--smbk-space-inline-md | comfortable: 8pxcompact: 6pxchanges with density | Spacing | |
| size.control.md--smbk-size-control-md | comfortable: 40pxcompact: 32pxchanges with density | Size | |
| space.inset.xl--smbk-space-inset-xl | comfortable: 16pxcompact: 12pxchanges with density | Spacing | |
| border-width.hairline--smbk-border-width-hairline | 1px | Border width | |
| radius.control.sm--smbk-radius-control-sm | 4px | Radius | |
| color.action.brand.background--smbk-color-action-brand-background | #cc0d0d | Color | |
| color.action.brand.border--smbk-color-action-brand-border | #ffffff1a | Color | |
| color.action.brand.foreground--smbk-color-action-brand-foreground | #f9fafb | Color | |
| typography.label-lg--smbk-typography-label-lg-font-family--smbk-typography-label-lg-font-size--smbk-typography-label-lg-font-weight--smbk-typography-label-lg-line-height--smbk-typography-label-lg-letter-spacing--smbk-typography-label-lg-text-transform | fontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 16pxfontWeight: 500lineHeight: 1.4letterSpacing: 0px | The quick brown fox | Typography |
| focus.ring.width--smbk-focus-ring-width | 2px | Focus | |
| color.border.focus--smbk-color-border-focus | light: #cc0d0ddark: #f34336changes with theme | Color | |
| focus.ring.offset--smbk-focus-ring-offset | 2px | Focus | |
| size.icon.md--smbk-size-icon-md | 20px | Size | |
| color.action.disabled.foreground--smbk-color-action-disabled-foreground | light: #7c8692dark: #606a75changes with theme | Color | |
| color.action.brand.background-hover--smbk-color-action-brand-background-hover | #a51d17 | Color | |
| color.action.brand.border-hover--smbk-color-action-brand-border-hover | #0000000d | Color | |
| elevation.inset--smbk-elevation-inset | light: inset 0px 0px 1px 0px #373d434ddark: inset 0px 0px 1px 0px #00000066 | Elevation | |
| color.action.brand.background-pressed--smbk-color-action-brand-background-pressed | #761812 | Color | |
| color.action.secondary.background--smbk-color-action-secondary-background | light: #373d4326dark: #606a7533changes with theme | Color | |
| color.action.secondary.foreground--smbk-color-action-secondary-foreground | light: #2d3237dark: #c4cdd8changes with theme | Color | |
| color.action.secondary.background-hover--smbk-color-action-secondary-background-hover | light: #373d4333dark: #606a754dchanges with theme | Color | |
| color.action.secondary.background-pressed--smbk-color-action-secondary-background-pressed | light: #373d4340dark: #606a7566changes with theme | Color | |
| color.action.outline.border--smbk-color-action-outline-border | light: #c4cdd8dark: #373d43changes with theme | Color | |
| color.action.outline.foreground--smbk-color-action-outline-foreground | light: #2d3237dark: #c4cdd8changes with theme | Color | |
| color.action.outline.background-hover--smbk-color-action-outline-background-hover | light: #373d431adark: #606a751achanges with theme | Color | |
| color.action.outline.border-hover--smbk-color-action-outline-border-hover | light: #9ba5b1dark: #4e555echanges with theme | Color | |
| color.action.outline.background-pressed--smbk-color-action-outline-background-pressed | light: #c4cdd8dark: #2d3237changes with theme | Color | |
| color.action.outline.border-pressed--smbk-color-action-outline-border-pressed | light: #7c8692dark: #606a75changes with theme | Color | |
| color.action.ghost.foreground--smbk-color-action-ghost-foreground | light: #2d3237dark: #c4cdd8changes with theme | Color | |
| color.action.ghost.background-hover--smbk-color-action-ghost-background-hover | light: #373d4326dark: #606a754dchanges with theme | Color | |
| color.action.ghost.background-pressed--smbk-color-action-ghost-background-pressed | light: #c4cdd8dark: #2d3237 | Color | |
| color.action.danger.background--smbk-color-action-danger-background | light: #febdb2dark: #4b130echanges with theme | Color | |
| color.action.danger.border--smbk-color-action-danger-border | #0000000d | Color | |
| color.action.danger.foreground--smbk-color-action-danger-foreground | light: #761812dark: #febdb2changes with theme | Color | |
| color.action.danger.background-hover--smbk-color-action-danger-background-hover | light: #fe7d6ddark: #761812changes with theme | Color | |
| color.action.danger.border-hover--smbk-color-action-danger-border-hover | light: #cc0d0d4ddark: #f34336changes with theme | Color | |
| color.action.danger.foreground-hover--smbk-color-action-danger-foreground-hover | light: #2a0403dark: #fee5e1changes with theme | Color | |
| color.action.danger.background-pressed--smbk-color-action-danger-background-pressed | light: #f34336dark: #a51d17changes with theme | Color | |
| color.action.disabled.background--smbk-color-action-disabled-background | light: #373d4314dark: #606a751achanges with theme | Color | |
| color.action.disabled.border--smbk-color-action-disabled-border | light: #c4cdd8dark: #2d3237changes with theme | Color | |
| color.surface.sunken--smbk-color-surface-sunken | light: #373d430ddark: #00000066changes with theme | Color | |
| color.border.rim--smbk-color-border-rim | light: #ffffffe6dark: #ffffff0dchanges with theme | Color | |
| elevation.inset-strong--smbk-elevation-inset-strong | light: inset -1px 2px 2px 0px #373d4333dark: inset -1px 2px 2px 0px #0000004d | Elevation | |
| size.control.lg--smbk-size-control-lg | comfortable: 48pxcompact: 40pxchanges with density | Size | |
| space.inset.2xl--smbk-space-inset-2xl | comfortable: 24pxcompact: 16pxchanges with density | Spacing | |
| radius.control.md--smbk-radius-control-md | 6px | Radius | |
| space.inline.sm--smbk-space-inline-sm | comfortable: 6pxcompact: 4pxchanges with density | Spacing | |
| size.control.sm--smbk-size-control-sm | comfortable: 32pxcompact: 28pxchanges with density | Size | |
| space.inset.lg--smbk-space-inset-lg | comfortable: 12pxcompact: 8pxchanges with density | Spacing | |
| typography.label-md--smbk-typography-label-md-font-family--smbk-typography-label-md-font-size--smbk-typography-label-md-font-weight--smbk-typography-label-md-line-height--smbk-typography-label-md-letter-spacing--smbk-typography-label-md-text-transform | fontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 14pxfontWeight: 500lineHeight: 1.4letterSpacing: 0px | The quick brown fox | Typography |
| size.icon.sm--smbk-size-icon-sm | 16px | Size | |
| space.inline.xs--smbk-space-inline-xs | 4px | Spacing | |
| size.control.xs--smbk-size-control-xs | 24px | Size | |
| space.inset.md--smbk-space-inset-md | comfortable: 8pxcompact: 6pxchanges with density | Spacing | |
| size.icon.xs--smbk-size-icon-xs | 12px | Size | |
| size.target.comfortable--smbk-size-target-comfortable | 44px | Size |
Manifest
{
"name": "button",
"block": "smbk-btn",
"summary": "The action control: five tones, three sizes, with optional leading and trailing icons or an icon alone, a small avatar before the label or a count after it.",
"adapt": "css",
"axes": {
"tone": {
"values": [
"brand",
"secondary",
"outline",
"ghost",
"danger"
],
"default": "brand",
"description": "Which action color family the button draws from. Figma calls this axis \"Variant\"."
},
"size": {
"values": [
"lg",
"md",
"sm",
"xs"
],
"default": "md",
"description": "Control height, padding, radius, label and icon size step together, one recipe per height. md fits apps and forms; a marketing page may place lg. xs is for a ghost icon-only button beside text, such as a help button in a table heading, and is refused on any other."
}
},
"flags": {
"icon-only": {
"description": "A square button holding one icon and no label. Needs an accessible name."
},
"loading": {
"description": "The action is running: a turning ring over the hidden label, the same width, and presses do nothing. It says it is busy."
},
"full-width": {
"description": "The button takes the whole width of its space, with its label centered: the one action of a narrow form or of a dialog on a phone."
}
},
"parts": [
"icon",
"leading-content",
"label",
"count",
"spinner"
],
"figmaNodeId": "4136:5058"
}