A few months ago, I logged out of my account the American Express website before remembering another task I needed to do, so I clicked the “Log Back In” button they so conveniently displayed. Strangely, the login form I was presented didn’t look the same as the one I was used to seeing on the American Express homepage. This new form had some strange black squiggles above each field.
What the heck are those squiggles? I wondered. A Control-click later, I had inspected one of the squiggles and discovered that it was actually tiny text, the contents of a not-quite-hidden
legend element. I wasn’t surprised with my discovery, after all, most accessibility-aware coders have been using
legends (and their necessary parent
fieldsets) to organize form controls for years. What was different about this implementation was that every field in the form was wrapped in its own
fieldset with its own
legend. And, as if that wasn’t bizarre enough, each
legend contained the same text: “Log In to American Express Online Services”.
Normally, I applaud the use of rich semantics like
fieldset as they provide excellent means by which to organize complex forms. But looking at this form, I surmised that the author knew enough to understand the importance of these elements, but wasn’t really sure how to go about implementing them. It’s the classic well-meaning but misguided markup trap we’ve all fallen into at one time or another. Either that, or American Express’ CMS was suffering from some form of markup-based Tourette’s.
Before we dive into alternative markup approaches, let’s take a quick look at the HTML behind this form. Here’s a brief excerpt:
<div><font class="smalltext"><strong>User ID</strong></font></div> <div> <fieldset class="fieldSetStyle"> <legend class="hideLegend hideLegendIE7">Log In to American Express Online Services</legend> <input maxlength="32" name="UserID" size="20" title="Enter the User Id" value="" onchange="uncheckRememberMe()" height="1"> </fieldset> </div> <div> <fieldset class="fieldSetStyle"> <legend class="hideLegend hideLegendIE7">Log In to American Express Online Services</legend> <input title="Remember My User ID" name="REMEMBERME" type="checkbox" class="checkBox" checked> <font class="smalltext"><strong>Remember Me</strong></font> </fieldset> </div>
Yeah, I know, the author is using a
font element, but let’s table that discussion as I want to focus on
Despite looking quite similar, the version of the login form that appears on the American Express homepage uses no
fieldsets at all and, apart from the names used for each of the form fields, bears little resemblance to the over-
fieldset-ed form. Here’s a brief excerpt of these same fields in that form:
The differences between the two forms lead me to believe the forms were either built by two separate departments or built at two very different times by the same department. The fact that one is written as HTML and the other is serialized as XHTML only reinforces that hypothesis. The inconsistencies between the two are problematic for many reasons, but I’ll get to that discussion in a moment.
Obviously, this form is much more condensed, but it suffers from similarly poor markup practices. However, before we jump in and start refactoring the markup of these two forms, let’s quickly review the raison d’être of
FIELDSETelement allows authors to group thematically related controls and labels. Grouping controls makes it easier for users to understand their purpose while simultaneously facilitating tabbing navigation for visual user agents and speech navigation for speech-oriented user agents. The proper use of this element makes documents more accessible.
LEGENDelement allows authors to assign a caption to a
FIELDSET. The legend improves accessibility when the
FIELDSETis rendered non-visually.
Looking at the markup of the
fieldset-ed form, I think the author was on the right track, just a bit overzealous. If we took his
legend and, instead of using it to wrap the individual fields, used it to wrap the contents of the form as a whole, I think that’d be a win for everyone:
<fieldset class="fieldSetStyle"> <legend class="hideLegend hideLegendIE7">Log In to American Express Online Services</legend> <!-- form contents will go here --> </fieldset>
Of course some might argue, as Derek does, that this form is a too basic for a
legend to be all that helpful, despite being semantically correct. It’s a matter of preference, but if you decide to use the
legend construct, I would suggest a shorter
legend; perhaps, simply, “Log In.”
fieldset wrapper in place, the individual form controls and other associated content can be flowed in. Personally, my preference is to use an ordered list (
ol) to contain each form control in a collection of several (as we see in this login form), but if you have a penchant for
div elements, that’s cool too; as long as your content is organized and makes sense both visually and aurally, the choice is yours:
<fieldset class=“fieldSetStyle”> <legend class="hideLegend hideLegendIE7">Log In to American Express Online Services</legend> <ol> <li> <font class="smalltext"><strong>User ID</strong></font> <input maxlength="32" name="UserID" size="20" title="Enter the User Id" value="" onchange="uncheckRememberMe()" height="1"> </li> <li> <input title="Remember My User ID" name="REMEMBERME" type="checkbox" class="checkBox" checked> <font class="smalltext"><strong>Remember Me</strong></font> </li> <!-- more form content goes here --> </ol> </fieldset>
label or not to
If you’re like me, another aspect of the markup that isn’t sitting quite right with you is the lack of
label elements surrounding the visual labels for the form (e.g. “User ID”). Surely the
label element is more meaningful than
strong? Of course it is, but it’s worth explaining the approach the authors are using here: they have opted to use
title attributes on the form controls rather than
label elements. As you probably know, the
title attribute provides advisory information about the element it is applied to, which certainly makes it a valid choice for form controls.
When a screen reader encounters a form control, it looks to see if the document contains a
label associated with that control. If it finds one, the contents of that
label are read aloud; if it does not find one, it will look to see if the control has a
title attribute. If it finds a
title, that text is read aloud in lieu of a
label. This may very well be the reason the author of these forms chose not to use
It’s certainly a valid method that lines up with the recommendations of WCAG2, but, from my perspective, the
label element would be preferable because
labels benefit both sighted and non-sighted users alike. They are not only visible and clickable by sighted users, but are made available to non-sighted users when the related form control is focused. The
title attribute, in contrast, is only exposed to sighted users as a tooltip when the form control is moused over, meaning that if you want to ensure a sighted user can read that content, you have to include it via a secondary method—as the authors of this form have within the
font > strong combo. That sort of redundancy doesn’t sit well with me because I don’t feel that “Enter the User Id” (the contents of the
title attribute) provides any more context to non-sighted users than “User ID” would if it were a
label. For that reason, I’d simplify the markup and drop the
<fieldset class="fieldSetStyle"> <legend class="hideLegend hideLegendIE7">Log In to American Express Online Services</legend> <ol> <li> <label class="smalltext" for="UserID">User ID</label> <input maxlength="32" id="UserID" name="UserID" size="20" value="" onchange="uncheckRememberMe()" height="1"> </li> <li> <label class="smalltext"> <input name="REMEMBERME" type="checkbox" class="checkBox" checked> Remember Me </label> </li> <!-- more form content goes here --> </ol> </fieldset>
As you can see, each form control has its own
label element. In the case of the “User ID” field, the
label is explicitly associated with the form control using the
for attribute (which references the
id of the associated form control). In the case of the “Remember Me” checkbox, the
label is implicitly associated because it contains that
input, demonstrating the alternate method of
label-control association. It’s worth noting that explicit association is generally preferred if you need to support legacy browsers like IE6, but you can always assign the
for attribute to a
label that is using implicit association as a back-up.
Going the Extra Mile
In a large enterprise like American Express, I can’t say I’m surprised to find two different login forms using entirely different markup and style rules, but that doesn’t mean it’s a good thing. Consistency is important and offers clear benefits in terms of maintainability, usability, and security.
From a user’s perspective, encountering two or more treatments of the same form or interface can be jarring. And when you are dealing with something as important as a person’s finances, it is even more crucial that they feel comfortable and confident that their personal information is secure. Inconsistencies in something as critical as a login form undermine that, making users uneasy or even suspicious that one of the versions might be part of a phishing scheme.
By refactoring the markup and bringing these two login forms (and any others) in line with one another, American Express would reduce their maintenance overhead, increase users’ confidence in their brand, and make users feel more secure using their service. That’s a lot of “bang” for very little “buck.”
Pitfalls to Avoid
- Avoid using an HTML element when you aren’t clear on its purpose.
- Don’t make two elements or attributes do the work one could do (as seen in the
- Don’t repeat yourself by creating more than one codebase (HTML, CSS, etc.) for a reusable component (such as a login form).
Things to Do
- Provide clear labels for your form controls.
legendto group related form controls.
- Keep reused and often-accessed components consistent in look and feel.
A perfect use for
fieldset is when users are asked to provide both a shipping and a billing address for an online purchase. The
legend for “Shipping Address” and “Billing Address” will help to disambiguate between two identically labeled “City” or “Postal/Zip Code” fields.
How would this work with assistive technology such as a screen reader? It depends on the screen reader and its settings, but by default, the JAWS screen reader will read out the text of the
legend before it reads out the name of the field that takes the focus.
What does this mean for the much simpler login form?
<fieldset> <legend>Log In to American Express Online Services</legend> <label for="UserID">User ID</label> <input id="UserID" name="UserID"> <label for="pass">Password</label> <input type=”password” id="pass" name="pass"> </fieldset>
When the user tabs into the User ID field with JAWS active, they will hear something like: “Log In to American Express Online Services, User ID, type in text”
And when they tab into the password field, they will hear: “Log in to American Express Online Services, Password, password, type in text”
And if there were another field? It would read the contents of the
legend before that
For most simple forms, it’s likely that you don’t need a
legend even though they are semantically correct. In this case, a particularly wordy
legend makes it downright unwieldy; for best effect, make sure the
legend text is concise and to the point.