MatSnackBar and MatLiveAnnouncer: reducing notification noise in Angular Material alerts
0 reputation · 15 May 2025, 17:55 UTC
0 reputation · 15 May 2025, 17:55 UTC
Determine how to configure Angular Material’s MatSnackBar to deliver timely alerts that are audible‑free yet accessible, while avoiding persistent UI noise.
duration is undefined, causing indefinite persistence.action string renders a dismiss button; omitting or setting config.actions: [] removes it.open() calls may stack, potentially causing flicker.MatLiveAnnouncer with polite or assertive modes, which do not trigger audible alerts.MatLiveAnnouncer?MatSnackBar.open calls with short durations in rapid succession?31775 reputation · 15 May 2025, 21:53 UTC
Set duration to roughly 3000–5000 ms, omit the action string (or pass an empty actions list), and pair each snack bar with a MatLiveAnnouncer.announce(message, 'polite') call. Rapid successive open() calls do not queue — each creates its own instance, so you must throttle or debounce them yourself to avoid stacked, flickering bars.
When duration is left undefined, the snack bar stays open until the user dismisses it or navigates away — that is the source of the persistent UI noise you're seeing. For brief informational messages, 3000 ms is a practical default; use up to 5000 ms for longer sentences. Avoid going below about 2000 ms: very short displays are easy to miss visually and give screen-reader users little margin to perceive the change.
this.snackBar.open('Settings saved', undefined, { duration: 3000 });
The dismiss button appears only when you pass an action string. Calling open(message, undefined, config) — or passing actions: [] in the config — renders no button. The timed disappearance then becomes the only dismissal path, which is exactly what you want for low-noise alerts.
Removing the button removes a visual cue, so compensate with the live announcer. MatSnackBar already announces its messages through MatLiveAnnouncer internally (politeness depends on the configured politeness option, defaulting to a non-interruptive mode), but if you need explicit control — for example an assertive announcement for errors — announce the same text yourself:
constructor(private liveAnnouncer: MatLiveAnnouncer, private snackBar: MatSnackBar) {}
notify(message: string, assertive = false) {
this.snackBar.open(message, undefined, { duration: 3000 });
this.liveAnnouncer.announce(message, assertive ? 'assertive' : 'polite');
}
Note that polite and assertive only control when a screen reader speaks; neither mode produces any audible alert on its own — there is no system sound to suppress.
MatSnackBar does not maintain a notification queue. Each open() call creates an independent instance; in practice a new call dismisses the currently displayed snack bar and immediately shows the next one, which with short durations (e.g. 1500 ms) appears as visible flicker or abrupt message replacement. If your code can emit bursts of notifications, gate them yourself:
throttleTime(3000) on the notification stream) so only one snack bar is active at a time.afterDismissed() before opening the next.MatSnackBar.open('Test', undefined, { duration: 3000 }) and confirm the bar disappears after ~3 s with no button.MatLiveAnnouncer.announce('Test', 'polite') and confirm via a screen reader or the browser accessibility inspector that the text is announced.open() calls in quick succession with duration: 1500 and observe the replacement/flicker behavior directly.Version note: this behavior has been stable across Angular Material v12 and later, but animation timing and dismissal semantics can shift slightly between releases — check your package.json and confirm against your version's docs before relying on edge cases.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.