Fancy Form Design Using CSS Article

By Cameron Adams
Required Fields and Error Messages

There are often little extra bits of information that you want to convey on a form, and they should be equally as accessible as the text label elements for the form element. In fact, to ensure that they’re accessible, they should be included in the label itself. There are two types that we’ll look at here: required fields and error messages.

Indicating Required Fields

The easiest and most accessible way of indicating the required fields on a form is to write “required” after the form label. This addition is not only read out by screenreaders, but it also means that an extra symbol key doesn’t need to be provided for visual users, as is the case should you choose to mark required fields with an asterisk or other symbol.

To emphasize the importance of the information, we can add the text “required” inside an em element, which also gives us a stylable element to differentiate the “required” text from the label text:

required-fields.html (excerpt)      
<label for="name">        
Name: <em>required</em>       


To give the em its own little place on the form, we can set it to display: block, and change the appearance of the text:

required-fields.css (excerpt)       

label em {        
display: block;        
color: #060;        
font-size: 85%;        

font-style: normal;        
text-transform: uppercase;      

Our “required” markers now look like Figure 24.

Figure 24: Form fields marked with textual “required” markers (See larger image in new window.)

However, the asterisk, or star, has now become a common tool for marking required fields, possibly due to its brevity. But it doesn’t have much meaning outside the visual context — most screenreaders will read an asterisk character as “star.” So you end up with a label being “Email address star” — a little confusing for the user.

For accessibility purposes, instead of including an actual asterisk character next to the form label, it’s actually better to include an inline image of the asterisk, with alt text saying “required.” This means that screenreader users will hear the word “required” instead of just “star,” which is a lot more helpful. If you are using an image, you should include a key at the top of the form to let visual users know exactly what it means.

We still want to emphasize the fact that the label is required, so we just replace the text “required” inside the em element with the image of an asterisk:

required-fields-star1.html (excerpt)       

<label for="name">        
Name: <em><img src="images/required_star.gif"        
alt="required" /></em>       


This replacement doesn’t actually need any styling; we can leave the em as an inline element and the asterisk will appear directly next to the form label:

Figure 25: Inline asterisk marking required fields (See larger image in new window.)

Or, we can use some CSS to position the image absolutely and have it more closely associated with the form element itself:

required-fields-star2.css (excerpt)      
label {        
position: relative;        

float: left;        
width: 10em;        
margin-right: 1em;      

label em {        
position: absolute;        
left: 10em;        
top: 0;       


When positioning the em absolutely, it’s important to position its parent (the label) relatively, so that when we specify some coordinates for the em, they will be relative to the label‘s top-left corner. The star image should be positioned in the gap between the label and the form element (created by the label‘s right margin), so the value for the em‘s left will depend upon what we’ve set there. Setting the top value for the em is just a precaution in case the image has wrapped onto a new line.

By taking this course of action, we’ll end up with a much more orderly series of “required” markers, as shown in Figure 26.

Figure 26: Required fields marked with absolutely positioned image of a star, aligned against form elements (See larger image in new window.)

Handling Error Messages

Error messages are handled in almost the same way as required markers. In order to be read out as a screenreader user places focus on the appropriate form element, they should form part of the label:

error-fields1.html (excerpt)      
<label for="name">        
Email: <strong>This must be a valid email address</strong>       


The semantic strong element is used to enclose the error message, distinguishing it from a required marker and giving it a stronger emphasis.

The styling is almost the same as it was for the textual “required” marker, except you might want to change the color. A good strong red is suitably alarming:

error-fields1.css (excerpt)       

label strong {        
display: block;        
color: #C00;        
font-size: 85%;        

font-weight: normal;        
text-transform: uppercase;      

This styling produces a layout such as that shown in Figure 27.


Figure 27: Error messages included as part of label element, displayed underneath the label text (See larger image in new window.)

An alternative placement of the error message does exist, but it depends upon a couple of prerequisites. The error message can be placed to the right of the form element as long as:

  • The maximum width of any of the form elements is known.
  • The error message is unlikely to wrap.

This placement involves the error message being positioned absolutely, so we must know in advance how far to move the error. Absolute elements are outside the flow of the document, so the other content will not adjust to accommodate the error message if it starts wrapping. If the design can be reconciled with these two problems, then the CSS for the job is:

error-fields2.css (excerpt)      
label {        

position: relative;        
float: left;        
width: 10em;        
margin-right: 1em;       

label strong {      
position: absolute;      
left: 27em;       

top: 0.2em;      
width: 19em;      
color: #C00;      
font-size: 85%;       

font-weight: normal      
;text-transform: uppercase;      

Again, because the strong element is being positioned absolutely, its parent label must be positioned relatively to allow us to move the error message relative to the label itself.

The width of the error message is dictated by the space following the form element. The left is calculated by adding together the width of the form element, plus the width of the label, plus any extra space we need in order to align the error message properly.

Figure 28 shows how it ends up when viewed in the browser.

Figure 28: Error messages as part of the label element, displayed using absolute positioning (See larger image in new window.)

Inaccessible Error Text Solutions It is possible to position the error text to the right of the text fields by changing the source order of the HTML But this either:

  • places the error text outside the label
  • involves nesting the form element inside the label and placing the error text after the form element

Both of these solutions are inaccessible because screenreaders will most likely fail to read out the error message when the form element is focused.

In conjunction with right-positioning the error messages, we can also include error icons, to further highlight the problem areas on the form. The error icon is included in the HTML with an appropriate alt attribute:

error-fields3.html (excerpt)       

<legend>Contact Details</legend>        

<label for="name">        
Email: <strong><img src="images/error_cross.gif"        

alt="Error" /> This must be a valid email address        

<input id="name" name="name" class="text" type="text" />        


We can now move it to the left of the form elements using absolute positioning. Because its parent (the strong element) is already absolutely positioned, any movement we make will be relative to that parent, so, effectively, we have to move it in a negative direction in order to shift it back over to the left:

error-fields3.css (excerpt)      
label strong img {        

position: absolute;        
left: -16em;      

This adjustment equates to the width of the form element, plus a little bit extra for spacing, so we’ll get a nicely positioned icon, such as you can see in Figure 29.


Figure 29: Error messages displaying to right of form elements, in combination with error icon on left (See larger image in new window.)


Now that you’ve finished this chapter, you have no excuse for producing inaccessible forms that use tables for positioning!

We’ve worked through the correct and effective labeling, grouping, layout, and styling of form elements, anticipating and solving potential problems of compatibility and accessibility along the way. With the code provided here you’ve got quite a few different options for how you want your forms laid out, but there’s still more you can do by combining and experimenting with different styles, form elements and layouts.

If there’s an underlying message of this chapter, it’s just to keep in mind that no matter what you do, your forms have to be usable and accessible above everything else. Forms, at the end of the day, are really all about your users being able to provide information and tell you what they want as easily as possible. Of course, there are other aspects of the site where usability comes into play — you might like to check out the Navigation and Tables chapters, also included in The Art and Science of CSS, and don’t forget to download a PDF of this chapter!

Go to page: 1 | 2 | 3 | 4 | 5 | 6 | 7
  • alex

    Very nice. A big big thanks!

  • Peter Bickford

    Great article (and one that’ll undoubtedly have me reworking parts of my own sites in the future!). One small note: check the code on p2 and p3 to remove the extraneous tags, possible inserted by your content management system. They had me scratching my head a bit…


  • http://localhost rikin

    The nested fieldset subgrouping does not work well for me. The labels for “checkboxes” appear underneath the square boxes. Which setting do I play with? I tried several but it wouldn’t display checkboxes and their labels on the same line.

    Thanks. Great tutorail!

Get the latest in Front-end, once a week, for free.