Giving Clues about Additional Content in a Form
Screen reader interaction with forms usually happens in focus mode. So if there are any non-interactive elements (like a paragraph) in the form, they are prone to be missed. To prevent this, they need to be attached specifically to the form controls. There are several ways to achieve this goal.
While we usually do not favour solutions using ARIA over traditional HTML, regarding forms, in our experience ARIA is the most robust way to associate content to controls.
Instead of referencing all the information, simply give the user a short clue that there is more information somewhere (below a form control, at the end of the page, or wherever):
Working Example
A seemingly very important form
Explanation
The example above shows three ways to give a user clue about additional information:
- For “Full name”, a clue was appended to the <label> and hidden visually. For more information about this, read Hiding elements visually by moving them off-screen.
- For “Biography”, a clue was added anywhere on the page, then hidden completely and referenced to the input using aria-describedby. For more information about this, read Hiding elements from all devices.
- For “Terms and conditions”, the label text was changed so it gives a clue itself (making it “self speaking”). This does not only serve screen reader users, but also visual users who could miss the terms and conditions because of not scrolling enough vertically.
Code
<h1>
A seemingly very important form
</h1>
<form>
<div class="control">
<label for="full_name">Full name <span class="visually-hidden">For additional info read below</span></label><input id="full_name" type="text" />
<div class="description">
<p>
Please tell us your name.
</p>
<p>
A name typically consists of a first and a last name.
</p>
<p>
Some people also have a middle name. Or more than one.
</p>
<p>
Because of that, we offer a single input here, instead of one for each kind of name.
</p>
<p>
Some cultures even have habits of naming that are very different to ours, so it's really hard (if not impossible) to define a offer an input mask that's working for all. This is another reason why having a single input works fine here.
</p>
</div>
</div>
<div class="control">
<label for="biography">Biography</label><textarea aria-describedby="biography_description" id="biography"></textarea>
<div class="description">
<p>
Please tell us something about your history.
</p>
<p>
If you don't know what a "biography" is, please visit the <a href="https://en.wikipedia.org/wiki/Biography">Wikipedia page about "Biography"</a>.
</p>
</div>
</div>
<div class="control">
<input id="accept_agbs" type="checkbox" /><label for="accept_agbs">I accept the terms and conditions (available at the bottom of this page)</label>
</div>
<input type="submit" value="Submit" />
<div id="biography_description">
For additional info read below
</div>
<div id="accept_agbs_description">
<h2>
Terms and conditions
</h2>
<h3>
Definitions
</h3>
<p>
Some definitions that nobody ever will read.
</p>
<h3>
Scope of Our Service
</h3>
<p>
More information that nobody ever will read.
</p>
<ul>
<li>
Very important note
</li>
<li>
Another important note
</li>
<li>
Maybe less important note
</li>
<li>
Again, very important note
</li>
</ul>
<h3>
Correspondence and Communication
</h3>
<p>
Still: nobody will ever read this information.
</p>
<p>
But at least let's put a link to Google here: <a href="https://www.google.ch/search?q=what+are+terms+and+conditions">What are terms and conditions?</a>
</p>
<h3>
Disclaimer
</h3>
<p>
Yeah, you know what I mean: never-ever-read-information here.
</p>
<h3>
Etc.
</h3>
<p>
Etc. etc. etc.
</p>
</div>
</form>
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
left: -10000px;
overflow: hidden;
}
.control, fieldset {
margin: 6px 0;
}
label {
display: inline-block;
width: 120px;
vertical-align: top;
}
input + label {
width: auto;
}
.description {
margin-top: 0;
margin-left: 120px;
}
fieldset .description {
margin-left: 22px;
}
ul {
margin-top: 0;
}
p {
margin: 0;
}
#biography_description {
display: none;
}
NIL