Toggle button

A toggle button is a button that changes its state between "on" and "off" using an icon to represent its current state.

UsageCodeAccessibility
  <sl-toggle-button fill="outline">
    <sl-icon name="far-gear" slot="default"></sl-icon>
    <sl-icon name="fas-gear" slot="pressed"></sl-icon>
  </sl-toggle-button>

When to use

Familiar Actions and UI Element Toggles

Icon-only toggle buttons are ideal for actions that are easily recognizable by users through common icons, such as play/pause, like/unlike, or expand/collapse. These buttons are commonly used in toolbars and media controls where space is limited and quick access to functionalities like muting audio or changing playback states is necessary. They are also useful for toggling UI elements on or off, such as expanding or collapsing a drawer, showing or hiding a menu, or turning a feature on or off within the application interface.

When not to use

Toggling Features or Settings

Users typically expect to see switches when enabling or disabling features. If you use an icon-only button instead, it can confuse users and disrupt the uniformity of the interface. So, in these situations, always opt for a switch component. It provides a clear, intuitive way for users to understand the state of a feature.

Anatomy

ItemNameDescriptionOptional
1ContainerTHTML button elementno
2IconThe outline icon appears in the default state, while the filled icon is displayed when the toggle button is selectedno
3TooltipThe tooltip appears on hover to provide additional information about the toggle button's actionno

Figma Options

With these options, you can tweak the appearance of the toggle button in Figma. They are available in the Design Panel so you can compose the switch to exactly fit the user experience need for the use case you are working on.

ItemOptionsDescription
Typeoutline ghostTo indicate the type of the toggle button
Stateidle hover active DisabledTo indicate the state of the toggle button
Sizesm md lgTo determine the size of the toggle button
SelectedbooleanTo indicate whether the toggle is selected or not
FontAwesomevalueTo specify the name of the Font Awesome icon you wish to use in the toggle button.
<sl-toggle-button>
  <sl-icon name="far-gear" slot="default"></sl-icon>
  <sl-icon name="fas-gear" slot="pressed"></sl-icon>
</sl-toggle-button>

<sl-toggle-button fill="outline" pressed>
  <sl-icon name="far-gear" slot="default"></sl-icon>
  <sl-icon name="fas-gear" slot="pressed"></sl-icon>
</sl-toggle-button>

API

Component has a range of properties to define the experience in different use cases.

Properties

NameAttributeTypeDefaultDescription
disableddisabledboolean | undefinedWhether the button is disabled; when set no interaction is possible.
fillfill'ghost' | 'outline' | undefinedThe variant of the toggle-button.
pressedpressedbooleanfalseThe pressed state of the button. Set the default value, so the
`aria-pressed` attribute is added to the element.
sizesize'md' | 'lg' | undefinedThe size of the button.

Events

NameEvent typeDescription
sl-toggleSlToggleEvent<boolean>Emits when the button has been toggled.

Slots

NameDescription
defaultThe icon shown in the default state of the button
pressedThe icon shown in the pressed state of the button

Keyboard Interaction

When the toggle button has focus:

  • Space: Activates the toggle button.
  • Enter: Activates the toggle button.
  • Following button activation, the focus is set depending on the type of action the button performs. For example:
    • If activating the toggle button opens a drawer, the focus moves inside the drawer.

Labeling

Assistive technology adds the term pressed to label of the button to indicate the status of the button. Therefore the aria-label you choose needs to make sense in combination with this term and certainly not change when the state changes.

If you have a toggle button that toggles a sidepanel you could choose "Show sidepanel" as a label. When a screenreader reads out "Show sidepanel. Toggle button." it is clear this button button can be toggled and is currently off and the sidepanel will not be visible. When the button is then pressed it will read out "Selected. Show sidepanel. Toggle button." indicating that "Show sidepanel" is now on and the side panel is visible.

Switching the label to what will happen when the button is pressed, ie. "Hide sidepanel" is wrong because it will confuse the user; it wil read "Selected. Hide sidepanel. Toggle button", meaning that "Hide sidepanel" is on, so not showing the sidepanel, while in fact it is shown.

WAI-ARIA

WAI-ARIA Roles, States, and Properties for a toggle button provide essential information to assistive technologies and screen readers. They convey the toggle button's role, state (enabled or disabled), and additional properties to ensure accessibility and a better user experience for individuals using assistive technology.

AttributeValueDescriptionUser suppliedSpecifies whether the attribute is always set in the component (no) or it needs to be provided by the developer (yes)
rolebuttonMakes it clear that our custom component has the same behavior as a button.no
aria-pressedbooleanMakes it clear it is a toggle button and not a regular button, and shows the state of the button true for on and false for offno
aria-labelstringUsed when the describe the function of the button because it is icon-onlyyes
aria-disabledbooleanAnnounces the toggle button as disabled with a screenreader. See [Note 1] below for more explanationyes

Notes:

  1. The aria-disabled should not be used as a one-for-one replacement for the disabled attribute because they have different functionalities:

    • disabled dims the button visually, takes it out of the tab-focus sequence, prevents actions (click, enter) on it and anounces it as 'dimmed' or 'disabled' in a screenreader.

    • aria-disabled only does the latter. You will need to disable the functionality yourself. This might be useful for scenario's where you don't want to take the button out of the navigation flow.

    When disabled is added to a button there is no need to also add aria-disabled; Everything aria-disabled does, disabled does as well.

    You can read more on the difference and in which scenarios which option might be preferable on the MDN page about aria-disabled

Interactive example