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.
<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).
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.
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.
<dt-button> Place Call </dt-button><dt-buttonimportance="outlined"> Place Call </dt-button><dt-buttonimportance="clear"> Place Call </dt-button>
The danger button style is used to communicate critical or destructive actions such as deleting content, accounts, or canceling services.
<dt-buttonkind="danger"> Place Call </dt-button><dt-buttonkind="danger"importance="outlined"> Place Call </dt-button><dt-buttonkind="danger"importance="clear"> Place Call </dt-button>
The positive button style is used to communicate positive actions.
<dt-buttonkind="positive"> Place Call </dt-button><dt-buttonkind="positive"importance="outlined"> Place Call </dt-button><dt-buttonkind="positive"importance="clear"> Place Call </dt-button>
The inverted button style is used to visually separate buttons set on darker backgrounds.
<dt-buttonkind="inverted"> Place Call </dt-button><dt-buttonkind="inverted"importance="outlined"> Place Call </dt-button><dt-buttonkind="inverted"importance="clear"> Place Call </dt-button>
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.
<dt-buttonkind="muted"importance="clear"> Place Call </dt-button><dt-buttonkind="muted"importance="outlined"> Place Call </dt-button>
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.
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.
The unstyled button removes all default Dialtone styling while preserving the semantic HTML <button> element and maintaining proper button behavior and accessibility.
If you have existing <a class="d-btn"> or <router-link class="d-btn"> workarounds, replace them with DtButton props:
<!-- Before: raw <a> with manual d-btn classes --><aclass="d-btn d-btn--primary d-btn--outlined d-btn--sm"href="<https://example.com>"target="_blank"rel="noopener noreferrer">
Link Text
</a><!-- After: DtButton with href prop --><dt-buttonhref="<https://example.com>"target="_blank"rel="noopener noreferrer"importance="outlined"size="sm">
Link Text
</dt-button>
<!-- Before: raw <router-link> with manual d-btn classes --><router-linkclass="d-btn d-btn--primary d-btn--sm":to="roomPath">
Join Room
</router-link><!-- After: DtButton with to prop --><dt-button:to="roomPath"size="sm">
Join Room
</dt-button>
The default button size is md, but does not need to be explicitly specified.
<dt-buttonsize="xs"> Place Call </dt-button><dt-buttonsize="sm"> Place Call </dt-button><dt-button> Place Call </dt-button><dt-buttonsize="lg"> Place Call </dt-button><dt-buttonsize="xl"> Place Call </dt-button>
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.
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.
The width of the button remains determined by the length of the label, which is visually hidden in this state.
<dt-buttonloading> Place Call </dt-button><dt-buttonv-dt-tooltip="`Tooltip`"loading><template#icon><dt-iconname="phone"size="300"/></template></dt-button><dt-buttonv-dt-tooltip="`Tooltip`"circleloading><template#icon><dt-iconname="phone"size="300"/></template></dt-button><dt-buttonkind="muted"importance="outlined"loading> Place Call </dt-button><dt-buttonkind="muted"importance="outlined"v-dt-tooltip="`Tooltip`"loading><template#icon><dt-iconname="phone"size="300"/></template></dt-button><dt-buttonkind="muted"importance="outlined"v-dt-tooltip="`Tooltip`"circleloading><template#icon><dt-iconname="phone"size="300"/></template></dt-button>
We provide the following branded buttons for log-in and sign-up workflows.
<buttonclass="d-btn d-btn--brand d-btn--google"type="button"><spanclass="d-btn__icon"><icon-google-glyph/></span><spanclass="d-btn__label">Log in with Google</span></button><buttonclass="d-btn d-btn--brand d-btn--o365"type="button"><spanclass="d-btn__icon"><icon-google-glyph/></span><spanclass="d-btn__label">Log in with Office365</span></button><buttonclass="d-btn d-btn--brand d-btn--linkedin"type="button"><spanclass="d-btn__icon"><icon-google-glyph/></span><spanclass="d-btn__label">Log in with LinkedIn</span></button>
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.