NB: This page is archived without styles. Go to our home page or read my blog.

Stylish, accessible forms

I can't think of how many times I have compromised on a form's visual design because of looming deadlines. So I made a form 'template' styled with CSS for me and anyone who might be interested.

I can't think of many web sites that don't include at least one form, and I can't think how many times I have compromised on a form's visual design because of looming deadlines, leaving a Must get around to styling this form properly comment in the code.

Form design can often be an after-thought, so I thought I'd make a form 'template' styled with CSS and post it here for anyone who might be interested. (Update available).

Accessible forms

WebAIM published an article that concentrates on creating accessible forms. The article reminds us to,

The form XHTML

Although form elements will change according to the site and form purpose, basic elements are always roughly the same. So I thought I would use the example of a 'create an account' form.

I've used two fieldsets to group related fields, personal and password information. I have also ignored the whining of Bobby and not used 'placeholder' text in any input boxes. Discussions over at Accessify Forum have indicated that this is no longer required for modern screen-readers. Finally I decided that it's unnecessary to use tabindex because the form elements are already logically ordered and I will use CSS to lay out their visual positioning.

<form id="example-form" method="post" action="">
<fieldset>
<legend>Personal information</legend>

<label for="fm-req_forename">First name</label>
<input type="text" name="fm-req_forename" id="fm-req_forename" />
<br />

<label for="fm-req_surname">Surname</label>
<input type="text" name="fm-req_surname" id="fm-req_surname" />
<br />

<label for="fm-eml_email">Email</label>
<input type="text" name="fm-eml_email" id="fm-eml_email" value=" " /> 
</fieldset> 

<fieldset> 
<legend>Password</legend> 

<label for="fm-req_password">Choose a password</label> 
<input type="text" name="fm-req_password" id="fm-req_password" /> 
<br /> 

<label for="fm-req_confirm">Confirm password</label> 
<input type="text" name="fm-req_confirm" id="fm-req_confirm" />
<br /> 
</fieldset> 

<input type="submit" name="Submit" value="Submit"> 

</form>

Unsemantic additions

I have added <br> tags after each form element. These are not semantically necessary, but they tidy things up when viewing without style-sheets. (If you're not worried about unstyled layout, these can safely be removed.)

To achieve a 'double' border effect inspired by Shaun Inman, I added an extra div around each form input.

<label for="fm-req_forename">Surname</label> 
<div> <input type="text" name="fm-req_surname" id="fm-req_surname" /> </div>

And a <div> with an id of 'fm-submit' to surround the submit button.

Here is the completed form XHTML without any styling.

Adding a little CSS

I'm aiming for a two-column layout using floats. First I'll set up the basic layout and remove those pesky, unsemantic br tags.

form { width : 100%; margin : 0; padding : 0; } 

fieldset { 
float : left; 
width : 40%; 
margin : 0 1em 0 0; 
padding : 1em; 
border : 1px solid #333; 
}

fieldset div br { 
display : none;
}

Now I'll style the legends and labels. I want the labels to sit above the form inputs, so I'll use display:block;. I also want the div that contains the submit button to 'clear' both fieldsets, so I'll set that to clear:both;.

legend { 
font-weight : bold; 
color : #333; 
margin : 0; 
padding : .5em; 
}

label { display : block; }

#fm-submit { clear : both; padding-top : 1em; }

Final styling

I want to add that double border effect. I'll use CSS specifity to target the divs and the form inputs and use the * Selector Hack to get over box model issues in Internet Explorer.

fieldset div { 
width : 196px; /* Width for modern browsers */ 
border : 1px solid #333; 
margin : 0; 
padding : 1px; 
}

* html fieldset div {
width: 200px; /* Width for IE5 */ 
w\idth: 196px; /* Width for IE6 */ 
} 

fieldset div input { 
width: 192px; /* Width for modern browsers */ 
border : 1px solid #666; 
padding : 1px; 
}
						
* html fieldset div input { 
width: 196px; /* Width for IE5 */ 
w\idth: 192px; /* Width for IE6 */ 
}

Sometimes I might want to visually highlight when certain information is required. I can do this by adding class="fm-required" to any <div>s that contain mandatory fields. I wish that there was some other way of doing this without adding extra mark-up.

XHTML

<label for="fm-eml_email">Email</label>
<div class="fm-required"> <input type="text" name="fm-eml_email" id="fm-eml_email" /> </div>

CSS

.fm-required { 
border : 1px solid #900; 
}

Further styling control might be also be gained by adding and ID to each fieldset and styling them (or their elements) with specific CSS.

Here is the final form complete with style and the completed CSS file.

Button styling

Cameron Adams wrote a interesting article on styling buttons with CSS, so I think I'll let him speak for himself on that subject.

Notes

I hope that this exercise might be as helpful as it proved to be for me. The CSS detailed here displays as intended in Firefox, Mozilla 1.6 and 1.7, IE6, IE5.5 and IE5 PC, For some reason yet unknown to me, Netcape 7 PC makes the double borders a few pixels wider than they should be, and Opera 7 PC ignores the floated fieldsets altogether. If anyone can make any suggestions...

Read some more?

Update 25/05/04

Richard Allsebrook made the point that a similar effect to my double borders could be achieved using plain 'ol CSS and no extra <div>. He suggested,

input  { border: 3px double #333; }

Richard is right of course, but my interest was in creating a more stylish form than is possible with just CSS. So I took five minutes to change the style-sheet, using colours selected from my recent Web imitates art column (Warhol's Chairman Mao and Lichtenstein's Hopeless).

Take a fresh look at the completed form.


Replies

  1. #1 On May 23, 2004 05:49 AM Andrew Krespanis said:

    Highly accessible Comrade,

    You continue to add fantastic content to your stylish new site, but in relation to this particular article I must ask; how about a little :focus? Get the jist?

    Patrick Griffiths has also just released a 12 line JS function that blesses IE with respect for :focus aswell....

    Love the site, keep it up!

  2. #2 On May 23, 2004 11:19 AM James said:

    Once again a really really useful column expoding the myths and mysteries surrounding the form element, and presentation of forms. Not sure about the double border mind - not minimalist enough for me! But still that's just down to taste. :-)

  3. #3 On May 23, 2004 01:01 PM Colly said:

    Top-notch overview Andy - some very helpful approaches in there. Forms are so often neglected, that when a designer takes the trouble to nurture a very usable, attractive form, it sticks out a mile.

  4. #4 On May 23, 2004 01:41 PM Gordon Mackay said:

    Hey Andy,

    A great looking and functional bit of coding. I like it!

    Thanks for sharing.

  5. #5 On May 23, 2004 11:54 PM Phil Baines said:

    Very nice Andy. This is fast becoming the most informative blog I read!

  6. #6 On May 24, 2004 11:25 AM Tim said:

    Simon Willison has done a couple of good articles on forms:
    https://www.sitepoint.com/article/simple-tricks-usable-forms
    https://simon.incutio.com/archive/2003/08/12/multiPartForms
    https://simon.incutio.com/code/js/multi-page-form/

  7. #7 On May 24, 2004 12:23 PM Richard@Home said:

    Great article Andy, don't know how I missed your blog in the past but I'll be stopping by regulally from now on.

    On a similar vein I blogged an article on separating the behaviour layer from your documents, with an example form to illustrate:

    https://richardathome.no-ip.com/examples/forms/index.php

    (the full article is here: https://richardathome.no-ip.com/index.php?article_id=227)

  8. #8 On May 24, 2004 03:09 PM Steve Potts said:

    Andy, many thanks for another quality blog post, especially the hilarity of a shot from "Terry and June". I have a query regarding the 'required' type of form control. You write:

    :: Sometimes I might want to visually highlight when certain information is required. I can do this by adding class="fm-required" to any divs that contain mandatory fields.

    In general, I do like the idea of using a special class to indicate a required form field, but I think we're breaking a couple of WCAG1.0 Priority 1 Guidelines in relying on styling and/or colour alone.

    :: 2.1 https://w3.org/TR/WCAG10/wai-pageauth.html#tech-color-convey "Ensure that all information conveyed with color is also available without color, for example from context or markup"
    :: 6.1 https:///w3.org/TR/WCAG10/wai-pageauth.html#tech-order-style-sheets "Organize documents so they may be read without style sheets. For example, when an HTML document is rendered without associated style sheets, it must still be possible to read the document."

    Your article continues:

    :: I wish that there was some other way of doing this without adding extra mark-up.

    Well, we could persuade the audience to believe we're adding 'no extra' mark-up by defining the non-required form fields to possess a 'neutral' class (i.e. instead of {div} we write {div class="fm-not-required"} which is a weak descriptive name, but you get the point). This still doesn't, I worry, circumvent the P1 guidelines, which I interpreted quite strictly.

    At the time of analysing the WAI Guidelines, I couldn't envisage any way of getting around the need to identify 'required' form fields by actually using additional mark-up that is present without colour and without style sheets. This is subjective and interprative etc, but please allow me to explain how I have been attempting to use and recommend accessible forms. So, taking your article code as an example:

    {label for="fm-req_forename"}Surname{/label}
    {div} {input type="text" name="fm-req_surname" id="fm-req_surname" /} {/div}

    That is, keep the nice CSS-styled red border, but add in markup, like an image. All my evaluations and in-house designers have chosen to use an asterisk. I'm no outstanding designer, but I took the 'pseudo-requirement' of an asterisk, converted it to a resizable image [https://www.wats.ca/resources/relativesizing/20] and placed it at the start of the {label} element:

    {label for="fm-req_forename"}{img src="r.gif" class="required" alt="required"} Surname{/label}
    {div} {input type="text" name="fm-req_surname" id="fm-req_surname" /} {/div}

    With this method, those browsing with text/voice browsers/screen readers get "required Surname" instead of just "Surname". Those browsing with style sheets get the image, or if we desire, no image at all if it's sized in CSS to be {0,0} or positioned absolutely off-screen. Of course, we can change the placement so the image is after the prompt in the {label}, but I like it before. Subjectivity reigns.

    Comments and opinions welcome. Keep the topic rolling.

  9. #9 On May 24, 2004 09:14 PM Malarkey said:

    Thanks for the comment Steve,

    My real interest here was the visual look of accessible forms. I think that from a minimal mark-up point of view, the use of attribute selectors and pseudo classes would fulfil most needs. But what of IE? Ho hum...

    I'm not really sure that using images within the label tag actually adds any more meaning that using "Email (required)" as the label, which is of use to sighted and non-sighted people.

  10. #10 On May 25, 2004 10:57 PM David Hawdale said:

    ta andy for all of this l think we should all be of a mind to share what we know ... I dont think this is the time or culture to hold back ... so much to know so little time to know it in etc.

    my expertise isn't in heavyweight css ( i leave that to mr potts ... see above) but what i do know is that web standards, accessibility, design, usability and best customer experiences based on all spaces of design (tech, vis, psych and function) is The Right Thing To Do, and the only way we all going to be able to do The Right Thing To Do is if we pool our knowledge across disciplines rather than keeping it boxed and mystical. so i shall try to reveal the workings of my mind (or what is left of it) too in my space as part of this emergent Brit Pack thing...

    blimey that got heavy ... didn't mean it to ...

  11. #11 On May 25, 2004 11:40 PM Richard Allsebrook said:

    You can achieve the double border look *without* adding the extra div using something along the lines of:

    input {
    border: 3px double #333;
    }

    The drawback is that doesn't allow you to give the outer border a separate colour to the inner one (as in your example).

  12. #12 On May 25, 2004 11:42 PM Richard Allsebrook said:

    Great article Andy, don't know how I missed your blog in the past but I'll be stopping by regulally from now on.

    https://richardathome.no-ip.com/examples/forms/index.php

    (the full article is here: https://richardathome.no-ip.com/index.php?article_id=227)

    On a similar vein I blogged an article on separating the behaviour layer from your documents, with an example form to illustrate:

  13. #13 On May 26, 2004 03:09 PM Malarkey said:

    Thanks guys for an interesting discussion. Following on from Richard's comment, I have tweeked the CSS to show more of my what technique is capable of.

  14. #14 On May 28, 2004 08:37 PM Malarkey said:

    The most excellent Cameron Adams mailed me with a link to his site on a similar topic. His article has some more great tips.

    https://www.themaninblue.com/writing/perspective/2004/03/24/

  15. #15 On June 8, 2004 08:45 AM Fabrice Bonny said:

    For better semantic, better unstyled layout and no additional div and br, I use definition lists in forms. Each label is in a dt and input in a dd.