Buttons
.sb-btn is the one button class. Intent, variant and size are separate modifiers that compose, so sb-btn sb-btn-outline sb-btn-danger sb-btn-sm is an outlined, small, danger button. With no modifiers you get a solid, primary, medium button.
Always set type="button" on a <button> that is not meant to submit a form.
Variants
Section titled “Variants”<div class="sb-cluster"> <button type="button" class="sb-btn sb-btn-solid">Solid</button> <button type="button" class="sb-btn sb-btn-soft">Soft</button> <button type="button" class="sb-btn sb-btn-outline">Outline</button> <button type="button" class="sb-btn sb-btn-ghost">Ghost</button> <button type="button" class="sb-btn sb-btn-link">Link</button></div>| Class | Effect |
|---|---|
sb-btn |
Base button: layout, type, hairline border, focus ring. Defaults to solid, primary, medium. |
sb-btn-solid |
Filled with the intent color and its on-accent ink (the default). |
sb-btn-soft |
Tinted wash of the intent color. The text mixes the intent with the foreground per flavor (--sb-soft-ink) to stay AA on the tint. |
sb-btn-outline |
Transparent with an intent-colored border. |
sb-btn-ghost |
No fill or border until hover. Primary and neutral ghosts use the foreground ink. |
sb-btn-link |
Underlined text without padding or fixed height. |
Intents
Section titled “Intents”An intent class sets the color the variant uses.
<div class="sb-cluster"> <button type="button" class="sb-btn sb-btn-primary">Primary</button> <button type="button" class="sb-btn sb-btn-secondary">Secondary</button> <button type="button" class="sb-btn sb-btn-neutral">Neutral</button> <button type="button" class="sb-btn sb-btn-info">Info</button> <button type="button" class="sb-btn sb-btn-success">Success</button> <button type="button" class="sb-btn sb-btn-warning">Warning</button> <button type="button" class="sb-btn sb-btn-danger">Danger</button></div><div class="sb-cluster"> <button type="button" class="sb-btn sb-btn-outline sb-btn-danger">Outline danger</button> <button type="button" class="sb-btn sb-btn-soft sb-btn-success">Soft success</button> <button type="button" class="sb-btn sb-btn-ghost sb-btn-info">Ghost info</button></div>| Class | Color |
|---|---|
sb-btn-primary |
The active accent (default). |
sb-btn-secondary |
Ultraviolet. |
sb-btn-neutral |
The foreground ink (--sb-fg), for low-emphasis actions. |
sb-btn-info |
Info. |
sb-btn-success |
Success. |
sb-btn-warning |
Warning. |
sb-btn-danger |
Danger. |
<div class="sb-cluster"> <button type="button" class="sb-btn sb-btn-xs">Extra small</button> <button type="button" class="sb-btn sb-btn-sm">Small</button> <button type="button" class="sb-btn sb-btn-md">Medium</button> <button type="button" class="sb-btn sb-btn-lg">Large</button></div><div class="sb-cluster"> <button type="button" class="sb-btn sb-btn-outline sb-btn-sm"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"/></svg> Overclock </button></div>| Class | Height | Horizontal padding | Type |
|---|---|---|---|
sb-btn-xs |
1.75rem | 0.625rem | text-xs |
sb-btn-sm |
2rem | 0.75rem | text-sm |
sb-btn-md |
2.5rem | 1rem | text-sm (default) |
sb-btn-lg |
3rem | 1.25rem | text-base |
A direct child <svg> is sized and spaced by the button; it inherits the text color.
Icon-only, block and grouped
Section titled “Icon-only, block and grouped”sb-btn-icon makes the button square (width equals the size’s height). An icon-only button has no text, so it needs an aria-label.
<div class="sb-cluster"> <button type="button" class="sb-btn sb-btn-icon sb-btn-xs" aria-label="Add"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 12h14M12 5v14"/></svg></button> <button type="button" class="sb-btn sb-btn-icon sb-btn-sm sb-btn-soft" aria-label="Add"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 12h14M12 5v14"/></svg></button> <button type="button" class="sb-btn sb-btn-icon sb-btn-md sb-btn-outline" aria-label="Add"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 12h14M12 5v14"/></svg></button> <button type="button" class="sb-btn sb-btn-icon sb-btn-lg sb-btn-ghost" aria-label="Close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg></button> <button type="button" class="sb-btn sb-btn-icon sb-btn-md sb-btn-soft sb-btn-danger" aria-label="Delete"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg></button></div>sb-btn-block stretches a button to the full width of its container. sb-btn-group joins adjacent buttons into one segmented control; put role="group" and an aria-label on it.
<div class="sb-stack"> <button type="button" class="sb-btn sb-btn-block sb-btn-secondary">Block button</button> <div class="sb-cluster"> <div class="sb-btn-group" role="group" aria-label="Range"> <button type="button" class="sb-btn">Day</button> <button type="button" class="sb-btn">Week</button> <button type="button" class="sb-btn">Month</button> </div> <div class="sb-btn-group" role="group" aria-label="Alignment"> <button type="button" class="sb-btn sb-btn-outline sb-btn-sm">Left</button> <button type="button" class="sb-btn sb-btn-outline sb-btn-sm">Center</button> <button type="button" class="sb-btn sb-btn-outline sb-btn-sm">Right</button> </div> </div></div>| Class | Effect |
|---|---|
sb-btn-icon |
Square, icon-only button. |
sb-btn-block |
Full-width button. |
sb-btn-group |
Container that squares the inner corners and collapses the borders of child .sb-btn elements. |
States
Section titled “States”The CSS keys on these attributes and pseudo-classes; there are no state classes.
<div class="sb-cluster"> <button type="button" class="sb-btn" disabled>Disabled</button> <button type="button" class="sb-btn sb-btn-soft" aria-disabled="true">aria-disabled</button> <button type="button" class="sb-btn sb-btn-outline" disabled>Disabled outline</button></div><div class="sb-cluster"> <button type="button" class="sb-btn" aria-busy="true"><span>Saving</span></button> <button type="button" class="sb-btn sb-btn-soft sb-btn-info" aria-busy="true"><span>Loading</span></button> <button type="button" class="sb-btn sb-btn-outline sb-btn-success" aria-busy="true"><span>Syncing</span></button></div>| Selector | Effect |
|---|---|
:hover |
A small bloom, plus per variant: solid lightens its fill, outline takes the soft tint, ghost the raised panel fill, and soft keeps its tint. Text on a tint or fill switches to the soft ink so it stays AA. Not applied to disabled or aria-disabled buttons. |
:active |
Moves down 1px and drops the bloom. Not applied to disabled or aria-disabled buttons. |
:focus-visible |
Keyboard focus ring. |
:disabled |
Dimmed, not-allowed cursor, no pointer feedback. |
[aria-disabled="true"] |
Same look as :disabled for elements that must stay focusable. Set the behavior yourself; the attribute does not block clicks. |
[aria-busy="true"] |
Loading: the label is hidden and a ring spinner is drawn over it. The button ignores pointer input. Wrap the text in a child element such as a <span> so it can be hidden without changing the button’s width. |
- Buttons are plain elements, so they work in OPEN//77’s CEF pages exactly as on a website.
- Use
aria-busy="true"rather than swapping the label for a spinner; the button keeps its width and the screen reader still announces its name. - The Vue components share this visual spec; see the Vue components for
SbButton.