Toast Messages
Demo
/* Importing fonts */
@import url("https://fonts.googleapis.com/css2?family=Barlow&family=Oswald&display=swap");
/* Container for the select element */
.select-container {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding-right: 20px;
}
/* Label above the select element */
.select-label {
font-family: "Barlow", sans-serif;
font-size: 16px;
color: #333;
margin-bottom: 10px;
}
/* Main container for toast messages */
.toast-container {
position: fixed;
top: 20px;
right: 20px;
z-index: 1000;
font-family: "Barlow", sans-serif;
}
/* Buttons container */
.controls {
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
font-family: "Barlow", sans-serif;
}
/* Styling for different buttons */
.error-button,
.notification-button,
.update-button {
/* Clear initial background and border */
background: none;
border: 2px solid transparent;
border-radius: 8px;
padding: 12px 20px; /* Increased padding for larger buttons */
margin: 5px;
cursor: pointer;
transition: all 0.3s ease; /* Smooth transition on hover */
font-size: 16px; /* Increased font size */
}
/* Hover styles for buttons */
.error-button:hover,
.notification-button:hover,
.update-button:hover {
opacity: 0.8; /* Reduced opacity on hover */
}
/* Error button styles */
.error-button {
color: #8c0000; /* Darker text */
border-color: #ff4d4d; /* Red border */
background-color: #ffe6e6; /* Lighter red background */
}
/* Notification button styles */
.notification-button {
color: #004d99; /* Darker text */
border-color: #007acc; /* Blue border */
background-color: #cce0ff; /* Lighter blue background */
}
/* Update button styles */
.update-button {
color: #804d00; /* Darker text */
border-color: #ff9933; /* Orange border */
background-color: #ffd699; /* Lighter orange background */
}
/* Individual toast message styling */
.toast {
position: relative;
max-width: 200px;
width: 80%; /* Allow the toast to take full width within the max-width */
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
word-wrap: break-word; /* Allow long words to break and wrap */
word-break: break-word; /* Break words when necessary */
opacity: 0;
animation: slideFadeIn 0.5s ease forwards; /* Animation for toast appearance */
}
/* Close button style within the toast */
.toast button.close-button {
/* Positioning */
position: absolute;
top: 5px;
right: 5px;
/* Button styling */
background: none;
border: none;
cursor: pointer;
font-size: 14px; /* Adjusted font size for smaller close button */
color: #; /* Missing color value */
width: 20px; /* Reduced width */
height: 20px; /* Reduced height */
text-align: center;
}
/* Hover styles for close button */
.toast button.close-button:hover {
color: #000; /* Change color on hover for better contrast */
}
/* Styling for error toast */
.error-toast {
border: 1px solid #ff4d4d; /* Red outline */
background-color: #ffe6e6; /* Lighter red interior */
color: #8c0000; /* Darker text for contrast */
}
/* Styling for notification toast */
.notification-toast {
border: 1px solid #007acc; /* Blue outline */
background-color: #cce0ff; /* Lighter blue interior */
color: #004d99; /* Darker text for contrast */
}
/* Styling for update toast */
.update-toast {
border: 1px solid #ff9933; /* Orange outline */
background-color: #ffd699; /* Lighter orange interior */
color: #804d00; /* Darker text for contrast */
}
/* Select element styles */
#durationSelect {
font-family: "Barlow", sans-serif;
font-size: 16px;
padding: 12px 20px;
border: 2px solid transparent;
border-radius: 8px;
margin-right: 5px;
cursor: pointer;
transition: all 0.3s ease;
}
/* Hover styles for select element */
#durationSelect:hover {
opacity: 0.8;
}
/* Keyframe animation for toast appearance */
@keyframes slideFadeIn {
0% {
opacity: 0;
transform: translateY(-50px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
// Wait for the DOM content to be fully loaded
document.addEventListener("DOMContentLoaded", function () {
// Get necessary elements from the DOM
const durationSelect = document.getElementById("durationSelect");
const toastContainer = document.querySelector(".toast-container");
// Function to create toast messages
function createToast(message, durationClass) {
console.log(
`Creating toast with message: "${message}" and duration class: "${durationClass}"`
);
// Get all existing toast messages
const existingToasts = document.querySelectorAll(".toast");
// Create a new toast message element
const newToast = document.createElement("div");
newToast.classList.add("toast", durationClass);
// Create close button for the toast message
const closeButton = document.createElement("button");
closeButton.classList.add("close-button");
closeButton.innerHTML = "X";
closeButton.setAttribute("aria-label", "Close toast message");
closeButton.addEventListener("click", function () {
newToast.remove();
});
// Set the message content and append the close button
newToast.innerText = message;
newToast.appendChild(closeButton);
// Add the new toast message at the beginning of the container
toastContainer.prepend(newToast);
// Apply animation for displaying new toast messages
existingToasts.forEach((toast) => {
toast.style.animation = "slideDown 0.5s ease forwards";
toast.style.transform = "translateY(" + (toast.offsetHeight + 20) + "px)";
});
// Remove animation after a set time
setTimeout(() => {
existingToasts.forEach((toast) => {
toast.style.animation = "";
toast.style.transform = "";
});
}, 500);
// Handle the duration for toast messages
const selectedDuration = parseInt(durationSelect.value);
if (selectedDuration === 0) {
console.log("Infinite duration set for toast");
return; // For infinite duration, don't set a timeout for removal
}
console.log(`Toast duration set for ${selectedDuration} milliseconds`);
// Set a timeout to remove the toast message after the specified duration
setTimeout(() => {
newToast.remove();
}, selectedDuration);
}
// Event listener for changes in the duration select element
durationSelect.addEventListener("change", function () {
const toasts = document.querySelectorAll(".toast");
const durationClass = this.value === "0" ? "no-fade" : "";
// Apply the selected duration class to existing toast messages
toasts.forEach((toast) => {
if (!toast.classList.contains("no-fade")) {
toast.classList.remove("default", "10-seconds");
toast.classList.add(durationClass);
}
});
});
// Event listeners for creating different types of toast messages
document.getElementById("errorButton").addEventListener("click", function () {
createToast(
"This is an example toast message for a software or website process error.",
"error-toast"
);
});
document
.getElementById("notificationButton")
.addEventListener("click", function () {
createToast(
"This is an example toast message for a user notification.",
"notification-toast"
);
});
document
.getElementById("updateButton")
.addEventListener("click", function () {
createToast(
"This is an example toast message for a system update.",
"update-toast"
);
});
});
Why use toast messages?
In web development, toast messages serve as unobtrusive, temporary notifications that deliver essential information to users without disrupting their workflow. These messages are particularly valuable as they provide immediate feedback on actions, updates, or alerts, enhancing the user experience by keeping users informed about critical events or changes. From an accessibility standpoint, well-designed toast messages offer benefits by providing clear and concise information that is easily perceivable by all users, including those utilizing assistive technologies. When properly implemented with appropriate ARIA attributes and keyboard accessibility, toast messages ensure that users with disabilities receive timely and accessible notifications, contributing to a more inclusive and user-friendly web experience.
What are some accessibility concerns?
- Visibility and Readability:
- Concern: Toast messages might appear abruptly or be difficult to notice, especially for users with visual impairments.
- Mitigation: Ensure adequate contrast between the toast message and its background for readability. Use visually distinct colors, text size, and animations to draw attention without being overwhelming. Provide sufficient time for users to read and comprehend the message.
- Keyboard Accessibility:
- Concern: Keyboard-only users might have difficulties interacting with or dismissing toast messages.
- Mitigation: Implement keyboard accessibility by allowing users to navigate to and dismiss toast messages using keyboard controls (e.g., Tab, Enter/Space, and Esc keys). Provide focus management to ensure that users can interact with the message content and dismiss it easily.
- Screen Reader Compatibility:
- Concern: Screen reader users might not receive or understand the content of the toast messages.
- Mitigation: Ensure toast messages are programmatically available to assistive technologies by using appropriate ARIA roles and attributes. Announce the appearance of new messages and their content using live regions or ARIA alerts.
- Timing and Dismissal:
- Concern: Toast messages might disappear too quickly, making it challenging for users to read or act upon them.
- Mitigation: Allow sufficient time for users to perceive and comprehend the message. Provide options for users to dismiss or interact with the message, allowing them to control the duration of its display.
- Focus and Interruptions:
- Concern: Toast messages might disrupt users’ focus or interfere with screen reader announcements.
- Mitigation: Avoid abrupt changes or automatic updates that might interrupt users. Ensure toast messages do not steal focus and provide options to pause or dismiss animations for users with attention-related disabilities.
- Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
- All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes, except where the underlying function requires input that depends on the path of the user's movement and not just the endpoints.
-
For moving, blinking, scrolling, or auto-updating information, all of the following are true:
Moving, blinking, scrolling: For any moving, blinking or scrolling information that (1) starts automatically, (2) lasts more than five seconds, and (3) is presented in parallel with other content, there is a mechanism for the user to pause, stop, or hide it unless the movement, blinking, or scrolling is part of an activity where it is essential, andAuto-updating: For any auto-updating information that (1) starts automatically and (2) is presented in parallel with other content, there is a mechanism for the user to pause, stop, or hide it or to control the frequency of the update unless the auto-updating is part of an activity where it is essential.
- In content implemented using markup languages, status messages can be programmatically determined through role or properties such that they can be presented to the user by assistive technologies without receiving focus.