Sensory Characteristics
Sometimes websites contain instructions based on sensory characteristics such as shape, color, location and so on. Though it is perceivable for sighted users, it is difficult to understand for screen reader users.
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.
- Instructions based on shape, color, location and so on SHOULD be accompanied by equivalent text.
-
Instead of highlighting the color, shape, and so on of the interactive element, the label/textual
description of the interactive element SHOULD be highlighted.
For example, in a game, a green color button along with the text “Next level” is provided to move to the next level.
A well-defined page with either no sensory characteristics or with equivalent text majorly benefit the below users.
- People with cognitive disabilities
- People with visual disabilities
<div id="error" tabindex="-1" role="alert">
</div>
<ul id="errorderlist"></ul>
<form id="contact-us" onsubmit="return checkError(this)" method="post">
<p>
<strong>Fields marked with asterisk (<span class="span">*</span>)
are mandatory.</strong>
</p>
<div class="form-control">
<label for="firstname">
First Name: <span class="span">*</span>
</label>
<input type="text" name="firstname" id="firstname"
autocomplete="given-name" aria-required="true">
</div>
<div class="form-control">
<label for="lastname">
Last Name: <span class="span">*</span>
</label>
<input type="text" name="lastname" id="lastname"
autocomplete="family-name" aria-required="true">
</div>
<div class="form-control">
<label for="email">Email: <span class="span">*</span></label>
<input type="email" id="email" autocomplete="email" name="email"
aria-required="true">
</div>
<div class="form-control">
<label for="phone">Phone: <span class="span">*</span></label>
<input type="tel" name="phone" autocomplete="tel" id="phone" aria-required="true" maxlength="14">
</div>
<input name="submit" id="submit" type="submit" value="Submit">
</form>
body {
font-style: Helvetica,Verdana,sans-serif;
font-size: 1rem;
}
input,textarea {
display: block;
margin-bottom: 0.2rem;
padding: 0.8rem;
border: 1px solid #8e8e8e;
line-height: 1.15;
width: 40%;
border-radius: 4px;
}
input[type=submit] {
background-color: #003057;
border: 2px solid #000;
border-radius: 10px;
color: #fff;
display: inline-block;
line-height: 1.15;
padding: 0.35rem 1rem;
width: auto;
text-align: center;
text-decoration: none;
margin: 0 2rem 0 0;
font-size: 1rem;
vertical-align: middle;
}
input[type=submit]:hover,
input[type=submit]:focus {
background-color: #068379;
cursor: pointer;
text-decoration: none;
}
.span { color: #be0000; }
.errText { color: #af0404; }
.form-control { margin-bottom: 0.8rem; }
#error {
color: #af0404;
font-weight: 600;
}
#errlist { color: #af0404; }
#errorderlist li { margin-top: 5px; }
@media screen and (max-width: 600px) {
#contact-us { width: 100%; }
input,
textarea {
width: 90%;
}
}
function validateNumber(input) {
let re = /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im;
return re.test(input)
}
function isNumber(evt) {
evt = (evt) ? evt : window.event;
let charCode = (evt.which) ? evt.which : evt.keyCode;
if (charCode > 31 && (charCode < 48 || charCode > 57) && charCode != 45 && charCode != 40 && charCode != 41) {
evt.preventDefault();
}
// return true;
}
function checkError(data) {
// let form= document.getElementById('contact-us')
let i = 0;
let phone = data['phone'].value;
let focuss ="";
document.querySelectorAll("#errorderlist li").forEach(function(a) {
a.remove();
});
document.querySelectorAll("span.errText").forEach(function(a) {
a.previousSibling.removeAttribute('aria-describedby');
a.previousSibling.removeAttribute('aria-invalid');
a.remove();
});
// validate firstname
if (data['firstname'].value == "") {
let span_field = document.createElement('span');
span_field.setAttribute('class', 'errText');
span_field.setAttribute('id', 'err_'+i);
span_field.innerHTML = 'Error: Please enter your first name.';
let elem_event_name = document.getElementById('firstname');
elem_event_name.setAttribute('aria-describedby', 'err_'+i);
elem_event_name.parentNode.insertBefore( span_field, elem_event_name.nextSibling );
elem_event_name.setAttribute('aria-invalid', 'true');
let err_summary_list = document.createElement('li');
let err_summary_anchor = document.createElement('a');
err_summary_list.appendChild(err_summary_anchor);
err_summary_anchor.setAttribute('href', '#firstname');
err_summary_anchor.setAttribute('id', 'errlist');
document.getElementById("errorderlist").appendChild(err_summary_list);
if (focuss == "") {
focuss = "firstname";
}
i++;
} else if ((isNaN(data['firstname'].value)) == false) {
let span_field = document.createElement('span');
span_field.setAttribute('class', 'errText');
span_field.setAttribute('id', 'err_'+i);
span_field.innerHTML = 'Error: Name cannot include numbers.';
let elem_event_name = document.getElementById('firstname');
elem_event_name.setAttribute('aria-describedby', 'err_'+i);
elem_event_name.parentNode.insertBefore( span_field, elem_event_name.nextSibling );
elem_event_name.setAttribute('aria-invalid', 'true');
let err_summary_list = document.createElement('li');
let err_summary_anchor = document.createElement('a');
err_summary_list.appendChild(err_summary_anchor);
err_summary_anchor.setAttribute('href', '#firstname');
err_summary_anchor.setAttribute('id', 'errlist');
document.getElementById("errorderlist").appendChild(err_summary_list);
if (focuss == "") {
focuss = "firstname";
}
i++;
}
// validate lastname
if (data['lastname'].value == "") {
let span_field = document.createElement('span');
span_field.setAttribute('class', 'errText');
span_field.setAttribute('id', 'err_'+i);
span_field.innerHTML = 'Error: Please enter your last name.';
let elem_event_name = document.getElementById('lastname');
elem_event_name.setAttribute('aria-describedby', 'err_'+i);
elem_event_name.parentNode.insertBefore( span_field, elem_event_name.nextSibling );
elem_event_name.setAttribute('aria-invalid', 'true');
let err_summary_list = document.createElement('li');
let err_summary_anchor = document.createElement('a');
err_summary_list.appendChild(err_summary_anchor);
err_summary_anchor.setAttribute('href', '#lastname');
err_summary_anchor.setAttribute('id', 'errlist');
document.getElementById("errorderlist").appendChild(err_summary_list);
if (focuss == "") {
focuss = "lastname";
}
i++;
} else if ((isNaN(data['lastname'].value)) == false) {
let span_field = document.createElement('span');
span_field.setAttribute('class', 'errText');
span_field.setAttribute('id', 'err_'+i);
span_field.innerHTML = 'Error: Name cannot include numbers.';
let elem_event_name = document.getElementById('lastname');
elem_event_name.setAttribute('aria-describedby', 'err_'+i);
elem_event_name.parentNode.insertBefore( span_field, elem_event_name.nextSibling );
elem_event_name.setAttribute('aria-invalid', 'true');
let err_summary_list = document.createElement('li');
let err_summary_anchor = document.createElement('a');
err_summary_list.appendChild(err_summary_anchor);
err_summary_anchor.setAttribute('href', '#lastname');
err_summary_anchor.setAttribute('id', 'errlist');
document.getElementById("errorderlist").appendChild(err_summary_list);
if (focuss == "") {
focuss = "lastname";
}
i++;
}
// validate email address
if (data['email'].value == "") {
let span_field = document.createElement('span');
span_field.setAttribute('class', 'errText');
span_field.setAttribute('id', 'err_'+i);
span_field.innerHTML = 'Error: Please enter email.';
let elem_event_name = document.getElementById('email');
elem_event_name.setAttribute('aria-describedby', 'err_'+i);
elem_event_name.parentNode.insertBefore( span_field, elem_event_name.nextSibling );
elem_event_name.setAttribute('aria-invalid', 'true');
let err_summary_list = document.createElement('li');
let err_summary_anchor = document.createElement('a');
err_summary_list.appendChild(err_summary_anchor);
err_summary_anchor.setAttribute('href', '#email');
err_summary_anchor.setAttribute('id', 'errlist');
document.getElementById("errorderlist").appendChild(err_summary_list);
if (focuss == "") {
focuss = "email";
}
i++;
} else {
let str = data['email'].value;
let filter =/^(\w+(?:\.\w+)*)@((?:\w+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
if (filter.test(str)) {
let after_at = str.substring(str.indexOf('@') + 1);
let before_dot = after_at.split(".");
after_at = before_dot[0];
} else {
let span_field = document.createElement('span');
span_field.setAttribute('class', 'errText');
span_field.setAttribute('id', 'err_'+i);
span_field.innerHTML = 'Error: Please enter a valid email address. For example: john@abc.com.';
let elem_event_name = document.getElementById('email');
elem_event_name.setAttribute('aria-describedby', 'err_'+i);
elem_event_name.parentNode.insertBefore( span_field, elem_event_name.nextSibling );
elem_event_name.setAttribute('aria-invalid', 'true');
let err_summary_list = document.createElement('li');
let err_summary_anchor = document.createElement('a');
err_summary_list.appendChild(err_summary_anchor);
err_summary_anchor.setAttribute('href', '#email');
err_summary_anchor.setAttribute('id', 'errlist');
document.getElementById("errorderlist").appendChild(err_summary_list);
if (focuss == "") {
focuss = "email";
}
i++;
}
}
// Validate phone number
if (data['phone'].value == "") {
let span_field = document.createElement('span');
span_field.setAttribute('class', 'errText');
span_field.setAttribute('id', 'err_'+i);
span_field.innerHTML = 'Error: Please enter your phone number.';
let elem_event_name = document.getElementById('phone');
elem_event_name.setAttribute('aria-describedby', 'err_'+i);
elem_event_name.parentNode.insertBefore( span_field, elem_event_name.nextSibling );
elem_event_name.setAttribute('aria-invalid', 'true');
let err_summary_list = document.createElement('li');
let err_summary_anchor = document.createElement('a');
err_summary_list.appendChild(err_summary_anchor);
err_summary_anchor.setAttribute('href', '#phone');
err_summary_anchor.setAttribute('id', 'errlist');
document.getElementById("errorderlist").appendChild(err_summary_list);
if (focuss == "") {
focuss = "phone";
}
i++;
}
else if (!validateNumber(phone)){
let span_field = document.createElement('span');
span_field.setAttribute('class', 'errText');
span_field.setAttribute('id', 'err_'+i);
span_field.innerHTML = 'Error: Please enter a valid contact number.';
let elem_event_name = document.getElementById('phone');
elem_event_name.setAttribute('aria-describedby', 'err_'+i);
elem_event_name.parentNode.insertBefore( span_field, elem_event_name.nextSibling );
elem_event_name.setAttribute('aria-invalid', 'true');
let err_summary_list = document.createElement('li');
let err_summary_anchor = document.createElement('a');
err_summary_list.appendChild(err_summary_anchor);
err_summary_anchor.setAttribute('href', '#phone');
err_summary_anchor.setAttribute('id', 'errlist');
document.getElementById("errorderlist").appendChild(err_summary_list);
if (focuss == "") {
focuss = "phone";
}
i++;
}
if (i != 0) {
document.getElementById('error').innerHTML = "Following form consists of "+ i +" error(s). Please fix the errors and try again.\n
";
document.getElementById('error').style.display = 'block';
document.getElementById('error').focus();
return false;
}else{
alert("Form Submitted Successfully");
document.getElementById("contact-us").reset();
document.getElementById('error').innerHTML="";
return false;
}
}