A Button is used to communicate and perform an action.
<script type="module">
import '@brightspace-ui/core/components/button/button.js';
import '@brightspace-ui/core/components/button/button-subtle.js';
import '@brightspace-ui/core/components/button/button-icon.js';
</script>
<d2l-button>Button</d2l-button>
<d2l-button primary>Primary Button</d2l-button>
<d2l-button-subtle text="Subtle Button" icon="tier1:gear"></d2l-button-subtle>
<d2l-button-icon text="Icon Button" icon="tier1:gear"></d2l-button-icon>Use a Button for most actions, especially if they need to be obvious to the user. For the main action on the page, use the primary attribute to draw the user's attention.
- Use buttons to cause an action or launch a workflow
- Keep
textshort - see "Writing" guidelines
- Don't use multiple Primary buttons - the primary action should always be clear and obvious
- Avoid icon-only buttons with unfamiliar icons, only use these for familiar concepts
- Don't use buttons for navigation, use a link instead
- Don't open menus with buttons - use a dropdown instead
<script type="module">
import '@brightspace-ui/core/components/button/button.js';
</script>
<d2l-button>My Button</d2l-button>| Property | Type | Description |
|---|---|---|
description |
String | A description to be added to the button for accessibility for additional context |
disabled |
Boolean | Disables the button |
disabledTooltip |
String | Tooltip text when disabled |
primary |
Boolean | Styles the button as a primary button |
Use subtle buttons for secondary, advanced, or de-emphasized actions that should not compete with primary tasks.
- Include an icon if you want to draw attention to the action or improve recognition
- Keep subtle button
textshort - see [Writing guidelines]({{ project.assetPath }}/style-elements/writing/)
- Don’t put content in the slot to set the visible label or icon; use
textoriconto ensure styles are maintained - Don’t use subtle buttons for primary or destructive actions — reserve them for less prominent interactions
- Don't use subtle buttons for navigation, use a link instead
- Don't open menus with subtle buttons - use a dropdown instead
<script type="module">
import '@brightspace-ui/core/components/button/button-subtle.js';
</script>
<d2l-button-subtle text="My Button" icon="tier1:gear"></d2l-button-subtle>| Property | Type | Description |
|---|---|---|
text |
String, required | Text for the button |
description |
String | A description to be added to the button for accessibility for additional context |
disabled |
Boolean | Disables the button |
disabledTooltip |
String | Tooltip text when disabled |
h-align |
String | Possible values are undefined (default), text or text-end. If text or text-end, aligns the button content to the leading (or trailing) edge of text. |
icon |
String | Preset icon key (e.g. tier1:gear) |
icon-right |
Boolean | Render the icon on the right of the button |
<script type="module">
import '@brightspace-ui/core/components/button/button-subtle.js';
import '@brightspace-ui/core/components/icons/icon-custom.js';
</script>
<d2l-button-subtle text="Subtle Button">
<d2l-icon-custom slot="icon">
<svg xmlns="http://www.w3.org/2000/svg" mirror-in-rtl="true">
<path fill="#494c4e" d="M18 12v5a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1v-5a1 1 0 0 1 2 0v4h14v-4a1 1 0 0 1 2 0z"/>
<path fill="#494c4e" d="M13.85 3.15l-2.99-3A.507.507 0 0 0 10.5 0H5.4A1.417 1.417 0 0 0 4 1.43v11.14A1.417 1.417 0 0 0 5.4 14h7.2a1.417 1.417 0 0 0 1.4-1.43V3.5a.47.47 0 0 0-.15-.35zM7 2h1a1 1 0 0 1 0 2H7a1 1 0 0 1 0-2zm4 10H7a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2zm0-4H7a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2z"/>
</svg>
</d2l-icon-custom>
</d2l-button-subtle>Use icon buttons for compact, supplementary actions where space is limited and the action is visually represented by a familiar icon.
- Ensure the icon is clear, simple, and universally recognized for its intended action — avoid complex or ambiguous icons
- Don’t use icon-only buttons for critical or primary actions; pair with text if the action is essential or not universally understood
- Don’t use icons that are unfamiliar, decorative, or easily confused with other actions — stick to established conventions
- Don’t overload interfaces with too many icon buttons — maintain a clear hierarchy and avoid visual clutter
- Don't use icon buttons for navigation, use a link instead
- Don't open menus with icon buttons - use a dropdown instead
<script type="module">
import '@brightspace-ui/core/components/button/button-icon.js';
</script>
<d2l-button-icon text="My Button" icon="tier1:gear"></d2l-button-icon>| Property | Type | Description |
|---|---|---|
description |
String | A description to be added to the button for accessibility for additional context |
icon |
String, required | Preset icon key (e.g. tier1:gear) |
text |
String, required | Accessible text for the button |
disabled |
Boolean | Disables the button |
disabledTooltip |
String | Tooltip text when disabled |
h-align |
String | Possible values are undefined (default), text or text-end. If text or text-end, aligns the button content to the leading (or trailing) edge of text. |
translucent |
Boolean | Indicates to display translucent (ex. on rich backgrounds) |
<script type="module">
import '@brightspace-ui/core/components/button/button-icon.js';
import '@brightspace-ui/core/components/icons/icon-custom.js';
</script>
<d2l-button-icon text="Custom Icon Button">
<d2l-icon-custom slot="icon">
<svg xmlns="http://www.w3.org/2000/svg" mirror-in-rtl="true">
<path fill="#494c4e" d="M18 12v5a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1v-5a1 1 0 0 1 2 0v4h14v-4a1 1 0 0 1 2 0z"/>
<path fill="#494c4e" d="M13.85 3.15l-2.99-3A.507.507 0 0 0 10.5 0H5.4A1.417 1.417 0 0 0 4 1.43v11.14A1.417 1.417 0 0 0 5.4 14h7.2a1.417 1.417 0 0 0 1.4-1.43V3.5a.47.47 0 0 0-.15-.35zM7 2h1a1 1 0 0 1 0 2H7a1 1 0 0 1 0-2zm4 10H7a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2zm0-4H7a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2z"/>
</svg>
</d2l-icon-custom>
</d2l-button-icon>Use toggle buttons when users need to easily flip between two opposing states, such as when subscribing or unsubscribing.
The d2l-button-toggle element is a container for buttons that toggle a pressed state. The component will automatically show or hide the buttons and manage focus based on the pressed state. Simply place a d2l-button-icon or d2l-button-subtle element in each of the not-pressed and pressed slots. Each button should describe the state and action the user can take.
- Use when flipping a setting on or off needs to be quick and easy, such as when users are expected to change the setting frequently
- Don’t use toggle buttons for unrelated actions, navigation, or as form inputs — use checkboxes or radio buttons for form selection
- Avoid ambiguous language — users shouldn't have to guess whether the toggle is giving the current state or describing an action it will perform
<script type="module">
import '@brightspace-ui/core/components/button/button-subtle.js';
import '@brightspace-ui/core/components/button/button-toggle.js';
</script>
<d2l-button-toggle pressed>
<d2l-button-subtle slot="not-pressed" icon="tier1:lock-unlock" text="Unlocked" description="Click to lock."></d2l-button-subtle>
<d2l-button-subtle slot="pressed" icon="tier1:lock-locked" text="Locked" description="Click to unlock."></d2l-button-subtle>
</d2l-button-toggle>| Property | Type | Description |
|---|---|---|
pressed |
Boolean | Pressed state |
d2l-button-toggle-change: dispatched when thepressedstate changes
Use a split button when you need to group a main action with a set of closely related alternative actions, especially when space is limited.
The d2l-button-split element provides a main button and a slot for d2l-button-split-item elements. Simply provide a key and text for the main button and each item. The d2l-button-split's click event provides the key of the selected action.
- Make the main action the most common action the user takes, while the related actions are similar but less popular or prominent actions
- For example, a "Save" button with additional options like "Save As" or "Save and Close"
- Keep split button
textshort - see [Writing guidelines]({{ project.assetPath }}/style-elements/writing/)
- Don’t use split buttons for unrelated or mutually exclusive actions
- Don’t use split buttons as a replacement for navigation or for actions that should be separate, standalone buttons
- Avoid including more than 5 actions
- Don’t use split buttons excessively or in groups; reserve them for cases where the pattern adds real value
- Don’t use split buttons if there is enough space to show all actions, since the Split Button requires user interaction to reveal hidden options
<script type="module">
import '@brightspace-ui/core/components/button/button-split.js';
import '@brightspace-ui/core/components/button/button-split-item.js';
</script>
<d2l-button-split key="save" text="Save" primary>
<d2l-button-split-item key="saveAsDraft" text="Save as Draft"></d2l-button-split-item>
<d2l-button-split-item key="saveAndClose" text="Save and Close"></d2l-button-split-item>
<d2l-button-split-item key="saveAndNew" text="Save and New"></d2l-button-split-item>
</d2l-button-split>| Property | Type | Description |
|---|---|---|
description |
String | A description to be added to the main button for accessibility for additional context |
disabled |
Boolean | Disables the main button and menu opener |
disabledTooltip |
String | Tooltip text when disabled |
key |
String, required | Key of the main button, provided on the click event detail |
primary |
Boolean | Styles the main button and menu opener as primary buttons |
text |
String, required | Accessible text for the main button |
| Property | Type | Description |
|---|---|---|
disabled |
Boolean | Disables the menu item |
key |
String, required | Key of the menu item, provided on the click event detail |
text |
String, required | Accessible text for the menu item |
click: dispatched when the user clicks the main action or menu item. Thekeyis provided on the event detail.
Use the Add button when users need to quickly insert new items at specific locations within a curated list or collection.
- Place the button where users expect to add items, such as between list elements or at logical insertion points between page sections
- Don’t use the add button as the only method for adding items — always supplement with a more prominent method (such as a main “Add” button or menu option) since the Add button is subtle and may not be discovered by all users
- Don’t crowd the interface with too many add buttons; use them only where inline addition is helpful and contextually relevant
<script type="module">
import '@brightspace-ui/core/components/button/button-add.js';
</script>
<d2l-button-add></d2l-button-add>| Property | Type | Description |
|---|---|---|
text |
String, required | The text associated with the button. When mode is "icon-and-text", this text is displayed next to the icon. Otherwise this text is in a tooltip. |
mode |
String | Display mode of the component. Defaults to "icon" (plus icon is always visible). Other options are "icon-and-text" (plus icon and text are always visible), and "icon-when-interacted" (plus icon is only visible when hover or focus). |
Use the Copy button to enable users to copy a text value to the clipboard. The d2l-button-copy's click event provides the writeTextToClipboard method for writing the text to the clipboard.
<script type="module">
import '@brightspace-ui/core/components/button/button-copy.js';
document.querySelector('d2l-button-copy').addEventListener('click', e => {
e.detail.writeTextToClipboard(document.querySelector('#to-copy').textContent);
});
</script>
<span id="to-copy">Lorem ipsum dolor sit amet, consectetur adipiscing elit</span>
<d2l-button-copy></d2l-button-copy>| Property | Type | Description |
|---|---|---|
disabled |
Boolean | Disables the button |
Use the Copy button to enable users to copy a text value to the clipboard. The d2l-button-subtle-copy's click event provides the writeTextToClipboard method for writing the text to the clipboard.
<script type="module">
import '@brightspace-ui/core/components/button/button-subtle-copy.js';
document.querySelector('d2l-button-subtle-copy').addEventListener('click', e => {
e.detail.writeTextToClipboard(document.querySelector('#to-copy').textContent);
});
</script>
<span id="to-copy">Lorem ipsum dolor sit amet, consectetur adipiscing elit</span>
<d2l-button-subtle-copy text="Copy text"></d2l-button-subtle-copy>| Property | Type | Description |
|---|---|---|
disabled |
Boolean | Disables the button |
description |
String | A description to be added to the button for accessibility when text on button does not provide enough context |
slim |
Boolean | Makes the button slimmer |
text |
String | Label text for the button |
Floating workflow buttons <d2l-floating-buttons> cause buttons to float or 'dock' to the bottom of the viewport when they would otherwise be below the bottom of the viewport. When their normal position becomes visible, they will undock.
- Use floating workflow buttons to keep important, contextually relevant actions accessible when their normal position would otherwise be out of view
- An example is a long or complex form page where it's common for users to make frequent isolated edits rather than sequentially completing the form
- Limit the number of floating buttons to only the most essential actions to reduce clutter and cognitive load.
- Consider using a Split Button if there are several related actions (such as Save, Save As...)
- Don’t use floating buttons for actions that are not critical or frequently needed; avoid floating buttons for secondary or rarely used actions
<script type="module">
import '@brightspace-ui/core/components/button/floating-buttons.js';
import '@brightspace-ui/core/components/button/button.js';
</script>
<!-- docs: start hidden content -->
<style>
.d2l-typography p {
margin: 0.5rem;
}
.content-placeholder {
align-items: center;
background-color: var(--d2l-color-regolith);
border: 2px dashed lightgrey;
border-radius: 8px;
display: flex;
height: 600px;
justify-content: center;
width: 100%;
}
.empty-space {
height: 5rem;
}
</style>
<!-- docs: end hidden content -->
<div class="content-placeholder d2l-body-compact">
Scroll to unstick
</div>
<d2l-floating-buttons>
<d2l-button primary>Primary</d2l-button>
<d2l-button>Secondary</d2l-button>
</d2l-floating-buttons>
<div class="empty-space"></div>Daylight buttons rely on standard button semantics to ensure a smooth experience for all assistive technologies, but there are a few interesting details to note:
-
If the button's context is implied by visual layout, then
descriptioncan be used to add missing context- Example: if multiple page sections have an Edit button relying on visual layout to indicate which section it edits, there could be extra information in the
descriptionto help differentiate the Edit buttons for non-sighted users
- Example: if multiple page sections have an Edit button relying on visual layout to indicate which section it edits, there could be extra information in the
-
If expanding other content in a dropdown, use the Dropdown component; if building custom expand/collapse behaviour, be sure to use
expandedandaria-haspopupattributes in accordance with best practices. -
Disabled buttons are normally not focusable as per web standards, but if the disabled state needs explaining you can use
disabled-tooltipto provide an explanation that appears in a tooltip via aria-describedby -
For Icon Buttons where there is no visible label,
textwill be displayed in a tooltip- If both
textandaria-labelare used, thenaria-labelwill be used as the primary label whiletextwill be used in a tooltip
- If both
-
Toggle buttons should describe the current state and the action the user can perform. As such,
aria-pressedshould not be used on the buttons as per W3C's Button Pattern.- Example: "Unpinned, click to pin" and "Pinned, click to unpin"
-
Floating Buttons maintain their position in the document's structure, despite sticking to the bottom of the viewport, so the tab order is unaffected and the effect is imperceptible to screen reader users
- Be cautious when using
always-float, since screen magnifier users may find it difficult to locate the buttons at the bottom of a large viewport
- Be cautious when using
<d2l-button-preset type="save">for common button types that will have built-in language support
Looking for an enhancement not listed here? Create a GitHub issue!