1 |
|
2 | title: "Snackbars"
|
3 | layout: detail
|
4 | section: components
|
5 | excerpt: "Snackbars provide brief messages about app processes at the bottom of the screen."
|
6 | iconId: toast
|
7 | path: /catalog/snackbars/
|
8 | -->
|
9 |
|
10 | # Snackbars
|
11 |
|
12 | Snackbars provide brief messages about app processes at the bottom of the screen.
|
13 |
|
14 | ## Design & API Documentation
|
15 |
|
16 | <ul class="icon-list">
|
17 | <li class="icon-list-item icon-list-item--spec">
|
18 | <a href="https://material.io/go/design-snackbar">Material Design guidelines: Snackbars</a>
|
19 | </li>
|
20 | <li class="icon-list-item icon-list-item--link">
|
21 | <a href="https://material-components.github.io/material-components-web-catalog/#/component/snackbar">Demo</a>
|
22 | </li>
|
23 | </ul>
|
24 |
|
25 | ## Installation
|
26 |
|
27 | ```
|
28 | npm install @material/snackbar
|
29 | ```
|
30 |
|
31 | ## Basic Usage
|
32 |
|
33 | ### HTML Structure
|
34 |
|
35 | ```html
|
36 | <aside class="mdc-snackbar">
|
37 | <div class="mdc-snackbar__surface" role="status" aria-relevant="additions">
|
38 | <div class="mdc-snackbar__label" aria-atomic="false">
|
39 | Can't send photo. Retry in 5 seconds.
|
40 | </div>
|
41 | <div class="mdc-snackbar__actions" aria-atomic="true">
|
42 | <button type="button" class="mdc-button mdc-snackbar__action">
|
43 | <div class="mdc-button__ripple"></div>
|
44 | <span class="mdc-button__label">Retry</span>
|
45 | </button>
|
46 | </div>
|
47 | </div>
|
48 | </aside>
|
49 | ```
|
50 |
|
51 | ### Styles
|
52 |
|
53 | ```scss
|
54 | @use "@material/snackbar/mdc-snackbar";
|
55 | ```
|
56 |
|
57 | ### JavaScript Instantiation
|
58 |
|
59 | ```js
|
60 | import {MDCSnackbar} from '@material/snackbar';
|
61 | const snackbar = new MDCSnackbar(document.querySelector('.mdc-snackbar'));
|
62 | ```
|
63 |
|
64 | > See [Importing the JS component](../../docs/importing-js.md) for more information on how to import JavaScript.
|
65 |
|
66 | ## Variants
|
67 |
|
68 | ### Stacked
|
69 |
|
70 | Action buttons with long text should be positioned _below_ the label instead of alongside it. This can be accomplished by adding the `mdc-snackbar--stacked` modifier class to the root element:
|
71 |
|
72 | ```html
|
73 | <aside class="mdc-snackbar mdc-snackbar--stacked">
|
74 | ...
|
75 | </aside>
|
76 | ```
|
77 |
|
78 | Alternatively, you can call the `layout-stacked` mixin from Sass:
|
79 |
|
80 | ```scss
|
81 | @use "@material/snackbar";
|
82 |
|
83 | @media (max-width: snackbar.$mobile-breakpoint) {
|
84 | .my-snackbar {
|
85 | @include snackbar.layout-stacked;
|
86 | }
|
87 | }
|
88 | ```
|
89 |
|
90 | ### Leading (tablet and desktop only)
|
91 |
|
92 | By default, snackbars are centered horizontally within the viewport.
|
93 |
|
94 | On larger screens, they can optionally be displayed on the _leading_ edge of the screen (the left side in LTR, or the right side in RTL) by adding the `mdc-snackbar--leading` modifier class to the root element:
|
95 |
|
96 | ```html
|
97 | <aside class="mdc-snackbar mdc-snackbar--leading">
|
98 | ...
|
99 | </aside>
|
100 | ```
|
101 |
|
102 | Alternatively, you can call the `position-leading` mixin from Sass:
|
103 |
|
104 | ```scss
|
105 | @media (min-width: snackbar.$mobile-breakpoint) {
|
106 | .my-snackbar {
|
107 | @include snackbar.position-leading;
|
108 | }
|
109 | }
|
110 | ```
|
111 |
|
112 | ### Wide (tablet and desktop only)
|
113 |
|
114 | To increase the margins between the snackbar and the viewport on larger screens, call the `viewport-margin` mixin inside a media query:
|
115 |
|
116 | ```scss
|
117 | @media (min-width: snackbar.$mobile-breakpoint) {
|
118 | .my-snackbar {
|
119 | @include snackbar.viewport-margin(snackbar.$viewport-margin-wide);
|
120 | }
|
121 | }
|
122 | ```
|
123 |
|
124 | ## Style Customization
|
125 |
|
126 | ### CSS Classes
|
127 |
|
128 | CSS Class | Description
|
129 | --- | ---
|
130 | `mdc-snackbar` | Mandatory. Container for the snackbar elements.
|
131 | `mdc-snackbar__label` | Mandatory. Message text.
|
132 | `mdc-snackbar__actions` | Optional. Wraps the action button/icon elements, if present.
|
133 | `mdc-snackbar__action` | Optional. The action button.
|
134 | `mdc-snackbar__dismiss` | Optional. The dismiss ("X") icon.
|
135 | `mdc-snackbar--opening` | Optional. Applied automatically when the snackbar is in the process of animating open.
|
136 | `mdc-snackbar--open` | Optional. Indicates that the snackbar is open and visible.
|
137 | `mdc-snackbar--closing` | Optional. Applied automatically when the snackbar is in the process of animating closed.
|
138 | `mdc-snackbar--leading` | Optional. Positions the snackbar on the leading edge of the screen (left in LTR, right in RTL) instead of centered.
|
139 | `mdc-snackbar--stacked` | Optional. Positions the action button/icon below the label instead of alongside it.
|
140 |
|
141 | ### Sass Mixins
|
142 |
|
143 | Mixin | Description
|
144 | --- | ---
|
145 | `fill-color($color)` | Sets the fill color of the snackbar.
|
146 | `label-ink-color($color)` | Sets the color of the snackbar's label text.
|
147 | `shape-radius($radius, $rtl-reflexive)` | Sets the rounded shape to snackbar surface with given radius size. Set `$rtl-reflexive` to true to flip radius values in RTL context, defaults to false.
|
148 | `min-width($min-width, $mobile-breakpoint)` | Sets the `min-width` of the surface on tablet/desktop devices. On mobile, the width is automatically set to 100%.
|
149 | `max-width($max-width)` | Sets the `max-width` of the snackbar.
|
150 | `elevation($z-index)` | Sets the elevation of the snackbar.
|
151 | `viewport-margin($margin)` | Sets the distance between the snackbar and the viewport.
|
152 | `z-index($z-index)` | Sets the `z-index` of the snackbar.
|
153 | `position-leading()` | Positions the snackbar on the leading edge of the screen (left in LTR, right in RTL) instead of centered.
|
154 | `layout-stacked()` | Positions the action button/icon below the label instead of alongside it.
|
155 |
|
156 | > **NOTE**: The `mdc-snackbar__action` and `mdc-snackbar__dismiss` elements can be further customized with [`mdc-button`](../mdc-button) and [`mdc-icon-button`](../mdc-icon-button) mixins.
|
157 |
|
158 | ## JavaScript API
|
159 |
|
160 | ### `MDCSnackbar` Properties
|
161 |
|
162 | Property | Value Type | Description
|
163 | --- | --- | ---
|
164 | `isOpen` | `boolean` (read-only) | Gets whether the snackbar is currently open.
|
165 | `timeoutMs` | `number` | Gets/sets the automatic dismiss timeout in milliseconds. Value must be between `4000` and `10000` (or `-1` to disable the timeout completely) or an error will be thrown. Defaults to `5000` (5 seconds).
|
166 | `closeOnEscape` | `boolean` | Gets/sets whether the snackbar closes when it is focused and the user presses the <kbd>ESC</kbd> key. Defaults to `true`.
|
167 | `labelText` | `string` | Gets/sets the `textContent` of the label element.
|
168 | `actionButtonText` | `string` | Gets/sets the `textContent` of the action button element.
|
169 |
|
170 | > **NOTE**: Setting `labelText` while the snackbar is open will cause screen readers to announce the new label. See [Screen Readers](#screen-readers) below for more information.
|
171 |
|
172 | ### `MDCSnackbar` Methods
|
173 |
|
174 | Method Signature | Description
|
175 | --- | ---
|
176 | `open() => void` | Opens the snackbar.
|
177 | `close(reason: string=) => void` | Closes the snackbar, optionally with the specified reason indicating why it was closed.
|
178 |
|
179 | ### Events
|
180 |
|
181 | Event Name | `event.detail` | Description
|
182 | --- | --- | ---
|
183 | `MDCSnackbar:opening` | `{}` | Indicates when the snackbar begins its opening animation.
|
184 | `MDCSnackbar:opened` | `{}` | Indicates when the snackbar finishes its opening animation.
|
185 | `MDCSnackbar:closing` | `{reason?: string}` | Indicates when the snackbar begins its closing animation. `reason` contains the reason why the snackbar closed (`'dismiss'`, `'action'`, or `undefined`).
|
186 | `MDCSnackbar:closed` | `{reason?: string}` | Indicates when the snackbar finishes its closing animation. `reason` contains the reason why the snackbar closed (`'dismiss'`, `'action'`, or `undefined`).
|
187 |
|
188 | ### Usage Within Frameworks
|
189 |
|
190 | If you are using a JavaScript framework, such as React or Angular, you can create a Snackbar for your framework. Depending on your needs, you can use the _Simple Approach: Wrapping MDC Web Vanilla Components_, or the _Advanced Approach: Using Foundations and Adapters_. Please follow the instructions [here](../../docs/integrating-into-frameworks.md).
|
191 |
|
192 | #### `MDCSnackbarAdapter` Methods
|
193 |
|
194 | Method Signature | Description
|
195 | --- | ---
|
196 | `addClass(className: string) => void` | Adds a class to the root element.
|
197 | `removeClass(className: string) => void` | Removes a class from the root element.
|
198 | `announce() => void` | Announces the snackbar's label text to screen reader users.
|
199 | `notifyOpening() => void` | Broadcasts an event denoting that the snackbar has just started opening.
|
200 | `notifyOpened() => void` | Broadcasts an event denoting that the snackbar has finished opening.
|
201 | `notifyClosing(reason: string) => void` | Broadcasts an event denoting that the snackbar has just started closing. If a non-empty `reason` is passed, the event's `detail` object should include its value in the `reason` property.
|
202 | `notifyClosed(reason: string) => void` | Broadcasts an event denoting that the snackbar has finished closing. If a non-empty `reason` is passed, the event's `detail` object should include its value in the `reason` property.
|
203 |
|
204 | #### `MDCSnackbarFoundation` Methods
|
205 |
|
206 | Method Signature | Description
|
207 | --- | ---
|
208 | `open()` | Opens the snackbar.
|
209 | `close(action: string)` | Closes the snackbar, optionally with the specified action indicating why it was closed.
|
210 | `isOpen() => boolean` | Returns whether the snackbar is open.
|
211 | `getTimeoutMs() => number` | Returns the automatic dismiss timeout in milliseconds.
|
212 | `setTimeoutMs(timeoutMs: number)` | Sets the automatic dismiss timeout in milliseconds. Value must be between `4000` and `10000` or an error will be thrown.
|
213 | `getCloseOnEscape() => boolean` | Returns whether the snackbar closes when it is focused and the user presses the <kbd>ESC</kbd> key.
|
214 | `setCloseOnEscape(closeOnEscape: boolean) => void` | Sets whether the snackbar closes when it is focused and the user presses the <kbd>ESC</kbd> key.
|
215 | `handleKeyDown(event: KeyEvent)` | Handles `keydown` events on or within the snackbar's root element.
|
216 | `handleActionButtonClick(event: MouseEvent)` | Handles `click` events on or within the action button.
|
217 | `handleActionIconClick(event: MouseEvent)` | Handles `click` events on or within the dismiss icon.
|
218 |
|
219 | #### Event Handlers
|
220 |
|
221 | When wrapping the Snackbar foundation, the following events must be bound to the indicated foundation methods:
|
222 |
|
223 | Event | Target | Foundation Handler | Register | Deregister
|
224 | --- | --- | --- | --- | ---
|
225 | `keydown` | `.mdc-snackbar` | `handleKeyDown` | During initialization | During destruction
|
226 | `click` | `.mdc-snackbar__action` | `handleActionButtonClick` | During initialization | During destruction
|
227 | `click` | `.mdc-snackbar__dismiss` | `handleActionIconClick` | During initialization | During destruction
|
228 |
|
229 | #### The Util API
|
230 |
|
231 | External frameworks and libraries can use the following utility methods from the `util` module when implementing their own component.
|
232 |
|
233 | Method Signature | Description
|
234 | --- | ---
|
235 | `announce(ariaEl: Element, labelEl?: Element) => void` | Announces the label text to screen reader users.
|
236 |
|
237 | > Alternatively, frameworks can use [Closure Library's `goog.a11y.aria.Announcer#say()` method](https://github.com/google/closure-library/blob/bee9ced776b4700e8076a3466bd9d3f9ade2fb54/closure/goog/a11y/aria/announcer.js#L80).
|
238 |
|
239 | ## Accessibility
|
240 |
|
241 | ### Screen Readers
|
242 |
|
243 | Snackbars automatically announce their label text to screen reader users with a ["polite" notification](https://www.w3.org/TR/wai-aria-1.1/#aria-live) when `open()` is called.
|
244 |
|
245 | However, screen readers only announce [ARIA Live Regions](https://mdn.io/ARIA_Live_Regions) when the element's `textContent` _changes_, so MDC Snackbar provides a `util.announce()` method to temporarily clear and then restore the label element's `textContent`.
|
246 |
|
247 | > **NOTE**: Setting `labelText` while the snackbar is open will cause screen readers to announce the new label.
|
248 |
|
249 | `util.announce()` supports the latest versions of the following screen readers and browsers:
|
250 |
|
251 | * [ChromeVox](https://chrome.google.com/webstore/detail/chromevox/kgejglhpjiefppelpmljglcjbhoiplfn)
|
252 | * [NVDA](https://www.nvaccess.org/):
|
253 | - Chrome
|
254 | - Firefox
|
255 | - IE 11
|
256 | * [JAWS](https://www.freedomscientific.com/Products/Blindness/JAWS):
|
257 | - Chrome
|
258 | - Firefox
|
259 | - IE 11
|
260 |
|
261 | macOS VoiceOver is _not_ supported at this time.
|
262 |
|
263 | ### Dismiss Icon
|
264 |
|
265 | Snackbars are intended to dismiss on their own after a few seconds, but a dedicated dismiss icon may be optionally included as well for accessibility purposes.
|
266 |
|
267 | ### Dismiss Key
|
268 |
|
269 | Pressing the <kbd>ESC</kbd> key while one of the snackbar's child elements has focus (e.g., the action button) will dismiss the snackbar.
|
270 |
|
271 | To disable this behavior, set `closeOnEscape` to `false`.
|
272 |
|
273 | ### No JS Ripples
|
274 |
|
275 | The `mdc-snackbar__action` and `mdc-snackbar__dismiss` elements should _**not**_ have JavaScript-enabled [`MDCRipple`](../mdc-ripple) behavior.
|
276 |
|
277 | When combined with the snackbar's exit animation, ripples cause too much motion, which can be distracting or disorienting for users.
|