Buttons

Buttons are user interface elements which allows users to take actions throughout the project. It is important that they have ample click space and help communicate the importance of their actions.

Stacks provides 4 different button styles:

  1. Secondary
  2. Primary
  3. Danger
  4. Muted

Each style is explained below, detailing how and where to use these styles.

All buttons, by default, are secondary buttons. There are three, graduating secondary styles:

  1. Clear (default)
  2. Outlined
  3. Filled

A button’s visual weight should correspond to the importance of the button’s action. The more important the action, the heavier the button’s visual weight.

<button class="s-btn" type="button"></button>
<button class="s-btn s-btn__outlined" type="button"></button>
<button class="s-btn s-btn__filled" type="button"></button>
Type Class Default State Selected State Disabled State
Clear
.s-btn
Outlined
.s-btn .s-btn__outlined
Filled
.s-btn .s-btn__filled

A visual style used to highlight the most important actions. To avoid confusing users, don’t use more than one primary button within a section or view.

<button class="s-btn s-btn__primary" type="button"></button>
Type Class Default State Selected State Disabled State
Primary
.s-btn .s-btn__primary

Danger buttons are a secondary button style, used to visually communicate destructive actions such as deleting content, accounts, or canceling services.

<button class="s-btn s-btn__danger" type="button"></button>
<button class="s-btn s-btn__outlined s-btn__danger" type="button"></button>
<button class="s-btn s-btn__filled s-btn__danger" type="button"></button>
Type Class Default State Selected State Disabled State
Clear
.s-btn .s-btn__danger
Outlined
.s-btn .s-btn__danger .s-btn__outlined
Filled
.s-btn .s-btn__danger .s-btn__filled

Muted buttons are a secondary button style, a grayscale visual treatment. Used in layouts for the least important items or currently inactive actions.

<button class="s-btn s-btn__muted" type="button"></button>
<button class="s-btn s-btn__outlined s-btn__muted" type="button"></button>
<button class="s-btn s-btn__filled s-btn__muted" type="button"></button>
Type Class Default State Selected State Disabled State
Clear
.s-btn .s-btn__muted
Outlined
.s-btn .s-btn__muted .s-btn__outlined
Filled
.s-btn .s-btn__muted .s-btn__filled

Any button can have a loading state applied by adding the .is-loading state class.

<button class="s-btn is-loading" type="button"></button>
<button class="s-btn s-btn__outlined is-loading" type="button"></button>
<button class="s-btn s-btn__filled is-loading" type="button"></button>
<button class="s-btn s-btn__primary is-loading" type="button"></button>
Type Class Default State Selected State Disabled State
Primary
.s-btn .s-btn__primary .is-loading
Secondary, Clear
.s-btn .is-loading
Secondary, Outlined
.s-btn .s-btn__outlined .is-loading
Secondary, Filled
.s-btn .s-btn__filled .is-loading
Danger, Clear
.s-btn .s-btn__danger .is-loading
Danger, Outlined
.s-btn .s-btn__danger .s-btn__outlined .is-loading
Danger, Filled
.s-btn .s-btn__danger .s-btn__filled .is-loading
Muted, Clear
.s-btn .s-btn__muted .is-loading
Muted, Outlined
.s-btn .s-btn__muted .s-btn__outlined .is-loading
Muted, Filled
.s-btn .s-btn__muted .s-btn__filled .is-loading

Adding the class .s-btn__dropdown to any button style will add an appropriately-styled caret. These should be paired with a menu or popover.

<button class="s-btn s-btn__dropdown" type="button">Dropdown</button>
Type Class Default State Selected State Disabled State
Primary
.s-btn .s-btn__primary .s-btn__dropdown
Secondary, Clear
.s-btn .s-btn__dropdown
Secondary, Outlined
.s-btn .s-btn__outlined .s-btn__dropdown
Secondary, Filled
.s-btn .s-btn__filled .s-btn__dropdown
Danger, Clear
.s-btn .s-btn__danger .s-btn__dropdown
Danger, Outlined
.s-btn .s-btn__danger .s-btn__outlined .s-btn__dropdown
Danger, Filled
.s-btn .s-btn__danger .s-btn__filled .s-btn__dropdown
Muted, Clear
.s-btn .s-btn__muted .s-btn__dropdown
Muted, Outlined
.s-btn .s-btn__muted .s-btn__outlined .s-btn__dropdown
Muted, Filled
.s-btn .s-btn__muted .s-btn__filled .s-btn__dropdown

Adding an .s-btn--badge to any button will add an appropriately-styled badge.

<button class="s-btn" type="button">
Badge
<span class="s-btn--badge">
<span class="s-btn--number">198</span>
</span>
</button>
Type Class Default State Selected State Disabled State
Primary
.s-btn .s-btn__primary .s-btn--badge
Secondary, Clear
.s-btn .s-btn--badge
Secondary, Outlined
.s-btn .s-btn__outlined .s-btn--badge
Secondary, Filled
.s-btn .s-btn__filled .s-btn--badge
Danger, Clear
.s-btn .s-btn__danger .s-btn--badge
Danger, Outlined
.s-btn .s-btn__danger .s-btn__outlined .s-btn--badge
Danger, Filled
.s-btn .s-btn__danger .s-btn__filled .s-btn--badge
Muted, Clear
.s-btn .s-btn__muted .s-btn--badge
Muted, Outlined
.s-btn .s-btn__muted .s-btn__outlined .s-btn--badge
Muted, Filled
.s-btn .s-btn__muted .s-btn__filled .s-btn--badge

A button’s default font-size is determined by the @body-fs variable. To change the button’s font-size, use the following classes with .s-btn:

Type Class Size Example
Extra Small s-btn__xs 11px
Small s-btn__sm 12px
Default N/A 13px
Medium s-btn__md 17px

Each button class has a selected state which can be visually activated by applying the .is-selected class. When a button can switch between selected and unselected states, it is important to also annotate the button with the aria-pressed attribute for accessibility. A title attribute may also be appropriate to describe what will happen when pressing the button.

<button class="s-btn" type="button" aria-pressed="false" title="…"></button>
<button class="s-btn is-selected" type="button" aria-pressed="true" title="…"></button>

<script>
toggleButton.addEventListener('click', () => {
let wasSelected = toggleButton.getAttribute('aria-pressed') === 'true';
let isSelected = !wasSelected;
toggleButton.classList.toggle('is-selected', isSelected);
toggleButton.setAttribute('aria-pressed', isSelected.toString());

});
</script>

Stacks provides additional classes for cases that are a bit more rare.

Type Class Definition Example
Unset .s-btn__unset Removes all styling from a button including its focus state.
Link .s-btn__link Styles a button element as though it were a link.
Type Class Definition Examples
Icon .s-btn__icon Adds some margin overrides that apply to an icon within a button
Type Class Definition Examples
Facebook .s-btn__facebook Styles a button consistent with Facebook’s branding
Google .s-btn__google Styles a button consistent with Google’s branding
GitHub .s-btn__github Styles a button consistent with GitHub’s branding

To maintain product consistency, buttons should maintain the following layout ordering:

Most button groups should be ordered from the most important to the least important action, left to right.

<button class="s-btn s-btn__primary" type="button">Post answer</button>
<button class="s-btn s-btn__filled" type="button">Save draft</button>
<button class="s-btn s-btn__outlined" type="button">Preview answer</button>
<button class="s-btn" type="button">Cancel</button>

Sometimes the layout dictates that buttons need to be stacked on top of each other. Again, these buttons should be stacked from the most important to the least important, top to bottom.

<div class="d-flex gs4 fd-column">
<button class="flex--item s-btn s-btn__primary" type="button">Post answer</button>
<button class="flex--item s-btn s-btn__filled" type="button">Save draft</button>
<button class="flex--item s-btn s-btn__outlined" type="button">Preview answer</button>
<button class="flex--item s-btn" type="button">Cancel</button>
</div>

Sometimes the best place for a series of actions is in the same area as the title. In these cases, the buttons should be pulled to the right. Within this instance, the button order should be reversed with the most important action to the far right and the least important action to the far left.

<div class="d-flex gs4">
<div class="d-flex ai-center sm:fd-column sm:ai-start">
<h3 class="flex--item mb0 sm:mb16 mr-auto fs-title fw-normal">Write your response</h3>

<div class="d-flex gs4 sm:fd-row-reverse sm:jc-end">
<button class="flex--item s-btn" type="button">Cancel</button>
<button class="flex--item s-btn s-btn__filled" type="button">Preview answer</button>
<button class="flex--item s-btn s-btn__primary" type="button">Post answer</button>
</div>
</div>
</div>

Write your response