Skip to main content
Light Dark System

Button

<sl-button> | SlButton
Since 2.0 stable

Buttons represent actions that are available to the user.

Button
<sl-button>Button</sl-button>
import { SlButton } from '@shoelace-style/shoelace/dist/react';

const App = () => <SlButton>Button</SlButton>;

Examples

Variants

Use the variant attribute to set the button’s variant.

Default Primary Success Neutral Warning Danger
<sl-button variant="default">Default</sl-button>
<sl-button variant="primary">Primary</sl-button>
<sl-button variant="success">Success</sl-button>
<sl-button variant="neutral">Neutral</sl-button>
<sl-button variant="warning">Warning</sl-button>
<sl-button variant="danger">Danger</sl-button>
import { SlButton } from '@shoelace-style/shoelace/dist/react';

const App = () => (
  <>
    <SlButton variant="default">Default</SlButton>
    <SlButton variant="primary">Primary</SlButton>
    <SlButton variant="success">Success</SlButton>
    <SlButton variant="neutral">Neutral</SlButton>
    <SlButton variant="warning">Warning</SlButton>
    <SlButton variant="danger">Danger</SlButton>
  </>
);

Sizes

Use the size attribute to change a button’s size.

Small Medium Large
<sl-button size="small">Small</sl-button>
<sl-button size="medium">Medium</sl-button>
<sl-button size="large">Large</sl-button>
import { SlButton } from '@shoelace-style/shoelace/dist/react';

const App = () => (
  <>
    <SlButton size="small">Small</SlButton>
    <SlButton size="medium">Medium</SlButton>
    <SlButton size="large">Large</SlButton>
  </>
);

Outline Buttons

Use the outline attribute to draw outlined buttons with transparent backgrounds.

Default Primary Success Neutral Warning Danger
<sl-button variant="default" outline>Default</sl-button>
<sl-button variant="primary" outline>Primary</sl-button>
<sl-button variant="success" outline>Success</sl-button>
<sl-button variant="neutral" outline>Neutral</sl-button>
<sl-button variant="warning" outline>Warning</sl-button>
<sl-button variant="danger" outline>Danger</sl-button>
import { SlButton } from '@shoelace-style/shoelace/dist/react';

const App = () => (
  <>
    <SlButton variant="default" outline>
      Default
    </SlButton>
    <SlButton variant="primary" outline>
      Primary
    </SlButton>
    <SlButton variant="success" outline>
      Success
    </SlButton>
    <SlButton variant="neutral" outline>
      Neutral
    </SlButton>
    <SlButton variant="warning" outline>
      Warning
    </SlButton>
    <SlButton variant="danger" outline>
      Danger
    </SlButton>
  </>
);

Pill Buttons

Use the pill attribute to give buttons rounded edges.

Small Medium Large
<sl-button size="small" pill>Small</sl-button>
<sl-button size="medium" pill>Medium</sl-button>
<sl-button size="large" pill>Large</sl-button>
import { SlButton } from '@shoelace-style/shoelace/dist/react';

const App = () => (
  <>
    <SlButton size="small" pill>
      Small
    </SlButton>
    <SlButton size="medium" pill>
      Medium
    </SlButton>
    <SlButton size="large" pill>
      Large
    </SlButton>
  </>
);

Circle Buttons

Use the circle attribute to create circular icon buttons. When this attribute is set, the button expects a single <sl-icon> in the default slot.

<sl-button variant="default" size="small" circle>
  <sl-icon name="gear" label="Settings"></sl-icon>
</sl-button>

<sl-button variant="default" size="medium" circle>
  <sl-icon name="gear" label="Settings"></sl-icon>
</sl-button>

<sl-button variant="default" size="large" circle>
  <sl-icon name="gear" label="Settings"></sl-icon>
</sl-button>
import { SlButton, SlIcon } from '@shoelace-style/shoelace/dist/react';

const App = () => (
  <>
    <SlButton variant="default" size="small" circle>
      <SlIcon name="gear" />
    </SlButton>
    <SlButton variant="default" size="medium" circle>
      <SlIcon name="gear" />
    </SlButton>
    <SlButton variant="default" size="large" circle>
      <SlIcon name="gear" />
    </SlButton>
  </>
);

Text Buttons

Use the text variant to create text buttons that share the same size as regular buttons but don’t have backgrounds or borders.

Text Text Text
<sl-button variant="text" size="small">Text</sl-button>
<sl-button variant="text" size="medium">Text</sl-button>
<sl-button variant="text" size="large">Text</sl-button>
import { SlButton } from '@shoelace-style/shoelace/dist/react';

const App = () => (
  <>
    <SlButton variant="text" size="small">
      Text
    </SlButton>
    <SlButton variant="text" size="medium">
      Text
    </SlButton>
    <SlButton variant="text" size="large">
      Text
    </SlButton>
  </>
);

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.

Link New Window Download Disabled
<sl-button href="https://example.com/">Link</sl-button>
<sl-button href="https://example.com/" target="_blank">New Window</sl-button>
<sl-button href="/assets/images/wordmark.svg" download="shoelace.svg">Download</sl-button>
<sl-button href="https://example.com/" disabled>Disabled</sl-button>
import { SlButton } from '@shoelace-style/shoelace/dist/react';

const App = () => (
  <>
    <SlButton href="https://example.com/">Link</SlButton>
    <SlButton href="https://example.com/" target="_blank">
      New Window
    </SlButton>
    <SlButton href="/assets/images/wordmark.svg" download="shoelace.svg">
      Download
    </SlButton>
    <SlButton href="https://example.com/" disabled>
      Disabled
    </SlButton>
  </>
);

Setting a Custom Width

As expected, buttons can be given a custom width by setting the width attribute. This is useful for making buttons span the full width of their container on smaller screens.

Small Medium Large
<sl-button variant="default" size="small" style="width: 100%; margin-bottom: 1rem;">Small</sl-button>
<sl-button variant="default" size="medium" style="width: 100%; margin-bottom: 1rem;">Medium</sl-button>
<sl-button variant="default" size="large" style="width: 100%;">Large</sl-button>
import { SlButton } from '@shoelace-style/shoelace/dist/react';

const App = () => (
  <>
    <SlButton variant="default" size="small" style={{ width: '100%', marginBottom: '1rem' }}>
      Small
    </SlButton>
    <SlButton variant="default" size="medium" style={{ width: '100%', marginBottom: '1rem' }}>
      Medium
    </SlButton>
    <SlButton variant="default" size="large" style={{ width: '100%' }}>
      Large
    </SlButton>
  </>
);

Prefix and Suffix Icons

Use the prefix and suffix slots to add icons.

Settings Refresh Open

Settings Refresh Open

Settings Refresh Open
<sl-button variant="default" size="small">
  <sl-icon slot="prefix" name="gear"></sl-icon>
  Settings
</sl-button>

<sl-button variant="default" size="small">
  <sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon>
  Refresh
</sl-button>

<sl-button variant="default" size="small">
  <sl-icon slot="prefix" name="link-45deg"></sl-icon>
  <sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon>
  Open
</sl-button>

<br /><br />

<sl-button variant="default">
  <sl-icon slot="prefix" name="gear"></sl-icon>
  Settings
</sl-button>

<sl-button variant="default">
  <sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon>
  Refresh
</sl-button>

<sl-button variant="default">
  <sl-icon slot="prefix" name="link-45deg"></sl-icon>
  <sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon>
  Open
</sl-button>

<br /><br />

<sl-button variant="default" size="large">
  <sl-icon slot="prefix" name="gear"></sl-icon>
  Settings
</sl-button>

<sl-button variant="default" size="large">
  <sl-icon slot="suffix" name="arrow-counterclockwise"></sl-icon>
  Refresh
</sl-button>

<sl-button variant="default" size="large">
  <sl-icon slot="prefix" name="link-45deg"></sl-icon>
  <sl-icon slot="suffix" name="box-arrow-up-right"></sl-icon>
  Open
</sl-button>
import { SlButton, SlIcon } from '@shoelace-style/shoelace/dist/react';

const App = () => (
  <>
    <SlButton variant="default" size="small">
      <SlIcon slot="prefix" name="gear"></SlIcon>
      Settings
    </SlButton>

    <SlButton variant="default" size="small">
      <SlIcon slot="suffix" name="arrow-counterclockwise"></SlIcon>
      Refresh
    </SlButton>

    <SlButton variant="default" size="small">
      <SlIcon slot="prefix" name="link-45deg"></SlIcon>
      <SlIcon slot="suffix" name="box-arrow-up-right"></SlIcon>
      Open
    </SlButton>

    <br />
    <br />

    <SlButton variant="default">
      <SlIcon slot="prefix" name="gear"></SlIcon>
      Settings
    </SlButton>

    <SlButton variant="default">
      <SlIcon slot="suffix" name="arrow-counterclockwise"></SlIcon>
      Refresh
    </SlButton>

    <SlButton variant="default">
      <SlIcon slot="prefix" name="link-45deg"></SlIcon>
      <SlIcon slot="suffix" name="box-arrow-up-right"></SlIcon>
      Open
    </SlButton>

    <br />
    <br />

    <SlButton variant="default" size="large">
      <SlIcon slot="prefix" name="gear"></SlIcon>
      Settings
    </SlButton>

    <SlButton variant="default" size="large">
      <SlIcon slot="suffix" name="arrow-counterclockwise"></SlIcon>
      Refresh
    </SlButton>

    <SlButton variant="default" size="large">
      <SlIcon slot="prefix" name="link-45deg"></SlIcon>
      <SlIcon slot="suffix" name="box-arrow-up-right"></SlIcon>
      Open
    </SlButton>
  </>
);

Caret

Use the caret attribute to add a dropdown indicator when a button will trigger a dropdown, menu, or popover.

Small Medium Large
<sl-button size="small" caret>Small</sl-button>
<sl-button size="medium" caret>Medium</sl-button>
<sl-button size="large" caret>Large</sl-button>
import { SlButton } from '@shoelace-style/shoelace/dist/react';

const App = () => (
  <>
    <SlButton size="small" caret>
      Small
    </SlButton>
    <SlButton size="medium" caret>
      Medium
    </SlButton>
    <SlButton size="large" caret>
      Large
    </SlButton>
  </>
);

Loading

Use the loading attribute to make a button busy. The width will remain the same as before, preventing adjacent elements from moving around. Clicks will be suppressed until the loading state is removed.

Default Primary Success Neutral Warning Danger
<sl-button variant="default" loading>Default</sl-button>
<sl-button variant="primary" loading>Primary</sl-button>
<sl-button variant="success" loading>Success</sl-button>
<sl-button variant="neutral" loading>Neutral</sl-button>
<sl-button variant="warning" loading>Warning</sl-button>
<sl-button variant="danger" loading>Danger</sl-button>
import { SlButton } from '@shoelace-style/shoelace/dist/react';

const App = () => (
  <>
    <SlButton variant="default" loading>
      Default
    </SlButton>
    <SlButton variant="primary" loading>
      Primary
    </SlButton>
    <SlButton variant="success" loading>
      Success
    </SlButton>
    <SlButton variant="neutral" loading>
      Neutral
    </SlButton>
    <SlButton variant="warning" loading>
      Warning
    </SlButton>
    <SlButton variant="danger" loading>
      Danger
    </SlButton>
  </>
);

Disabled

Use the disabled attribute to disable a button. Clicks will be suppressed until the disabled state is removed.

Default Primary Success Neutral Warning Danger
<sl-button variant="default" disabled>Default</sl-button>
<sl-button variant="primary" disabled>Primary</sl-button>
<sl-button variant="success" disabled>Success</sl-button>
<sl-button variant="neutral" disabled>Neutral</sl-button>
<sl-button variant="warning" disabled>Warning</sl-button>
<sl-button variant="danger" disabled>Danger</sl-button>
import { SlButton } from '@shoelace-style/shoelace/dist/react';

const App = () => (
  <>
    <SlButton variant="default" disabled>
      Default
    </SlButton>

    <SlButton variant="primary" disabled>
      Primary
    </SlButton>

    <SlButton variant="success" disabled>
      Success
    </SlButton>

    <SlButton variant="neutral" disabled>
      Neutral
    </SlButton>

    <SlButton variant="warning" disabled>
      Warning
    </SlButton>

    <SlButton variant="danger" disabled>
      Danger
    </SlButton>
  </>
);

Styling Buttons

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. sl-button[variant="primary"]).

Pink Button
<sl-button class="pink">Pink Button</sl-button>

<style>
  sl-button.pink::part(base) {
    /* Set design tokens for height and border width */
    --sl-input-height-medium: 48px;
    --sl-input-border-width: 4px;

    border-radius: 0;
    background-color: #ff1493;
    border-top-color: #ff7ac1;
    border-left-color: #ff7ac1;
    border-bottom-color: #ad005c;
    border-right-color: #ad005c;
    color: white;
    font-size: 1.125rem;
    box-shadow: 0 2px 10px #0002;
    transition: var(--sl-transition-medium) transform ease, var(--sl-transition-medium) border ease;
  }

  sl-button.pink::part(base):hover {
    transform: scale(1.05) rotate(-1deg);
  }

  sl-button.pink::part(base):active {
    border-top-color: #ad005c;
    border-right-color: #ff7ac1;
    border-bottom-color: #ff7ac1;
    border-left-color: #ad005c;
    transform: scale(1.05) rotate(-1deg) translateY(2px);
  }

  sl-button.pink::part(base):focus-visible {
    outline: dashed 2px deeppink;
    outline-offset: 4px;
  }
</style>

Importing

If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.

Script Import Bundler React

To import this component from the CDN using a script tag:

<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.5.2/cdn/components/button/button.component.js"></script>

To import this component from the CDN using a JavaScript import:

import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.5.2/cdn/components/button/button.component.js';

To import this component using a bundler:

import '@shoelace-style/shoelace/dist/components/button/button.component.js';

To import this component as a React component:

import { SlButton } from '@shoelace-style/shoelace/dist/react';

Slots

Name Description
(default) The button’s label.
prefix A presentational prefix icon or similar element.
suffix A presentational suffix icon or similar element.

Learn more about using slots.

Properties

Name Description Reflects Type Default
variant The button’s theme variant. 'default' | 'primary' | 'success' | 'neutral' | 'warning' | 'danger' | 'text' 'default'
size The button’s size. 'small' | 'medium' | 'large' 'medium'
caret Draws the button with a caret. Used to indicate that the button triggers a dropdown menu or similar behavior. boolean false
disabled Disables the button. boolean false
loading Draws the button in a loading state. boolean false
outline Draws an outlined button. boolean false
pill Draws a pill-style button with rounded edges. boolean false
circle Draws a circular icon button. When this attribute is present, the button expects a single <sl-icon> in the default slot. boolean false
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'
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 ''
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 ''
href When set, the underlying button will be rendered as an <a> with this href instead of a <button>. string ''
target Tells the browser where to open the link. Only used when href is present. '_blank' | '_parent' | '_self' | '_top' -
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'
download Tells the browser to download the linked file as this filename. Only used when href is present. string | undefined -
form The “form owner” to associate the button with. If omitted, the closest containing form will be used instead. The value of this attribute must be an id of a form in the same document or shadow root as the button. string -
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 -
validity
Gets the validity state object - -
validationMessage
Gets the validation message - -
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Events

Name React Event Description Event Detail
sl-blur onSlBlur Emitted when the button loses focus. -
sl-focus onSlFocus Emitted when the button gains focus. -
sl-invalid onSlInvalid 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. -
getForm() Gets the associated form, if one exists. -
reportValidity() Checks for validity and shows the browser’s validation message if the control is invalid. -
setCustomValidity() Sets a custom validation message. Pass an empty string to restore validity. message: string

Learn more about methods.

Parts

Name Description
base The component’s base wrapper.
prefix The container that wraps the prefix.
label The button’s label.
suffix The container that wraps the suffix.
caret The button’s caret icon, an <sl-icon> element.

Learn more about customizing CSS parts.

Dependencies

This component automatically imports the following dependencies.

  • <sl-icon>
  • <sl-spinner>