- Button
- Examples
- Primary
- Destructive
- Sizes
- Plain buttons
- Outline buttons
- States
- Link buttons
- Full width
- Button with icons
- Disclosure
- Custom styling
- Keyboard support
- Best practices
- Order of actions
- Buttons vs links
- Content guidelines
- Related components
- Importing
- Slots
- Properties
- Events
- Methods
- CSS Parts
- Dependencies
Button
<ahi-button> | AhiButton
Buttons are used primarily for actions, such as “Add”, “Close”, “Cancel”, or “Save”. Plain buttons, which look similar to links, are used for less important or less commonly used actions, such as “view additional details“.
The default form of a button, used for most cases. They are not impactful enough to represent the primary action in a container.
<ahi-button>Default button</ahi-button>
Examples
Primary
Use a primary button to call attention to an action on a form or to highlight the strongest
call to action on a page. Primary buttons should only appear once per container (not including the
application header or in a modal dialog). Not every screen requires a primary button.
<ahi-button variant="primary">Primary button</ahi-button>
Destructive
The destructive button appears as a final confirmation for a destructive action such as
deleting. These are found mostly in confirmation modals.
<ahi-button variant="destructive">Destructive button</ahi-button>
Sizes
Use the size attribute to change a button’s size.
<ahi-button size="small">Small button</ahi-button>
<ahi-button size="medium">Medium button</ahi-button>
<ahi-button size="large">Large button</ahi-button>
Plain buttons
Use plain buttons for less important or less commonly used actions since they’re less
prominent. For example, plain buttons are used as actions in cards.
<ahi-button plain>Plain button</ahi-button>
Outline buttons
Use outline buttons against shaded or colorful backgrounds. An outline button will maintain the
appropriate visual weight and won’t clash with the background color.
<ahi-button outline>Default button</ahi-button>
<ahi-button variant="primary" outline>Primary button</ahi-button>
<ahi-button variant="destructive" outline>Destructive button</ahi-button>
States
Disabled
Use for actions that aren’t currently available. The surrounding interface should make it clear why the button is disabled and what needs to be done to enable it.
<ahi-button variant="primary" disabled>Disabled button</ahi-button>
<ahi-button variant="destructive" disabled>Disabled button</ahi-button>
<ahi-button outline disabled>Disabled button</ahi-button>
<ahi-button plain disabled>Disabled button</ahi-button>
<ahi-button variant="destructive" plain disabled>Disabled button</ahi-button>
Loading
Use when a button has been pressed and the associated action is in progress.
<ahi-button variant="primary" loading>Loading button</ahi-button>
Link buttons
It’s often helpful to have a button that works like a link. This is possible by setting the
href attribute, which will make the component render an <a> under the hood.
This gives you all the default link behavior the browser provides (e.g. CMD/CTRL/SHIFT + CLICK)
and exposes the target and download attributes.
<ahi-button href="https://example.com/" target="_blank">Link button</ahi-button>
When a target is set, the link will receive rel="noreferrer noopener" for
security reasons.
Full width
Use for buttons placed in a narrow column (especially when stacking multiple buttons) or for creating a set of buttons of equal width. Full-width buttons should rarely exceed 320 px wide.
<ahi-button style="width: 100%;">Full width button</ahi-button>
Button with icons
Buttons may include an icon before or after the text. Use the prefix and
suffix slots to add icons.
<!-- Icon before -->
<ahi-button>
<ahi-icon slot="prefix" name="settings" size="minor"></ahi-icon>
Settings
</ahi-button>
<!-- Icon after -->
<ahi-button>
<ahi-icon slot="suffix" name="refresh" size="minor"></ahi-icon>
Refresh
</ahi-button>
Disclosure
Use the disclosure attribute to add a dropdown indicator when a button will trigger a dropdown,
menu, or select.
<div style="display: flex; gap: var(--ahi-space-2)">
<ahi-button disclosure>Dropdown</ahi-button>
<ahi-button disclosure="up">Dropdown</ahi-button>
<ahi-button disclosure="select">Select</ahi-button>
</div>
Custom styling
This example demonstrates how to style buttons using a custom class. This is the recommended approach if you
need to add additional variations. To customize an existing variation, modify the selector to target the
button’s variant attribute instead of a class (e.g.
ahi-button[variant="primary"]).
<ahi-button class="magenta">Button</ahi-button>
<style>
ahi-button.magenta::part(base) {
background: linear-gradient(
15deg,
var(--ahi-brand-navy),
var(--ahi-color-purple-700),
var(--ahi-color-purple-400),
var(--ahi-color-purple-50)
);
border-radius: var(--ahi-border-radius-medium);
}
ahi-button.magenta::part(base):hover {
filter: brightness(90%);
}
ahi-button.magenta::part(base):active {
filter: brightness(75%);
}
ahi-button.magenta::part(label) {
color: var(--ahi-text-on-primary);
font-size: 1.25rem;
}
</style>
Keyboard support
-
Give buttons focus with the
tabkey (orshift+tabwhen tabbing backwards) -
Activate buttons with the
enter/returnkey or thespacekey
Best practices
Buttons should:
- Be clearly and accurately labeled.
- Lead with a strong, actionable verb.
- Use established button colors appropriately. For example, only use a danger button style for an action that’s difficult or impossible to undo.
- Prioritize the most important actions. Too many buttons can cause confusion.
- Be consistent with the positioning of buttons in the interface. See Order of actions.
Order of actions
Rank a row’s actions first: one primary action (variant="primary"), then
secondary actions (the default button), then tertiary actions
(plain). Then put the primary action at the edge the row is aligned to, so people find it in
the same place on every screen.
| Row | Order, left to right | Used for |
|---|---|---|
| End-aligned (right, in left-to-right languages) | Tertiary, secondary, primary | Card footers, dialog footers, popover footers, header actions |
| Start-aligned | Primary, secondary, tertiary | Form buttons that line up with the fields above them, page-level calls to action |
| Centered | Primary, secondary, tertiary | Empty states |
-
Keep the source order the same as the order on screen. Keyboard focus and screen readers follow the
source, so don’t move the primary action with
flex-direction: row-reverseororder. -
When a row stacks into full-width buttons on a narrow screen, put the primary action on top. For an
end-aligned row that takes
flex-direction: column-reverse, the one place the order on screen may differ from the source. - Use one primary action per row.
-
When a row confirms an action that can’t be undone, like Delete in a delete dialog, the
destructivebutton takes the primary position and Cancel is secondary. - Back and Next keep their direction whatever the alignment: Back at the start, Next at the end.
- In a row that spans the full width, a tertiary action such as Clear all can sit alone at the start edge, with the other actions at the end.
A card footer is end-aligned by default:
<ahi-card title="Secure your account with 2-step authentication">
<ahi-card-section>Two-step authentication asks for a code at every sign-in, so only you can get into your account.</ahi-card-section>
<ahi-button slot="footer-actions" plain>Learn more</ahi-button>
<ahi-button slot="footer-actions">Not now</ahi-button>
<ahi-button slot="footer-actions" variant="primary">Turn on</ahi-button>
</ahi-card>
Form buttons line up with the fields above them, so the row is start-aligned:
<div class="ahi-column ahi-gap-4" style="max-width: 24rem">
<ahi-input label="Preferred name"></ahi-input>
<div class="ahi-row ahi-gap-2">
<ahi-button variant="primary">Save</ahi-button>
<ahi-button>Cancel</ahi-button>
</div>
</div>
Buttons vs links
Buttons are used primarily for actions, such as “Add”, “Close”, “Cancel”, or “Save”.
Links are used primarily for navigation, and usually appear within or directly following a sentence.
The HTML that renders for the button component and anchor tags carry meaning.
Using these intentionally and consistently results in:
- a more inclusive experience for assistive technology users
- a more cohesive visual experience for sighted users
- products that are easier to maintain at scale
Content guidelines
- Always write button text in sentence case, which means the first word is capitalized and the rest are lowercase (unless a term is a proper noun).
- Avoid unnecessary words and articles such as “the,” “an,” or “a.”
Related components
- To combine or lay out multiple buttons, use the button group component
-
For navigational actions that appear within or directly following a sentence, use
<a>(anchor) tags.
Importing
To import this component using a script tag:
<script type="module" src="/path/to/azalea-kit-ui/dist/components/button/button.js"></script>
To import this component using a bundler:
import '@azaleahealth/azalea-kit-ui/dist/components/button/button.js';
Slots
| Name | Description |
|---|---|
| (default) | The button’s label. |
prefix
|
Used to prepend an icon or similar element to the button. |
suffix
|
Used to append an icon or similar element to the button. |
Learn more about using slots.
Properties
| Name | Description | Type | Default | |
|---|---|---|---|---|
disabled
|
Disables the button. |
boolean
|
false
|
|
disclosure
|
Draws the button with a disclosure icon. Used to indicate that the button triggers a dropdown menu or similar behavior. |
'up' | 'down' | 'select' | undefined
|
- | |
download
|
Tells the browser to download the linked file as this filename. Only used when href is
present.
|
string | undefined
|
- | |
formAction
formaction
|
Used to override the form owner’s action attribute. |
string
|
- | |
formEnctype
formenctype
|
Used to override the form owner’s enctype attribute. |
'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain'
|
- | |
formMethod
formmethod
|
Used to override the form owner’s method attribute. |
'post' | 'get'
|
- | |
formNoValidate
formnovalidate
|
Used to override the form owner’s novalidate attribute. |
boolean
|
- | |
formTarget
formtarget
|
Used to override the form owner’s target attribute. |
'_self' | '_blank' | '_parent' | '_top' | string
|
- | |
href
|
When set, the underlying button will be rendered as an <a> with this
href instead of a <button>.
|
string
|
''
|
|
loading
|
Replaces button text with a spinner while a background action is being performed. |
boolean
|
false
|
|
name
|
The name of the button, submitted as a name/value pair with form data, but only when this button is
the submitter. This attribute is ignored when
href is present.
|
string
|
''
|
|
outline
|
Draws an outlined button. |
boolean
|
false
|
|
plain
|
Draws a button that looks like a link |
boolean
|
false
|
|
size
|
The button’s size. |
'small' | 'medium' | 'large'
|
'medium'
|
|
target
|
Tells the browser where to open the link. Only used when href is present. |
'_blank' | '_parent' | '_self' | '_top'
|
- | |
type
|
The type of button. Note that the default value is button instead of
submit, which is opposite of how native <button> elements behave.
When the type is submit, the button will submit the surrounding form.
|
'button' | 'submit' | 'reset'
|
'button'
|
|
rel
|
When using href, this attribute will map to the underlying link’s
rel attribute. Unlike regular links, the default is noreferrer noopener to
prevent security exploits. However, if you’re using target to point to a specific
tab/window, this will prevent that from working correctly. You can remove or change the default
value by setting the attribute to an empty string or a value of your choice, respectively.
|
string
|
'noreferrer noopener'
|
|
value
|
The value of the button, submitted as a pair with the button’s name as part of the form data, but
only when this button is the submitter. This attribute is ignored when href is present.
|
string
|
''
|
|
variant
|
The button’s theme variant. |
'default' | 'destructive' | 'primary'
|
'default'
|
|
validity
|
Gets the validity state object | - | - | |
validationMessage
|
Gets the validation message | - | - | |
formId
form
|
By default, form controls are associated with the nearest containing
<form> element. This attribute allows you to place the form control outside of a
form and associate it with the form that has this id. The form must be in the same
document or shadow root for this to work.
|
string
|
''
|
|
form
|
The form the control is associated with, following the native form-control contract: reading returns
the associated <form> element (or null if there is none), assigning
takes a form id — assign an empty string to restore association with the nearest containing form.
|
HTMLFormElement | null
|
- | |
updateComplete |
A read-only promise that resolves when the component has finished updating. |
Learn more about properties and attributes.
Events
| Name | Description | Event Detail |
|---|---|---|
ahi-blur |
Emitted when the button loses focus. | - |
ahi-focus |
Emitted when the button gains focus. | - |
ahi-invalid |
Emitted when the form control has been checked for validity and its constraints aren’t satisfied. | - |
Learn more about events.
Methods
| Name | Description | Arguments |
|---|---|---|
click() |
Simulates a click on the button. | - |
focus() |
Sets focus on the button. |
options: FocusOptions
|
blur() |
Removes focus from the button. | - |
checkValidity() |
Checks for validity but does not show a validation message. Returns true when valid and
false when invalid.
|
- |
reportValidity() |
Checks for validity and shows the browser’s validation message if the control is invalid. | - |
setCustomValidity() |
Sets a custom validation message. If message is not empty, the field will be considered
invalid.
|
message: string
|
resetValidity() |
Hides validity again, returning the control to its pristine state: it stops matching
:user-invalid and drops its error styling until the user next interacts with it. The
value and the validity are both untouched — an empty required control is still invalid and still
blocks submission. This only changes whether that invalidity is shown. Interaction state
otherwise has exactly one automatic exit, form.reset(). Call this when the application
replaces a value itself and the old error no longer describes anything the user did: loading a
draft, switching which record is being edited, or clearing a filter row.
|
- |
Learn more about methods.
CSS Parts
| Name | Description |
|---|---|
base |
Deprecated. Use the button part instead. |
button |
The component’s outer wrapper. |
prefix |
The prefix slot’s container. |
label |
The button’s label. |
suffix |
The suffix slot’s container. |
disclosure |
The button’s disclosure icon, an <ahi-icon> element. |
spinner |
The spinner that shows when the button is in the loading state. |
Learn more about customizing CSS parts.
Dependencies
This component automatically imports the following dependencies.
<ahi-icon><ahi-spinner>