Overlays
.sb-dialog
Section titled “.sb-dialog”sb-dialog styles a native <dialog>. Open it modally with dialog.showModal(): the browser puts it in the top layer, draws the ::backdrop, traps focus, closes on Escape and returns focus to the opener. dialog.show() opens it non-modally, inline.
The demos on this page use one delegated script: data-open="#id" on a button calls showModal(), and data-close on a button inside the dialog calls close().
<div class="sb-cluster"> <button type="button" class="sb-btn" data-open="#dlg-md">Open dialog</button> <button type="button" class="sb-btn sb-btn-soft sb-btn-danger" data-open="#dlg-danger">Danger dialog</button> <button type="button" class="sb-btn sb-btn-outline sb-btn-secondary" data-open="#dlg-lg">Large, scrolling</button> <button type="button" class="sb-btn sb-btn-outline sb-btn-secondary" data-open="#drw-right">Drawer right</button> <button type="button" class="sb-btn sb-btn-outline sb-btn-secondary" data-open="#drw-bottom">Drawer bottom</button></div><dialog class="sb-dialog sb-dialog-md" id="dlg-md" aria-labelledby="dlg-md-title"> <header class="sb-dialog-header"> <p class="sb-dialog-eyebrow">Confirm transfer</p> <h2 class="sb-dialog-title" id="dlg-md-title">Send 8,750 eddies to Regina?</h2> <p class="sb-dialog-description">The transfer settles immediately and cannot be reversed.</p> <button type="button" class="sb-dialog-close" data-close aria-label="Close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg></button> </header> <div class="sb-dialog-body"> <p>The body scrolls on its own when it overflows. Header, body and footer are optional parts.</p> </div> <footer class="sb-dialog-footer"> <span class="sb-dialog-footer-start sb-text-subtle">Balance: 46,350</span> <button type="button" class="sb-btn sb-btn-ghost sb-btn-neutral" data-close>Cancel</button> <button type="button" class="sb-btn" data-close>Send</button> </footer></dialog><dialog class="sb-dialog sb-dialog-sm sb-dialog-danger" id="dlg-danger" aria-labelledby="dlg-danger-title"> <header class="sb-dialog-header"> <h2 class="sb-dialog-title" id="dlg-danger-title">Delete save slot?</h2> <p class="sb-dialog-description">The top hairline turns danger for destructive flows.</p> </header> <footer class="sb-dialog-footer"> <button type="button" class="sb-btn sb-btn-ghost sb-btn-neutral" data-close autofocus>Keep</button> <button type="button" class="sb-btn sb-btn-danger" data-close>Delete</button> </footer></dialog><dialog class="sb-dialog sb-dialog-lg" id="dlg-lg" aria-labelledby="dlg-lg-title"> <header class="sb-dialog-header"> <h2 class="sb-dialog-title" id="dlg-lg-title">Large dialog</h2> <button type="button" class="sb-dialog-close" data-close aria-label="Close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg></button> </header> <div class="sb-dialog-body"> <p>Paragraph one of a long body.</p><p>Paragraph two.</p><p>Paragraph three.</p><p>Paragraph four.</p><p>Paragraph five.</p><p>Paragraph six.</p><p>Paragraph seven.</p><p>Paragraph eight.</p><p>Paragraph nine.</p><p>Paragraph ten.</p><p>Paragraph eleven.</p><p>Paragraph twelve.</p><p>Paragraph thirteen.</p><p>Paragraph fourteen.</p><p>Paragraph fifteen.</p> </div> <footer class="sb-dialog-footer"><button type="button" class="sb-btn" data-close>Done</button></footer></dialog><dialog class="sb-dialog sb-dialog-drawer" id="drw-right" aria-labelledby="drw-right-title"> <header class="sb-dialog-header"> <p class="sb-dialog-eyebrow">Inventory</p> <h2 class="sb-dialog-title" id="drw-right-title">Right drawer</h2> <button type="button" class="sb-dialog-close" data-close aria-label="Close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg></button> </header> <div class="sb-dialog-body"><p>Slides in from the inline-end edge.</p></div> <footer class="sb-dialog-footer"><button type="button" class="sb-btn" data-close>Done</button></footer></dialog><dialog class="sb-dialog sb-dialog-drawer sb-dialog-drawer-bottom" id="drw-bottom" aria-labelledby="drw-bottom-title"> <header class="sb-dialog-header"> <h2 class="sb-dialog-title" id="drw-bottom-title">Bottom sheet</h2> <button type="button" class="sb-dialog-close" data-close aria-label="Close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg></button> </header> <div class="sb-dialog-body">Rounded top corners.</div></dialog>// Native behaviors for the plain-HTML component demos. The CSS classes need none of this; it only// wires the platform features the markup relies on.export function bindNativeBehaviors() { document.addEventListener('click', (event) => { const target = event.target if (!(target instanceof Element)) return
// [data-open="#id"] opens a modal <dialog>; [data-close] closes the dialog it sits in. const opener = target.closest('[data-open]') if (opener) { const dialog = document.querySelector(opener.getAttribute('data-open')) if (dialog instanceof HTMLDialogElement && !dialog.open) dialog.showModal() return } const closer = target.closest('[data-close]') if (closer) closer.closest('dialog')?.close() })
// Tab lists: click and arrow keys move selection (roving tabindex), Home and End jump. for (const tabs of document.querySelectorAll('[data-tabs]')) { const list = tabs.querySelector('[role="tablist"]') if (!list) continue const vertical = list.getAttribute('aria-orientation') === 'vertical' const enabledTabs = () => [...list.querySelectorAll('[role="tab"]:not(:disabled)')]
const select = (tab, focus) => { for (const item of list.querySelectorAll('[role="tab"]')) { const selected = item === tab item.setAttribute('aria-selected', String(selected)) item.tabIndex = selected ? 0 : -1 const panel = document.getElementById(item.getAttribute('aria-controls')) if (panel) panel.hidden = !selected } if (focus) tab.focus() }
list.addEventListener('click', (event) => { const tab = event.target instanceof Element ? event.target.closest('[role="tab"]') : null if (tab && !tab.disabled) select(tab, false) })
list.addEventListener('keydown', (event) => { const all = enabledTabs() const index = all.indexOf(document.activeElement) if (index < 0) return const previousKey = vertical ? 'ArrowUp' : 'ArrowLeft' const nextKey = vertical ? 'ArrowDown' : 'ArrowRight' let target if (event.key === nextKey) target = all[(index + 1) % all.length] else if (event.key === previousKey) target = all[(index - 1 + all.length) % all.length] else if (event.key === 'Home') target = all[0] else if (event.key === 'End') target = all[all.length - 1] if (!target) return event.preventDefault() select(target, true) }) }
// The indeterminate state of a checkbox has no attribute; it is a DOM property. for (const box of document.querySelectorAll('[data-indeterminate]')) box.indeterminate = true}Always name the dialog with aria-labelledby (pointing at the title) or aria-label. Put autofocus on the safest control of a destructive dialog, as the danger example does.
| Class | Effect |
|---|---|
sb-dialog |
The panel (medium by default): canvas fill, hairline, radius xl, a gradient bloom hairline on top, enter animation. |
sb-dialog-sm, -md, -lg, -xl, -full |
Width 24rem, 32rem (default), 48rem and 64rem, and full-viewport with no radius. |
sb-dialog-header |
Header part. |
sb-dialog-eyebrow |
Small uppercase caption above the title. |
sb-dialog-title |
Title; use a heading element. |
sb-dialog-description |
Supporting text under the title. |
sb-dialog-close |
Close button in the header corner; needs an aria-label. |
sb-dialog-body |
Scrolling content area. |
sb-dialog-footer |
Action row, pinned to the bottom. |
sb-dialog-footer-start |
Pushes a footer item to the start (for a note beside the actions). |
sb-dialog-danger |
The top hairline turns danger, for destructive flows. |
sb-dialog-drawer |
Slides in from a viewport edge (inline-end by default). |
sb-dialog-drawer-left, -top, -bottom |
Edge for a drawer. |
[open] |
The visible state; the enter animation plays when it is set. |
::backdrop |
Dimmed, blurred scrim using --sb-backdrop. |
.sb-popover
Section titled “.sb-popover”sb-popover styles an element with the popover attribute. The Popover API gives you toggling with popovertarget, light dismiss (click outside, Escape) and top-layer stacking with no script. popovertargetaction="hide" on a button inside closes it.
The browser centers an unpositioned popover in the viewport, so these demos open in the middle of the window. In a real UI, position it with CSS anchor positioning or a library such as Floating UI.
Netrunner build
Intelligence 20, Cool 15
Panel fill, hairline border and the overlay shadow.
Large popover
<div class="sb-cluster"> <button type="button" class="sb-btn sb-btn-soft" popovertarget="pop-md">Popover</button> <button type="button" class="sb-btn sb-btn-soft" popovertarget="pop-sm">Small</button> <button type="button" class="sb-btn sb-btn-soft" popovertarget="pop-lg">Large</button> <button type="button" class="sb-btn sb-btn-soft" popovertarget="pop-glass">Glass</button></div><div id="pop-md" popover class="sb-popover"> <header class="sb-popover-header"> <h3 class="sb-popover-title">Netrunner build</h3> <p class="sb-popover-description">Intelligence 20, Cool 15</p> </header> <button type="button" class="sb-popover-close" popovertarget="pop-md" popovertargetaction="hide" aria-label="Close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" width="14" height="14"><path d="M6 6l12 12M18 6L6 18"/></svg></button> <div class="sb-popover-body"><p>Panel fill, hairline border and the overlay shadow.</p></div> <footer class="sb-popover-footer"> <button type="button" class="sb-btn sb-btn-ghost sb-btn-neutral sb-btn-sm" popovertarget="pop-md" popovertargetaction="hide">Close</button> <button type="button" class="sb-btn sb-btn-sm">Equip</button> </footer></div><div id="pop-sm" popover class="sb-popover sb-popover-sm">Small popover: 12rem wide.</div><div id="pop-lg" popover class="sb-popover sb-popover-lg"> <header class="sb-popover-header"><h3 class="sb-popover-title">Large popover</h3></header> <div class="sb-popover-body">22rem minimum width.</div></div><div id="pop-glass" popover class="sb-popover sb-popover-glass">Glass popover for HUD overlays over game imagery.</div>| Class | Effect |
|---|---|
sb-popover |
Panel fill, hairline, radius md, overlay shadow, enter animation on :popover-open. |
sb-popover-sm, -md, -lg |
Width presets: 12rem, 16rem (default) and 22rem (up to 32rem). |
sb-popover-glass |
Glass fill for HUD overlays over game imagery. |
sb-popover-header, -title, -description |
Header, title (use a heading) and supporting text. |
sb-popover-body, -footer |
Content and action row. |
sb-popover-close |
Corner close button; needs an aria-label. |
sb-popover-arrow |
An 8px rotated square for a pointer; position it yourself. |
[popover] |
Hidden until open. |
:popover-open |
Open state: enter animation. |
[data-state="open"], [data-state="closed"] |
Enter and leave motion for a popover positioned by script (no popover attribute). |
[data-side="top"], "left", "right" |
Motion direction and arrow side for a script-positioned popover. |
sb-popover also works as a plain box with no popover attribute, driven by data-state and data-side, which is how a positioning library renders it:
<div class="sb-cluster sb-cluster-6"> <div class="sb-popover sb-popover-sm" data-state="open" data-side="bottom">data-state="open"</div> <div class="sb-popover sb-popover-sm" data-side="top" style="position: relative"> data-side="top" with an arrow <span class="sb-popover-arrow" style="bottom: -0.3rem; left: 50%; translate: -50% 0"></span> </div></div>.sb-menu
Section titled “.sb-menu”sb-menu is a list of actions. It works as a static block (sidebars, menus a script renders) or as a Popover API element. A menu is a command surface, so give it role="menu" and its items role="menuitem", menuitemcheckbox or menuitemradio.
A popover menu opens and dismisses natively. The arrow-key navigation, typeahead and focus management of the menu pattern are not provided by HTML; use the Vue SbDropdownMenu family when you need them.
<button type="button" class="sb-btn sb-btn-secondary" popovertarget="menu-pop" aria-haspopup="menu">Open menu</button><div id="menu-pop" popover class="sb-menu" role="menu" aria-label="Actions"> <div class="sb-menu-label">Job</div> <button type="button" class="sb-menu-item" role="menuitem"><span class="sb-menu-item-text">Accept</span><span class="sb-menu-shortcut">Enter</span></button> <button type="button" class="sb-menu-item" role="menuitem"><span class="sb-menu-item-text">Track on map</span><span class="sb-menu-shortcut">T</span></button> <div class="sb-menu-separator" role="separator"></div> <button type="button" class="sb-menu-item" role="menuitemcheckbox" aria-checked="true"><span class="sb-menu-item-text">Notify on update</span></button> <button type="button" class="sb-menu-item" role="menuitemcheckbox" aria-checked="false"><span class="sb-menu-item-text">Pin</span></button> <div class="sb-menu-separator" role="separator"></div> <button type="button" class="sb-menu-item sb-menu-item-danger" role="menuitem"><span class="sb-menu-item-text">Abandon</span><span class="sb-menu-shortcut">Del</span></button></div>Highlight is a primary wash plus a 2px bar on the inline-start edge. It shows on hover, on :focus-visible and on [data-highlighted], which is how a script marks the keyboard-active item.
<div class="sb-menu" role="menu" aria-label="Context" style="position: static; display: flex"> <div class="sb-menu-label">Character</div> <button type="button" class="sb-menu-item" role="menuitem"><span class="sb-menu-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></svg></span><span class="sb-menu-item-text">Profile</span><span class="sb-menu-shortcut">P</span></button> <button type="button" class="sb-menu-item" role="menuitem" data-highlighted><span class="sb-menu-item-text">Highlighted (data-highlighted)</span><span class="sb-menu-shortcut">I</span></button> <button type="button" class="sb-menu-item" role="menuitem"><span class="sb-menu-item-text">With description<span class="sb-menu-item-description">Secondary line under the label</span></span></button> <button type="button" class="sb-menu-item" role="menuitem" aria-haspopup="menu" aria-expanded="false"><span class="sb-menu-item-text">Submenu trigger</span></button> <button type="button" class="sb-menu-item" role="menuitem" aria-haspopup="menu" aria-expanded="true"><span class="sb-menu-item-text">Submenu open</span></button> <button type="button" class="sb-menu-item" role="menuitem" disabled><span class="sb-menu-item-text">Disabled</span><span class="sb-menu-shortcut">D</span></button> <div class="sb-menu-separator" role="separator"></div> <div class="sb-menu-label">Toggles</div> <button type="button" class="sb-menu-item" role="menuitemcheckbox" aria-checked="true"><span class="sb-menu-item-text">Checked</span></button> <button type="button" class="sb-menu-item" role="menuitemcheckbox" aria-checked="false"><span class="sb-menu-item-text">Unchecked</span></button> <button type="button" class="sb-menu-item" role="menuitemcheckbox" aria-checked="mixed"><span class="sb-menu-item-text">Mixed</span></button> <div class="sb-menu-separator" role="separator"></div> <div class="sb-menu-group" role="group" aria-label="Difficulty"> <button type="button" class="sb-menu-item" role="menuitemradio" aria-checked="false"><span class="sb-menu-item-text">Easy</span></button> <button type="button" class="sb-menu-item" role="menuitemradio" aria-checked="true"><span class="sb-menu-item-text">Hard</span></button> </div> <div class="sb-menu-group" role="group"> <button type="button" class="sb-menu-item sb-menu-item-danger" role="menuitem"><span class="sb-menu-item-text">Delete character</span><span class="sb-menu-shortcut">Del</span></button> </div></div><div class="sb-stack"> <div class="sb-menu sb-menu-sm" role="menu" aria-label="Small" style="position: static; display: flex"> <div class="sb-menu-label">sb-menu-sm</div> <button type="button" class="sb-menu-item" role="menuitem"><span class="sb-menu-item-text">Compact item</span><span class="sb-menu-shortcut">1</span></button> </div> <div class="sb-menu sb-menu-lg" role="menu" aria-label="Large" style="position: static; display: flex"> <div class="sb-menu-label">sb-menu-lg</div> <button type="button" class="sb-menu-item" role="menuitem"><span class="sb-menu-item-text">Roomy item</span><span class="sb-menu-shortcut">2</span></button> </div> <div class="sb-menubar" role="menubar" aria-label="Menubar"> <button type="button" class="sb-menu-item" role="menuitem" aria-haspopup="menu">File</button> <button type="button" class="sb-menu-item" role="menuitem" aria-haspopup="menu" aria-expanded="true">Edit</button> <button type="button" class="sb-menu-item" role="menuitem" aria-haspopup="menu">View</button> <button type="button" class="sb-menu-item" role="menuitem" aria-haspopup="menu" disabled>Help</button> </div></div><div class="sb-menu sb-menu-glass" role="menu" aria-label="Glass" style="position: static; display: flex"> <div class="sb-menu-label">sb-menu-glass</div> <button type="button" class="sb-menu-item" role="menuitem"><span class="sb-menu-item-text">Over game imagery</span></button> <button type="button" class="sb-menu-item" role="menuitem" data-highlighted><span class="sb-menu-item-text">Highlighted</span></button></div>| Class / selector | Effect |
|---|---|
sb-menu |
The panel. As [popover] it is hidden until open, with the :popover-open enter animation. |
sb-menu-sm, sb-menu-lg |
Compact and roomy items. |
sb-menu-glass |
Glass fill for HUD context menus. |
sb-menu-label |
Non-interactive section heading. |
sb-menu-separator |
Divider line; give it role="separator". |
sb-menu-group |
Wrapper for related items (role="group"). |
sb-menu-item |
A row. Use a <button>. |
sb-menu-item-text |
The label cell. |
sb-menu-item-description |
Secondary line inside the text cell. |
sb-menu-icon |
Leading icon slot; mark it aria-hidden. |
sb-menu-shortcut |
Trailing key hint, in mono. |
sb-menu-item-danger |
Danger ink. |
sb-menubar |
Horizontal row of triggers (role="menubar"). |
[aria-checked="true"], [aria-checked="mixed"], [data-state="checked"] |
Draws the check or dash mark on an item. |
[aria-haspopup], [aria-expanded="true"] |
A submenu trigger: chevron, and the highlight stays while open. |
:disabled, [aria-disabled="true"], [data-disabled] |
Disabled item. |
[data-highlighted] |
Keyboard-active item. |
[data-state="open"], [data-state="closed"] |
Enter and leave motion for a script-rendered menu. |
.sb-tooltip
Section titled “.sb-tooltip”There are two tooltips, for two environments.
[data-tooltip] (websites only) is CSS only. The text comes from the attribute and shows on hover and :focus-visible after a short delay. Placement is data-tooltip-placement (top by default, bottom, left, right). An empty attribute shows nothing. The tooltip is an absolutely positioned pseudo-element, so near the edge of a narrow page it can widen the page; the demo’s overflow-x: clip on the wrapper prevents that. It cannot escape an ancestor with overflow: hidden or a transform, it has no touch or gamepad path, and it is not announced as a description, so keep the same information in a visible label or aria-label for essential controls.
<div class="sb-cluster" style="overflow-x: clip"> <button type="button" class="sb-btn sb-btn-outline sb-btn-neutral" data-tooltip="Default placement: top">Top</button> <button type="button" class="sb-btn sb-btn-outline sb-btn-neutral" data-tooltip="Placement: bottom" data-tooltip-placement="bottom">Bottom</button> <button type="button" class="sb-btn sb-btn-outline sb-btn-neutral" data-tooltip="Placement: left" data-tooltip-placement="left">Left</button> <button type="button" class="sb-btn sb-btn-outline sb-btn-neutral" data-tooltip="Placement: right" data-tooltip-placement="right">Right</button> <button type="button" class="sb-btn sb-btn-outline sb-btn-neutral" data-tooltip="A longer tooltip that wraps onto a second line once it passes eighteen rem of width" data-tooltip-placement="bottom">Long text</button></div>.sb-tooltip (in-game safe) is the box itself. A script (Vue SbTooltip, Floating UI) positions it next to its anchor and sets data-state and data-side. It carries role="tooltip" and should be referenced from the anchor with aria-describedby. Shown here statically:
<div class="sb-cluster sb-cluster-6"> <span class="sb-tooltip" role="tooltip" data-state="open" data-side="top">Equip to slot 1<kbd class="sb-tooltip-kbd">1</kbd></span> <span class="sb-tooltip" role="tooltip" data-side="bottom">data-side="bottom"</span> <span class="sb-tooltip" role="tooltip" data-side="left">data-side="left"</span> <span class="sb-tooltip" role="tooltip" data-side="right">data-side="right"</span></div>| Class / attribute | Effect |
|---|---|
[data-tooltip] |
Adds a CSS-only tooltip from the attribute value (websites only). |
[data-tooltip-placement] |
top (default), bottom, left or right. |
sb-tooltip |
The tooltip box: panel fill, strong hairline, small type, max 18rem, no pointer events. |
sb-tooltip-arrow |
Styles an <svg> arrow with the box’s fill and stroke. |
sb-tooltip-kbd |
Trailing key hint inside the box. |
[data-state="open"], [data-state="closed"] |
Enter and leave animation. |
[data-side="top"], "bottom", "left", "right" |
Motion direction. |
.sb-toast
Section titled “.sb-toast”A toast is a transient message. The CSS styles the elements; a script adds them to a .sb-toast-region, removes them and sets data-state="closed" for the leave motion. The region is position: fixed, pinned to a corner. The demo below overrides that inline so it can sit inside the page.
Use role="status" for routine messages and role="alert" for errors. Do not put an action that exists nowhere else in a toast: it disappears.
<div class="sb-toast-region sb-toast-region-bottom-right" role="region" aria-label="Notifications" style="position: static; width: auto; translate: none"> <div class="sb-toast" role="status"> <svg class="sb-toast-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 8v4M12 16h.01"/></svg> <div class="sb-toast-title">Default (primary)</div> <div class="sb-toast-description">Job accepted. Dakota will ping you with coordinates.</div> <button type="button" class="sb-toast-action sb-btn sb-btn-ghost sb-btn-primary sb-btn-sm">View</button> <button type="button" class="sb-toast-close" aria-label="Dismiss"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg></button> <div class="sb-toast-timer" style="--sb-toast-progress: 0.6"></div> </div> <div class="sb-toast sb-toast-success" role="status"> <svg class="sb-toast-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 13l4 4L19 7"/></svg> <div class="sb-toast-title">Saved</div> <div class="sb-toast-description">Loadout stored to slot 2.</div> <button type="button" class="sb-toast-action sb-btn sb-btn-ghost sb-btn-success sb-btn-sm">Undo</button> </div> <div class="sb-toast sb-toast-info" role="status"> <div class="sb-toast-title">Info, no icon</div> <div class="sb-toast-description">The title column starts at the accent bar.</div> </div> <div class="sb-toast sb-toast-warning" role="alert"> <div class="sb-toast-title">Low ammo</div> <div class="sb-toast-description">Reload before the next wave.</div> </div> <div class="sb-toast sb-toast-danger" role="alert"> <div class="sb-toast-title">Connection lost</div> <div class="sb-toast-description">Retrying in 5 s.</div> <button type="button" class="sb-toast-action sb-btn sb-btn-soft sb-btn-danger sb-btn-sm">Retry</button> </div> <div class="sb-toast sb-toast-solid" role="status"> <div class="sb-toast-title">Solid</div> <div class="sb-toast-description">Opaque panel for pages without a backdrop.</div> </div></div>| Class / attribute | Effect |
|---|---|
sb-toast-region |
Fixed stack container (role="region" with an aria-label). Bottom-right by default. Top regions reverse the stacking order. |
sb-toast-region-top-left, -top-center, -top-right, -bottom-left, -bottom-center, -bottom-right |
Region position. |
sb-toast |
The toast: glass fill, hairline, an accent bar on the inline-start edge with a bloom, slide-in animation. Accent is primary by default. |
sb-toast-info, -success, -warning, -danger, -neutral |
Accent color. |
sb-toast-solid |
Opaque panel for pages without a backdrop. |
sb-toast-icon |
Leading icon; mark it aria-hidden. Without it the title column starts at the accent bar. |
sb-toast-title, sb-toast-description |
Text parts. |
sb-toast-action |
An action button (combine with sb-btn). |
sb-toast-close |
Dismiss button; needs an aria-label. |
sb-toast-timer |
Optional countdown bar. Set --sb-toast-progress from 0 to 1. |
[data-state="open"], [data-state="closed"] |
Enter and leave motion. |
[data-swipe="move"], "cancel", "end" |
Swipe-to-dismiss states, mirroring Reka UI’s Toast. |