A button is an UI element which signals key actions to take an action throughout an app. It is important a button is identifiable, consistent, communicates its actions clearly, and is appropriately sized to its action.

Preview

Usage

  • <button> and link (<a>) HTML elements each describe a specific intent. Understanding the distinction is important: if it goes somewhere, it's a link (<a>). If an action occurs, use a Button (<button>). When you need button styling with navigation behavior (CTAs, toolbar actions that navigate), use DtButton's href or to props — see Navigation.
  • Avoid using too many buttons on a page.
  • Set the type attribute to define its purpose: submit, button, or reset. Browsers default to submit if it isn't defined, and that cannot be assumed as the preferred behavior.

Do

  • Conveying that an action that will occur when invoked.
  • To trigger an action or behavior, such as submitting a form or spawning a Modal.

Don’t

  • Avoid using to navigate between destinations, deferring to a Link instead. Exception: use DtButton with href or to when button styling is intentional (e.g. CTAs, toolbar actions).

Writing Guidelines

Button labels should be clear and predictable so users have confidence in their actions.

  • Lead with a strong verb and use verb + noun structure except for common actions like “Done,” “Close,” “Cancel,” or “OK”
  • Should be sentence case
  • Do not use punctuation
  • Avoid unnecessary articles such as “the,” “an,” and “a.”

Do

  • Add number
  • Create menu

Don’t

  • Add Number
  • Create a menu

Variants

Dialtone provides five options for kind, with three levels of importance. Use kind="primary" for the main call to action, kind="danger" for destructive actions, kind="muted" for secondary actions, kind="clear" for low-emphasis actions, and kind="link" for navigation-style buttons. The DtButton kind prop controls the visual hierarchy and semantic meaning of the action.

clear
Default level of importance. Typically used for secondary or minimally important actions.
outlined
Slightly more important than clear, presenting a contrasting border and transparent background.
primary
Highest level of importance, presenting a solid background color.
default
Our default button colors.
muted
For non-primary actions and contexts where base style may not work.
N/A
danger
Potentially destructive or otherwise critical actions.
positive
Used to communicate positive actions.
inverted
Use for placement on non-white, dark backgrounds.
unstyled
Raw button devoid of any style.
N/AN/AN/A

Default

The base button should be the go-to button for most of your needs. When in doubt, use this style. To help provide clarity to users, it is generally recommended to use only one primary button style within a section or page.

Danger

The danger button style is used to communicate critical or destructive actions such as deleting content, accounts, or canceling services.

Positive

The positive button style is used to communicate positive actions.

Inverted

The inverted button style is used to visually separate buttons set on darker backgrounds.

Muted

The muted button style is used to communicate non-primary actions for contexts in which the base style may not work (e.g. colored backgrounds, validation components, etc). This style’s use should be rare. When in doubt, use the default button style.

Disabled

Buttons can be disabled using the disabled attribute or the Dialtone class, d-btn--disabled. Use the attribute when a button should appear disabled and not receive focus; use the class when a button should appear disabled but still receive focus (i.e. a disabled button with a tooltip).

When using the raw HTML instead of the Vue component , it requires aria-disabled, and additional javascript implementation is required to prevent events.

Active

Buttons can be set to active state using the active prop or .d-btn--active Dialtone class.

Buttons can be styled as a Link in situations for which you need the appearance of a link but behavior of a button. Using the button element provides a better accessibility experience.

Unstyled

The unstyled button removes all default Dialtone styling while preserving the semantic HTML <button> element and maintaining proper button behavior and accessibility.

DtButton can render as an <a> or <router-link> for cases where you need button styling with navigation behavior.

  • Navigating within the app? Use to. Renders <router-link> for client-side navigation without page reloads.
  • Linking to an external site? Use href. Renders <a> for standard browser navigation.
  • Triggering an action? Use neither. Renders <button> (default).

href

Pass href to render as an <a> element. Use target="_blank" and rel="noopener noreferrer" for external links.

to

Pass to to render as <router-link> for internal client-side SPA navigation. Use replace to navigate without adding a history entry.

Migration

If you have existing <a class="d-btn"> or <router-link class="d-btn"> workarounds, replace them with DtButton props:

Split Button

The Split Button is its own component containing multiple buttons.

Sizes

The default button size is md, but does not need to be explicitly specified.

Icon Support

Icon and Label

Button labels can include an icon next to the text. Every button style can accept icon classes, though we only provide a few possible examples. icon-position can be left (default), right, top, bottom.

Icon Only

Icon-only buttons are commonly used for toggling actions, navigation, or closing UI elements.

Circle

The following styles are available as a circle shape.

Loading

Loading buttons are useful for communicating a delay between the button interaction and its action taking place. Every button style can accept the loading button class, though we only provide a few possible examples. When loading is true, DtButton replaces the label with a spinner animation, indicating an async operation (such as form submit) is in progress. The spinner is centered within the button and the button remains disabled until loading is false.

Replace button label

The width of the button remains determined by the length of the label, which is visually hidden in this state.

With label

Branded

We provide the following branded buttons for log-in and sign-up workflows.

<button class="d-btn d-btn--brand d-btn--google" type="button">
  <span class="d-btn__icon"><icon-google-glyph /></span>
  <span class="d-btn__label">Log in with Google</span>
</button>
<button class="d-btn d-btn--brand d-btn--o365" type="button">
  <span class="d-btn__icon"><icon-google-glyph /></span>
  <span class="d-btn__label">Log in with Office365</span>
</button>
<button class="d-btn d-btn--brand d-btn--linkedin" type="button">
  <span class="d-btn__icon"><icon-google-glyph /></span>
  <span class="d-btn__label">Log in with LinkedIn</span>
</button>

Vue API

Slots

Name
Description
default

Content within button

icon

Button icon

Props

Name
Description
Default
active

Determines whether the button should have active styling default is false.

Type: boolean
Values: truefalse
false
assertiveOnFocus

Determines whether a screenreader reads live updates of the button content to the user while the button is in focus. default is to not.

Type: boolean
Values: truefalse
false
circle

Whether the button is a circle or not.

Type: boolean
Values: truefalse
false
disabled

HTML button disabled attribute (Reference)

Type: boolean
Values: truefalse
false
href

When provided, renders an <a> element for standard browser navigation.

Type: string
null
iconPosition

The position of the icon slot within the button.

Type: string
Values: leftrighttopbottom
'left'
importance

The fill and outline of the button associated with its visual importance.

Type: string
Values: clearoutlinedprimary
'primary'
kind

The color of the button.

Type: string
Values: defaultunstyledmuteddangerpositiveinverted
'default'
labelClass

Used to customize the label container

Type: string|array|object
''
link

Whether the button should be styled as a link or not.

Type: boolean
Values: truefalse
false
linkInverted

Determines whether the link should have inverted styling if the button is styled as a link.

Type: boolean
Values: truefalse
false
linkKind

The color of the link and button if the button is styled as a link.

Type: string
Values: defaultwarningdangersuccessmuted
'default'
loading

Whether the button should display a loading animation or not.

Type: boolean
Values: truefalse
false
rel

HTML anchor rel attribute. Only applied when using the href prop.

Type: string
null
replace

vue-router replace prop. When true, navigation will not leave a history entry. Only applied when using the to prop.

Type: boolean
Values: truefalse
false
size

The size of the button.

Type: string
Values: xssmmdlgxl
'md'
target

HTML anchor target attribute. Only applied when using the href prop.

Type: string
Values: _self_blank_parent_top
null
to

vue-router to prop. When provided, renders a <router -link> for client-side SPA navigation.

Type: string|object
null
type

HTML button type attribute (Reference)

Type: string
Values: buttonsubmitreset
'button'
width

Button width, accepts CSS width attribute values

Type: string
null

Events

Name
Description
focusin

Native button focus in event

Type: FocusEvent
focusout

Native button focus out event

Type: FocusEvent

Accessibility

  • Choosing between Link and Button elements is paramount for screenreaders to inform the user what will occur. For example: will it go somewhere (Link) or will something happen (Button)?
  • Do not rely on color alone to convey the intent of the button. Defer to the button text as primary way to convey the buttons intent.
  • Display a visible focus state when users tab to them.
  • Use standard semantic usage of HTML elements.
  • Be aware of how screenreaders handle buttons and links differently. For example, both the Enter and Space keys triggers a button, while links are triggered only by the Enter key.
  • If it is a button type while focused:
    • Pressing the Enter or Space key should trigger the action.
    • Pressing the Tab key moves focus to the next focusable element.
    • Pressing the Shift+Tab key moves focus to the previous focusable element.
  • When using DtButton with href or to, the component automatically handles Spacebar activation and disabled state (aria-disabled, tabindex="-1"). Navigating elements keep their native link role — role="button" is not added because the element navigates rather than performing an in-page action.

Classes

Class
Applies to
Description
Button documentation last updated Thursday, June 11, 2026