Skip to content

QsButton

<qs-button>alpha

A standard button component used to trigger actions and events. Definitely not a <div>.

Button ​

Here describe the action triggeredHere describe the action triggeredHere describe the action triggeredHere describe the action triggeredHere describe the action triggered
html
<qs-button>Here describe the action triggered</qs-button>
<qs-button variant="primary">Here describe the action triggered</qs-button>
<qs-button variant="danger">Here describe the action triggered</qs-button>
<qs-button variant="success">Here describe the action triggered</qs-button>
<qs-button variant="primary" icon="check">Here describe the action triggered</qs-button>

Prop ​

PropTypeDefaultDescription
disabledbooleanfalseWhether or not the button is in a disabled state
hrefstring""Where the button should link to, will also force the component to render as a link.
variant"default" | "primary" | "danger" | "success""default"The style variant of the component.
iconstring""Name of a `qs-icon` to render before the label. Must match a name from the icon set (e.g. `check`, `trash`). Omit for a text-only button.
labelstring""Accessible name for the inner control. Required when the button has no visible text (icon-only); an `aria-label` on the host would not reach it.
type"submit" | "button" | "reset""submit"Native button type. Inside a form, `submit` (the default) submits it; set `button` for any other action, so it doesn't submit by accident. Ignored with `href`.
textstring—The text content of the element, captured from light DOM before the first render.

Usage ​

Use a button to trigger an action or event, such as submitting a form, opening a dialog, or confirming a decision. Use a button with an href to act as a CTA link.

Variants ​

Use variant to communicate the intent of the action.

  • Default — for secondary or low-priority actions
  • Primary — for the single, primary action on a page or in a section; use sparingly
  • Danger — for destructive or irreversible actions, such as deleting or removing
  • Success — for confirming a positive outcome, such as saving or completing

Avoid using multiple primary or danger buttons in close proximity. If everything is high priority, nothing is.


Do: ​

Place primary buttons after default buttons if you need to stack two buttons together:

CancelSave Document

Don’t: ​

Stack primary, danger, or success buttons next to one another

Click meClick me
Do a Good Thing!Do Another Good Thing!

Pass an href to render the button as an anchor element. Use this when the action navigates the user to a new page or location rather than triggering an in-page action.

Get started
html
<qs-button href="/get-started">Get started</qs-button>

Don't use a link-button for actions that don't result in navigation — use a standard button instead.

In a form ​

Like a native <button>, a qs-button inside a form submits it by default. Give every other button in the form type="button":

html
<form>
  <qs-button type="button">Preview</qs-button>
  <qs-button variant="primary">Save</qs-button>
</form>

Icon ​

Pass icon with a name from the icon set to reinforce the action's meaning. The icon is placed before the label and inherits the button's text color.

Save changesAdd itemDelete
html
<qs-button variant="success" icon="check">Save changes</qs-button>
<qs-button variant="primary" icon="plus">Add item</qs-button>
<qs-button variant="danger" icon="trash">Delete</qs-button>
  • Pair icon with a visible label by default — an icon alone is rarely unambiguous, and this component has no dedicated icon-only mode
  • Pick an icon whose meaning is well established (a checkmark for confirm, a trash can for delete) — don't use icon for pure decoration
  • One icon per button; don't combine icon with other leading content
  • If you must ship an icon with no visible label (e.g. a tight toolbar), set label on the <qs-button>: it becomes the inner control's aria-label. An aria-label on the host does not reach the inner <button>. The icon itself is aria-hidden and won't provide a name

Disabled state ​

Use disabled to prevent interaction when an action is temporarily unavailable. Where possible, pair a disabled button with an explanation of why it's unavailable.

html
<qs-button disabled>Unavailable</qs-button>

Avoid using disabled as a default state — if an action is never available in a given context, don't show the button at all.

In a framework ​

Children are the static content of the first render, and their markup (links, <em>, lang spans) is kept. For text that changes, bind Elena's text property instead of rendering a child, as Elena recommends:

html
<!-- React -->  <qs-button text={label} />
<!-- Vue -->    <qs-button :text="label" />
<!-- Angular --><qs-button [text]="label" />

Don't let a framework add or remove individual children inside qs-button: once rendered, they live inside the component's own element.

Accessibility ​

  • Button text should clearly describe the action it triggers — avoid vague labels like "Click here" or "Submit"
  • When using icon, keep the slotted text present; if you must omit it, set label on the <qs-button> instead
  • If you need to construct more complex accessibilityName use ariaLabelledby to reference other elements on the page or ariaDescribedby to provide additional context
  • Disabled buttons are not focusable by default; consider whether users need to know why the action is unavailable before removing it from the tab order