Alerts - Critical Messages
A critical message alert is a type of notification that is used to immediately inform users of urgent and important messages. It is used to communicate important information such as errors or warnings that require immediate attention.
NOTE:
- New to accessibility or uncertain of requirements, it will be helpful to review all sections below.
- Already familiar with requirements, skip to the “Working Example” section for sample HTML, CSS and JavaScript (when needed), along with a working demo.
- The critical message text MUST meet the minimum contrast requirement ratio of 3:1 for the large text or text with 14pts and bold.
- The critical message text MUST meet the minimum contrast requirement ratio of 4.5:1 for the standard text.
- The non-text content in the critical message such as icons or graphics MUST meet the minimum contrast requirement ratio of 3:1.
- Only color MUST NOT be used to convey critical message alerts.
- Identify the critical message content such as text, images or other types of content that change dynamically on the page.
- The alert message MUST be visually distinct from the surrounding content on the page.
- Clear and concise language MUST be used to convey the alert message.
-
Provide appropriate ARIA roles such as
alert
orstatus
depending on the context of the alert message. -
The role
alert
is used to indicate that an element contains important, time-sensitive information that requires the user's attention. When an element has thealert
role, assistive technologies such as screen readers will announce the contents of the element immediately to the user, even if they are currently focused on another part of the page. -
The role
alert
has an implicitaria-live
value ofassertive
and an implicitaria-atomic
value oftrue
. - The container of the critical message SHOULD be present in DOM by default to ensure a smooth user experience.
-
In case the alert is a dialog, the role
alertdialog
is used to indicate the important information. -
The
aria-labelledby
attribute SHOULD be used to provide an accessible name for the alert dialog. It refers to the title of the alert dialog. -
The
aria-describedby
attribute SHOULD be used to provide an accessible description for the alert dialog. It refers to the alert dialog content that describes its purpose. -
The
aria-modal
attribute SHOULD be used to inform assistive technologies that the content underneath the alert dialog is not available for users.
For example,
<!-- Login form -->
<div class="autocomplete">
<form id="contact-us" onsubmit="return checkError(this)" method="post">
<label for="username">Username</label>
<input name="username" id="username" type="text" autocomplete="name">
<label for="password">Password</label>
<input name="password" id="password" type="password" autocomplete="new-password">
<input type="submit" class="alert-button" id="alert-button" name="alert-button" value="SIGN IN">
</form>
<!-- Alert message -->
<div id="error" tabindex="-1" role="alert" style="display: block;">
<p>Following form consists of 2 error(s). Please fix the errors and try again.</p>
</div>
<!-- Alert dialog -->
<div id="alert-modal" role="alertdialog" aria-modal="true" aria-labelledby="alert_label" aria-describedby="alert_msg">
<div id="alert-box">
<h2 id="alert_label">Login Failed</h2>
<p id="alert_msg">That username or password didn't work.</p>
<button id="cancel-button">Cancel</button>
</div>
</div>
</div>
A well-defined critical message alerts benefits majorly the below users.
- People with cognitive disabilities
- People using speech input
- People with limited dexterity
- People using keyboard only
- People with visual disabilities
<div class="autocomplete">
<form id="contact-us" onsubmit="return checkError(this)" method="post">
<label for="username">Username</label>
<input name="username" id="username" type="text" autocomplete="name">
<label for="password">Password</label>
<input name="password" id="password" type="password" autocomplete="current-password">
<input type="submit" class="alert-button" id="alert-button" name="alert-button" value="SIGN IN">
</form>
<div id="alert-modal" role="alertdialog" aria-modal="true" aria-labelledby="alert_label" aria-describedby="alert_msg">
<div id="alert-box">
<h2 id="alert_label">Login Failed</h2>
<p id="alert_msg">That username or password didn't work.</p>
<button id="cancel-button">Okay</button>
</div>
</div>
</div>
#alert-modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1;
}
.alert-button {
background-color: #003057;
border: 1px solid #000;
color: #fff;
padding: 5px 10px;
text-align: center;
text-decoration: none;
display: block;
font-size: 1.2rem;
border-radius: 5px;
cursor: pointer;
margin: 1rem auto;
width: 30%;
}
.alert-button:hover {
background-color: #037d76;
}
#alert-box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: auto;
max-width: 450px;
padding: 20px;
background-color: #fff;
text-align: center;
border-radius: 5px;
}
#alert-box h2 {
margin-top: 0;
}
#alert_msg {
margin-bottom: 1rem;
}
#cancel-button {
background-color: #f44336;
border: 1px solid #000;
color: #fff;
padding: 5px 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 1.2rem;
border-radius: 5px;
cursor: pointer;
}
#alert-modal[aria-hidden="true"] {
display: none;
}
#alert-modal[aria-hidden="false"] {
display: block;
}
#alert-modal[aria-hidden="false"] + #main-content {
opacity: 0.5;
}
#alert-box[role="dialog"] {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
padding: 20px;
background-color: #fff;
text-align: center;
border-radius: 5px;
}
#alert-box[role="dialog"][aria-labelledby="alert-heading"] {
position: relative;
padding: 0;
}
#alert-box[role="dialog"][aria-labelledby="alert-heading"] h2 {
position: absolute;
}
:focus {
outline: 2px solid #000;
outline-offset: 1px;
}
h1, .autocomplete {
text-align: left;
}
.autocomplete {
position: relative;
max-width: 334px;
width: 100%;
margin: 80px auto 30px;
}
label {
display: block;
margin-top: 1rem;
font-size: 1.1rem;
}
.errText {
color: #af0404;
}
input {
display: block;
margin-bottom: 0.2rem;
padding: 0.8rem;
border: 1px solid #8e8e8e;
line-height: 1.15;
width: 90%;
border-radius: 4px;
}
let alertButton = document.getElementById("alert-button");
let cancelButton = document.getElementById("cancel-button");
let alertModal = document.getElementById("alert-modal");
let error = document.getElementById("error");
function checkError(data) {
let i = 0;
let focuss ="";
document.querySelectorAll("span.errText").forEach(function(a){
a.previousSibling.removeAttribute('aria-describedby');
a.previousSibling.removeAttribute('aria-invalid');
a.remove();
});
let span_field = '';
let elem_event_name = '';
if (data['username'].value == "") {
span_field = document.createElement('span');
span_field.setAttribute('class', 'errText');
span_field.setAttribute('id', 'err_' + i);
span_field.innerHTML = 'Error: Please enter your username.';
elem_event_name = document.getElementById('username');
elem_event_name.setAttribute('aria-describedby', 'err_' + i);
elem_event_name.parentNode.insertBefore( span_field, elem_event_name );
elem_event_name.setAttribute('aria-invalid','true');
if (focuss == "") {
focuss = "username";
}
i++;
}
if (data['password'].value == "") {
span_field = document.createElement('span');
span_field.setAttribute('class', 'errText');
span_field.setAttribute('id','err_' + i);
span_field.innerHTML = 'Error: Please enter your Password.';
elem_event_name = document.getElementById('password');
elem_event_name.setAttribute('aria-describedby', 'err_' + i);
elem_event_name.parentNode.insertBefore( span_field, elem_event_name );
elem_event_name.setAttribute('aria-invalid', 'true');
if (focuss == "") {
focuss = "password";
}
i++;
}
if (i != 0) {
document.getElementById(focuss).focus();
alertModal.style.display = "block";
cancelButton.focus();
cancelButton.addEventListener("click", function() {
alertModal.style.display = "none";
document.getElementById('username').focus();
});
return false;
}
}
Login Failed
That username or password didn't work.