<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.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.href or to when button styling is intentional (e.g. CTAs, toolbar actions).Button labels should be clear and predictable so users have confidence in their actions.
Dialtone provides five options for kind, with three levels of importance. Use kind="primary" for the main call to action, kind="critical" 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 Default button colors. | |||
| muted For non-primary actions and contexts where base style may not work. | N/A | ||
| critical Potentially destructive or otherwise critical actions. | |||
| positive Used to communicate positive, confirmatory, or success-related actions. | |||
| inverted Use for placement on non-white, dark backgrounds. | |||
| unstyled Raw button devoid of any style. | N/A | N/A | N/A |
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-button importance="outlined"> Place Call </dt-button> <dt-button importance="clear"> Place Call </dt-button>
The critical button style is used to communicate critical or destructive actions such as deleting content, accounts, or canceling services.
<dt-button kind="critical"> Place Call </dt-button> <dt-button kind="critical" importance="outlined"> Place Call </dt-button> <dt-button kind="critical" importance="clear"> Place Call </dt-button>
The positive button style is used to communicate positive, confirmatory, or success-related actions.
<dt-button kind="positive">Place Call</dt-button> <dt-button kind="positive" importance="outlined">Place Call</dt-button> <dt-button kind="positive" 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-button kind="muted" importance="clear"> Place Call </dt-button> <dt-button kind="muted" importance="outlined"> Place Call </dt-button>
<dt-button disabled {props}>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).
Using the class also requires aria-disabled, and additional javascript implementation is required to prevent events.
<dt-stack gap="100" :direction="{ 'default': 'column', 'md': 'row' }" > <!-- disabled attribute --> <dt-button disabled>Place Call (disabled attribute)</dt-button> <!-- disabled class --> <span v-dt-tooltip="`Tooltip example`" tabindex="0"> <dt-button class="d-btn--disabled" aria-disabled="true" tabindex="-1">Place Call (disabled class)</dt-button> </span> </dt-stack>
Buttons can be set to active state using the active prop or .d-btn--active Dialtone class.
<dt-button importance="clear" active>Place Call</dt-button> <dt-button active>Place Call</dt-button> <dt-button kind="critical" importance="clear" active>Place Call</dt-button> <dt-button kind="positive" importance="clear" active>Place Call</dt-button> <dt-button kind="muted" active>Place Call</dt-button>
Buttons can be styled to match the appearance of a DtLink in situations for which you need the appearance of a link but require the behavior of a button. Using the button element provides a better accessibility experience.
<dt-button link>Place Call</dt-button> <dt-button link linkKind="warning">Place Call</dt-button> <dt-button link linkKind="critical">Place Call</dt-button> <dt-button link linkKind="positive">Place Call</dt-button> <dt-button link linkKind="muted">Place Call</dt-button> <dt-button link disabled>Place Call</dt-button>
This inverts the underline behavior. With underline="false", the link will not have an underline by default, but will show one on hover.
<dt-button link :underline="false">Place Call</dt-button> <dt-button link linkKind="critical" :underline="false">Place Call</dt-button>
The unstyled button removes all default Dialtone styling while preserving the semantic HTML <button> element and maintaining proper button behavior and accessibility.
<dt-button kind="unstyled">Place Call</dt-button>
Use the v-dt-mode directive in place of kind="inverted" on the component element. The previous inverted variant of DtButton was limited to a single presentation style. The directive now makes every combination available as an inverted style.
<dt-button v-dt-mode:invert {props}>Place Call</dt-button>
DtButton can render as an <a> or <router-link> for cases where you need button styling with navigation behavior.
to. Renders <router-link> for client-side navigation without page reloads.href. Renders <a> for standard browser navigation.<button> (default).Pass href to render as an <a> element. Use target="_blank" and rel="noopener noreferrer" for external links.
<dt-button href="https://dialtone.dialpad.com" target="_blank" rel="noopener noreferrer" kind="muted" importance="outlined" :size="200" > <template #endIcon="{ iconSize }"> <dt-icon name="external-link" :size="iconSize" /> </template> Dialtone </dt-button>
Pass to to render as <router-link> for internal client-side SPA navigation. Use replace to navigate without adding a history entry.
<dt-button to="/" kind="default" :size="100"> Home </dt-button>
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 --> <a class="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-button href="<https://example.com>" target="_blank" rel="noopener noreferrer" importance="outlined" :size="200" > Link Text </dt-button>
<!-- Before: raw <router-link> with manual d-btn classes --> <router-link class="d-btn d-btn--primary d-btn--sm" :to="roomPath" > Join Room </router-link> <!-- After: DtButton with to prop --> <dt-button :to="roomPath" :size="200"> Join Room </dt-button>
The default button size is 300, but does not need to be explicitly specified.
<dt-button :size="100" kind="muted" importance="outlined"> Call <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button :size="200" kind="muted" importance="outlined"> Call <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button kind="muted" importance="outlined"> Call <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button :size="400" kind="muted" importance="outlined"> Call <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button :size="500" kind="muted" importance="outlined"> Call <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button>
Place icons before and/or after inline of the label with startIcon and endIcon slots.
<span> <dt-button importance="outlined"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> Label </dt-button> </span> <span> <dt-button importance="outlined"> Label <template #endIcon="{ iconSize }"> <dt-icon name="arrow-right" :size="iconSize" /> </template> </dt-button> </span> <span> <dt-button importance="outlined"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> Label <template #endIcon="{ iconSize }"> <dt-icon name="arrow-right" :size="iconSize" /> </template> </dt-button> </span>
Place icons above or below the label with blockStartIcon and blockEndIcon slots.
<dt-button importance="outlined"> <template #blockStartIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> Label </dt-button> <dt-button importance="outlined"> <template #blockEndIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> Label </dt-button>
Icon-only buttons are commonly used for toggling actions, navigation, or closing UI elements.
<dt-stack direction="row" gap="100"> <dt-button v-dt-tooltip="`Tooltip`" kind="muted" importance="clear"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button v-dt-tooltip="`Tooltip`" kind="muted" importance="outlined"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> </dt-stack> <dt-stack direction="row" gap="100"> <dt-button v-dt-tooltip="`Tooltip`" importance="clear"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button v-dt-tooltip="`Tooltip`" importance="outlined"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button v-dt-tooltip="`Tooltip`"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> </dt-stack> <dt-stack direction="row" gap="100"> <dt-button v-dt-tooltip="`Tooltip`" kind="critical" importance="clear"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button v-dt-tooltip="`Tooltip`" kind="critical" importance="outlined"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button v-dt-tooltip="`Tooltip`" kind="critical"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> </dt-stack> <dt-stack direction="row" gap="100"> <dt-button v-dt-tooltip="`Tooltip`" importance="clear" kind="positive"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button v-dt-tooltip="`Tooltip`" importance="outlined" kind="positive"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button v-dt-tooltip="`Tooltip`" kind="positive"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> </dt-stack>
The following styles are available as a circle shape.
<dt-stack direction="row" gap="100"> <dt-button v-dt-tooltip="`Tooltip`" circle kind="muted" importance="clear"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button v-dt-tooltip="`Tooltip`" circle kind="muted" importance="outlined"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> </dt-stack> <dt-stack direction="row" gap="100"> <dt-button v-dt-tooltip="`Tooltip`" circle kind="critical" importance="clear"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button v-dt-tooltip="`Tooltip`" circle kind="critical" importance="outlined"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button v-dt-tooltip="`Tooltip`" circle kind="critical"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> </dt-stack> <dt-stack direction="row" gap="100"> <dt-button v-dt-tooltip="`Tooltip`" circle importance="clear" kind="positive"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button v-dt-tooltip="`Tooltip`" circle importance="outlined" kind="positive"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> <dt-button v-dt-tooltip="`Tooltip`" circle kind="positive"> <template #startIcon="{ iconSize }"> <dt-icon name="phone" :size="iconSize" /> </template> </dt-button> </dt-stack>
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-button loading> Place Call </dt-button>
<dt-button> Validating <template #endIcon="{ iconSize }"> <dt-loader :size="iconSize" /> </template> </dt-button>
Use the #leading and #trailing slots to render freeform content at the start or end of a button — outside the label area but inside the button's border. Common use cases include badges, count indicators, or keyboard shortcut hints. Use leading-class and trailing-class to add padding or styling to the slot containers.
<dt-button kind="muted" importance="outlined" leading-class="d-pis-150"> Caution <template #leading> <span class="d-bgc-critical-strong d-bar-300 d-w12 d-h12"></span> </template> </dt-button>
<dt-button :size="200" kind="muted" importance="outlined" trailing-class="d-pie-25"> Copy <template #startIcon="{ iconSize }"> <dt-icon name="copy" :size="iconSize" /> </template> <template #trailing> <dt-keyboard-shortcut shortcut="{cmd}+C" /> </template> </dt-button>
We provide the following branded buttons for log-in and sign-up workflows.
<button class="d-btn d-btn--brand d-btn--google d-w100p" type="button"><span class="d-btn__icon"><dt-icon name="google-glyph" /></span><span class="d-btn__label">Log in with Google</span></button> <button class="d-btn d-btn--brand d-btn--o365 d-w100p" type="button"><span class="d-btn__icon"><dt-icon name="office-365" /></span><span class="d-btn__label">Log in with Office365</span></button> <button class="d-btn d-btn--brand d-btn--linkedin d-w100p" type="button"><span class="d-btn__icon"><dt-icon name="linkedin" /></span><span class="d-btn__label">Log in with LinkedIn</span></button>
Enter and Space keys triggers a button, while links are triggered only by the Enter key.Enter or Space key should trigger the action.Tab key moves focus to the next focusable element.Shift+Tab key moves focus to the previous focusable element.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.import { DtButton } from '@dialpad/dialtone-vue';
Name
|
Type
|
|---|---|
blockEndIcon | Icon displayed below the button label (block-end) |
blockStartIcon | Icon displayed above the button label (block-start) |
default | Content within button |
endIcon | Icon displayed at the end (aka right) of the button |
icon | Button icon |
leading | Optional leading content at the start of the button, such as badges or indicators |
startIcon | Icon displayed at the start (aka left) of the button |
trailing | Optional trailing content at the end of the button, such as badges or indicators |
Name
|
Default
|
Type
|
|---|---|---|
active | false |
"true"
|
"false"
Determines whether the button should have active styling
default is false. |
assertiveOnFocus | false |
"true"
|
"false"
Determines whether a screenreader reads live updates of
the button content to the user while the button
is in focus. default is to not. |
blockEndIconClass | '' | string|array|object Used to customize the block-end (aka bottom) icon container |
blockStartIconClass | '' | string|array|object Used to customize the block-start (aka top) icon container |
circle | false |
"true"
|
"false"
Whether the button is a circle or not. Use only with icon-only buttons. |
disabled | false |
"true"
|
"false"
HTML button disabled attribute
(Reference) |
endIconClass | '' | string|array|object Used to customize the end icon container |
href | null | string When provided, renders an |
importance | 'primary' |
"clear"
|
"outlined"
|
"primary"
The fill and outline of the button associated with its visual importance. |
kind | 'default' |
"default"
|
"unstyled"
|
"muted"
|
"critical"
|
"positive"
|
"inverted"
The color of the button.
The inverted value is deprecated and will be removed in the next major version.
Please use the v-dt-mode directive instead. |
labelClass | '' | string|array|object Used to customize the label container |
leadingClass | '' | string|array|object Used to customize the leading container |
link | false |
"true"
|
"false"
Whether the button should be styled as a link or not. |
linkKind | 'default' |
"default"
|
"critical"
|
"warning"
|
"positive"
|
"muted"
|
"info"
|
"mention"
The color of the link and button if the button is styled as a link. |
linkUnderline | true |
"true"
|
"false"
Determines whether the link-styled button should display an underline.
Only applies when the link prop is true. |
loading | false |
"true"
|
"false"
Whether the button should display a loading animation or not. |
rel | null | string HTML anchor rel attribute. Only applied when using the |
replace | false |
"true"
|
"false"
vue-router |
size | 300 |
"100"
|
"200"
|
"300"
|
"400"
|
"500"
The size of the button. |
startIconClass | '' | string|array|object Used to customize the start icon container |
target | null |
"_self"
|
"_blank"
|
"_parent"
|
"_top"
HTML anchor target attribute. Only applied when using the |
to | null | string|object vue-router |
trailingClass | '' | string|array|object Used to customize the trailing container |
type | 'button' |
"button"
|
"submit"
|
"reset"
HTML button type attribute
(Reference) |
width | null | string Button width, accepts
CSS width attribute values |
iconClass Deprecated | '' | string|array|object Used to customize the legacy icon container Use startIconClass or endIconClass |
iconPosition Deprecated | 'start' |
"start"
|
"end"
|
"blockStart"
|
"blockEnd"
|
"left"
|
"right"
|
"top"
|
"bottom"
The position of the icon slot within the button. Use startIcon / endIcon / blockStartIcon / blockEndIcon slots instead. |
linkInverted Deprecated | false |
"true"
|
"false"
Determines whether the link should have inverted styling if the button is styled as a link. Use v-dt-mode instead. |
underline Deprecated | null |
"true"
|
"false"
Use linkUnderline instead. |
Name
|
Type
|
|---|---|
focusin | FocusEvent Native button focus in event |
focusout | FocusEvent Native button focus out event |
Class
|
Applies to
|
Description
|
|---|
Button documentation last updated Friday, September 4, 2026
fix/popover-modal-zindex-scope