Snackbar
Material Design 3 snackbar component for brief messages and notifications
Snackbar
Snackbars provide brief messages about app processes. They appear temporarily at the bottom of the screen and automatically disappear after a timeout.
Basic Usage
Click the button to show a snackbar message.
Basic Snackbar
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Snackbar</button>
<div class="snackbar snackbar-bottom">
<span class="snackbar-message">Message sent</span>
</div>Positions
Bottom Center (Default)
Bottom Center
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Bottom</button>
<div class="snackbar snackbar-bottom">
<span class="snackbar-message">Bottom center snackbar</span>
</div>Bottom Left
Bottom Left
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Bottom Left</button>
<div class="snackbar snackbar-bottom-left">
<span class="snackbar-message">Bottom left snackbar</span>
</div>Bottom Right
Bottom Right
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Bottom Right</button>
<div class="snackbar snackbar-bottom-right">
<span class="snackbar-message">Bottom right snackbar</span>
</div>Top Center
Top Center
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Top</button>
<div class="snackbar snackbar-top">
<span class="snackbar-message">Top center snackbar</span>
</div>Top Left
Top Left
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Top Left</button>
<div class="snackbar snackbar-top-left">
<span class="snackbar-message">Top left snackbar</span>
</div>Top Right
Top Right
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Top Right</button>
<div class="snackbar snackbar-top-right">
<span class="snackbar-message">Top right snackbar</span>
</div>With Action
Add an action button for user interaction.
Snackbar with Action
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 5000);
">Show with Action</button>
<div class="snackbar snackbar-bottom">
<span class="snackbar-message">Message archived</span>
<button class="snackbar-action" onclick="this.parentElement.classList.remove('snackbar-show')">Undo</button>
</div>With Close Button
Allow users to dismiss the snackbar manually.
Snackbar with Close
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 10000);
">Show with Close</button>
<div class="snackbar snackbar-bottom">
<span class="snackbar-message">This snackbar can be dismissed</span>
<button class="snackbar-close" aria-label="Close" onclick="this.parentElement.classList.remove('snackbar-show')">Γ</button>
</div>With Icon
Add an icon for visual emphasis.
Snackbar with Icon
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show with Icon</button>
<div class="snackbar snackbar-bottom">
<span class="snackbar-icon">β</span>
<span class="snackbar-message">Action completed successfully</span>
</div>Semantic Colors
Success
Success Snackbar
html
<button class="btn btn-success" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Success</button>
<div class="snackbar snackbar-bottom snackbar-success">
<span class="snackbar-icon">β</span>
<span class="snackbar-message">Successfully saved!</span>
</div>Error
Error Snackbar
html
<button class="btn btn-error" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Error</button>
<div class="snackbar snackbar-bottom snackbar-error">
<span class="snackbar-icon">β</span>
<span class="snackbar-message">An error occurred</span>
</div>Warning
Warning Snackbar
html
<button class="btn btn-warning" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Warning</button>
<div class="snackbar snackbar-bottom snackbar-warning">
<span class="snackbar-icon">β </span>
<span class="snackbar-message">Warning: Check your input</span>
</div>Info
Info Snackbar
html
<button class="btn btn-info" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Info</button>
<div class="snackbar snackbar-bottom snackbar-info">
<span class="snackbar-icon">βΉ</span>
<span class="snackbar-message">New updates available</span>
</div>Brand Colors
Primary Snackbar
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Primary</button>
<div class="snackbar snackbar-bottom snackbar-primary">
<span class="snackbar-message">Primary snackbar</span>
</div>Secondary Snackbar
html
<button class="btn btn-secondary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Secondary</button>
<div class="snackbar snackbar-bottom snackbar-secondary">
<span class="snackbar-message">Secondary snackbar</span>
</div>Tertiary Snackbar
html
<button class="btn btn-tertiary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Tertiary</button>
<div class="snackbar snackbar-bottom snackbar-tertiary">
<span class="snackbar-message">Tertiary snackbar</span>
</div>Dark Snackbar
The traditional Material Design 3 dark snackbar style.
Dark Snackbar
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 3000);
">Show Dark</button>
<div class="snackbar snackbar-bottom snackbar-dark">
<span class="snackbar-message">Dark snackbar message</span>
<button class="snackbar-action" onclick="this.parentElement.classList.remove('snackbar-show')">Action</button>
</div>Multiline
For longer messages that need more space.
Multiline Snackbar
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 5000);
">Show Multiline</button>
<div class="snackbar snackbar-bottom snackbar-multiline">
<span class="snackbar-message">
This is a longer message that provides more detailed information about the action that was taken.
</span>
<button class="snackbar-action" onclick="this.parentElement.classList.remove('snackbar-show')">Dismiss</button>
</div>Complete Example
A snackbar with icon, message, action, and close button.
Complete Snackbar
html
<button class="btn btn-primary" onclick="
const snackbar = this.nextElementSibling;
snackbar.classList.add('snackbar-show');
setTimeout(() => snackbar.classList.remove('snackbar-show'), 10000);
">Show Complete</button>
<div class="snackbar snackbar-bottom snackbar-success">
<span class="snackbar-icon">β</span>
<span class="snackbar-message">Email sent successfully</span>
<button class="snackbar-action" onclick="this.parentElement.classList.remove('snackbar-show')">View</button>
<button class="snackbar-close" aria-label="Close" onclick="this.parentElement.classList.remove('snackbar-show')">Γ</button>
</div>JavaScript Integration
Basic Function
function showSnackbar(message, options = {}) {
const {
position = 'bottom',
duration = 3000,
variant = '',
action = null,
showClose = false
} = options;
// Create snackbar
const snackbar = document.createElement('div');
snackbar.className = `snackbar snackbar-${position} ${variant}`;
// Build content
let html = `<span class="snackbar-message">${message}</span>`;
if (action) {
html += `<button class="snackbar-action">${action.text}</button>`;
}
if (showClose) {
html += `<button class="snackbar-close" aria-label="Close">Γ</button>`;
}
snackbar.innerHTML = html;
document.body.appendChild(snackbar);
// Event listeners
if (action?.onClick) {
snackbar.querySelector('.snackbar-action').addEventListener('click', () => {
action.onClick();
hideSnackbar(snackbar);
});
}
if (showClose) {
snackbar.querySelector('.snackbar-close').addEventListener('click', () => {
hideSnackbar(snackbar);
});
}
// Show with animation
requestAnimationFrame(() => {
snackbar.classList.add('snackbar-show');
});
// Auto hide
if (duration > 0) {
setTimeout(() => hideSnackbar(snackbar), duration);
}
return snackbar;
}
function hideSnackbar(snackbar) {
snackbar.classList.remove('snackbar-show');
setTimeout(() => snackbar.remove(), 300);
}
// Usage examples
showSnackbar('Message sent');
showSnackbar('File deleted', {
position: 'bottom-left',
variant: 'snackbar-warning',
action: { text: 'Undo', onClick: () => console.log('Undone!') }
});
showSnackbar('Connection restored', {
variant: 'snackbar-success',
showClose: true,
duration: 5000
});
React Example
import { useState, useEffect } from 'react';
interface SnackbarProps {
message: string;
isOpen: boolean;
onClose: () => void;
variant?: 'success' | 'error' | 'warning' | 'info';
action?: { text: string; onClick: () => void };
duration?: number;
}
export function Snackbar({
message,
isOpen,
onClose,
variant,
action,
duration = 3000
}: SnackbarProps) {
useEffect(() => {
if (isOpen && duration > 0) {
const timer = setTimeout(onClose, duration);
return () => clearTimeout(timer);
}
}, [isOpen, duration, onClose]);
return (
<div className={`snackbar snackbar-bottom ${variant ? `snackbar-${variant}` : ''} ${isOpen ? 'snackbar-show' : ''}`}>
<span className="snackbar-message">{message}</span>
{action && (
<button className="snackbar-action" onClick={() => { action.onClick(); onClose(); }}>
{action.text}
</button>
)}
<button className="snackbar-close" onClick={onClose} aria-label="Close">Γ</button>
</div>
);
}
// Usage
function App() {
const [snackbar, setSnackbar] = useState({ isOpen: false, message: '' });
return (
<>
<button onClick={() => setSnackbar({ isOpen: true, message: 'Hello!' })}>
Show Snackbar
</button>
<Snackbar
{...snackbar}
onClose={() => setSnackbar(s => ({ ...s, isOpen: false }))}
/>
</>
);
}
API Reference
Class Names
| Class | Description |
|---|---|
.snackbar | Base snackbar (required) |
.snackbar-show | Show the snackbar with animation |
.snackbar-bottom | Bottom center position |
.snackbar-bottom-left | Bottom left position |
.snackbar-bottom-right | Bottom right position |
.snackbar-top | Top center position |
.snackbar-top-left | Top left position |
.snackbar-top-right | Top right position |
.snackbar-message | Message text container |
.snackbar-action | Action button |
.snackbar-close | Close/dismiss button |
.snackbar-icon | Icon element |
.snackbar-success | Success color variant |
.snackbar-error | Error color variant |
.snackbar-warning | Warning color variant |
.snackbar-info | Info color variant |
.snackbar-primary | Primary color variant |
.snackbar-secondary | Secondary color variant |
.snackbar-tertiary | Tertiary color variant |
.snackbar-dark | Dark (inverted) style |
.snackbar-multiline | Multiline layout |
Container Classes (Advanced)
For managing multiple snackbars, use the container approach:
| Class | Description |
|---|---|
.snackbar-container | Container for multiple snackbars |
.snackbar-container-bottom | Container at bottom center |
.snackbar-container-bottom-left | Container at bottom left |
.snackbar-container-bottom-right | Container at bottom right |
.snackbar-container-top | Container at top center |
.snackbar-container-top-left | Container at top left |
.snackbar-container-top-right | Container at top right |
Best Practices
- Keep messages brief - Snackbars should contain short, actionable messages
- Use appropriate duration - 3-5 seconds for simple messages, longer for messages with actions
- One at a time - Avoid showing multiple snackbars simultaneously
- Donβt block content - Snackbars should not cover important UI elements
- Provide actions when appropriate - Allow users to undo actions or view details
- Use semantic colors - Match the snackbar color to the message type (success, error, etc.)
Related Components
- Toast - Alternative toast implementation
- Alert - Prominent inline alerts
- Dialog - Modal dialogs for important interactions