Snackbar

Snackbar

Material Design 3 snackbars, from the HTML.

Snackbars show short updates about app processes at the bottom of the screen. They should not interrupt browsing — people can keep using the page without interacting with the bar. A .snackbar is the bar. A <p> is the supporting text. A trailing <button> is the optional action; a .circle button is the optional close.

Tokens follow the M3 snackbar spec. The container is inverse-surface, 4dp corners, elevation 3, 48dp minimum. Supporting text is body-medium / inverse-on-surface, two lines max. The action is a label-large / inverse-primary text button. Close is a 24dp inverse-on-surface icon. On compact viewports the bar is inset 8dp from the edges; from the Medium breakpoint up it hugs content (344–672dp) and sits centered 24dp from the bottom.

A snackbar can time out on its own (4 seconds, or 10 with an action) or stay until the user acts (displayLength: Infinity). Only one shows at a time. Snackbar is not in AutoInit() — construct one when you need it, or drop a static .snackbar in the page and add .active to pin it.

Photo saved to album

Item archived

Can't send photo. Retry in 5 seconds.

new Expressive.Snackbar({ text: 'Photo saved to album' });

new Expressive.Snackbar({
  text: 'Item archived',
  action: 'Undo',
  onAction: function() { /* restore */ }
});

new Expressive.Snackbar({
  text: "Can't send photo. Retry in 5 seconds.",
  action: 'Retry',
  dismissible: true
});

The constructor wraps text in a <p> and appends the action and close when those options are set. The live region is role="status" with aria-live="polite", so it announces without stealing focus.

Initialization

The IIFE bundle exposes Expressive.Snackbar. Snackbar is not in AutoInit() — construct one when you need it.

new Expressive.Snackbar({
  text: 'I am a snackbar!'
});

One way to hook that up is a click handler on a button:

<button type="button" id="snackbar-basic">Show</button>
document.getElementById('snackbar-basic').addEventListener('click', function() {
  new Expressive.Snackbar({ text: 'I am a snackbar!' });
});

Markup

The same anatomy works as static HTML. Without .active the bar is in-flow — useful for previews. With .active it pins to the bottom of the viewport, centered from the Medium breakpoint. Add .top only if you must move it off the bottom.

Single-line snackbar with action

<div class="snackbar">
  <p>Photo saved to album</p>
</div>

<div class="snackbar">
  <p>Item archived</p>
  <button type="button">Undo</button>
</div>

<div class="snackbar active">
  <p>Single-line snackbar with action</p>
  <button type="button">Action</button>
</div>

.active does not dismiss itself. Add and remove the class, or use the constructor if you want the 4-second timer and swipe-to-dismiss.

Options

You can customize each snackbar with these options.

Name Type Default Description
text String '' Plain-text supporting text, wrapped in a <p>. If set, it replaces any HTML from snackbarId.
action String '' Optional action label. Rendered as a trailing text button.
onAction Function null Called when the action button is pressed. The snackbar still dismisses.
dismissible Boolean false Show a trailing close icon button.
snackbarId String Id of a <template> (or another element) used as the snackbar body.
displayLength Number 4000 How long the snackbar stays before it dismisses, in milliseconds. Default 4s, or 10s when action is set. Pass Infinity to remain until the user takes action.
inDuration Number 300 Enter transition duration, in milliseconds.
outDuration Number 375 Exit transition duration, in milliseconds.
classes String '' Space-separated classes added to the snackbar. rounded is a stadium. top moves the bar off the bottom.
completeCallback Function null Called when the snackbar is dismissed.
activationPercent Number 0.8 Fraction of the snackbar’s width a drag must travel to dismiss it.
root Element null Any element in the tree the snackbar should render into. Pass one when the page lives in a shadow root, so the container is appended there rather than to document.body.

Methods

Instance methods are called on the snackbar. You can get the instance like this:
const instance = Expressive.Snackbar.getInstance(elem);
.dismiss();

Dismiss this snackbar with its exit animation. Runs completeCallback when the animation finishes.

instance.dismiss();
Snackbar.dismissAll();

Dismiss every snackbar that is currently showing.

Expressive.Snackbar.dismissAll();

Properties

Name Type Description
el Element The snackbar element.
options Object The options the instance was initialized with.
panning Boolean Whether the snackbar is being dragged.
timeRemaining Number Milliseconds left before the snackbar dismisses.

Custom HTML

Pass snackbarId pointing at a <template>. The first child of the template is cloned as the snackbar. Leave text empty so the HTML is kept. Use the same anatomy as a static snackbar.

<button type="button" class="tonal" id="snackbar-html-1">Show Snackbar 1</button>
<template id="my-snackbar-1">
  <div>
    <p>This is snackbar nº1 with a <a href="https://github.com">link</a></p>
  </div>
</template>
new Expressive.Snackbar({ snackbarId: 'my-snackbar-1' });

Callback

Run a function when the snackbar is dismissed.

new Expressive.Snackbar({
  text: 'I will call back when dismissed',
  completeCallback: function() {
    new Expressive.Snackbar({ text: 'Your snackbar was dismissed' });
  }
});

Styling

Pass classes in the classes option. rounded is a 24dp stadium — the M3 default is 4dp. Snackbars sit at the bottom; top is the exception.

new Expressive.Snackbar({
  text: 'I am a snackbar!',
  classes: 'rounded'
});

new Expressive.Snackbar({
  text: 'Posted from the top',
  classes: 'top'
});

Dismiss a Snackbar Programmatically

To remove a specific snackbar, get the instance from the snackbar element and call dismiss(). Swipe also dismisses — drag past 80% of the width (or flick). The action and close buttons are not swipe handles.

const snackbarElement = document.querySelector('.snackbar');
const snackbarInstance = Expressive.Snackbar.getInstance(snackbarElement);
snackbarInstance.dismiss();
Dismiss all snackbars
Expressive.Snackbar.dismissAll();
  • Source color

    The seed every generated ramp derives from. Pick one and browse the docs — the whole theme follows. Error does not: it is a fixed hue.