Accessible, stylish form layout

Yes, HTML forms are the worst things known to web designers. Yes, HTML forms have to be accessible and
usable. No, HTML forms do not have to be an eyesore.

As the unwanted orphan of web pages, forms are neglected by many and designed by few. Most people
are content to put in some text fields, some bold text and a submit button. I've come across quite a few
tutorials on how to make forms as eye-achingly colourful
as possible, and on how to customise form widgets in
ways that Safari promptly ignores, but I can't find any articles telling you how to use semantic, accessible code
along with CSS to make better form layout. Layout is where most of the problems lie with forms – grouping
objects, labeling fields, helping the user cope with the amount of information that they have to fill in. The
only article I could find relating to Standards and form layout was a rather oldish
Eric Meyer throwback. So, as a service to the
web design community, I have journeyed into the foul depths of forms for the last few days, and come out
all the more wiser. Here is the tale of my travels ...

The semantics

The code I've used in my form templates is all the same, and entirely semantic.
There's more than enough valid form data tags to give CSS the ability to style all elements,
so there's no need to introduce any superfluous divs or spans. (Note: The "horizontal" and "margin"
forms mightn't look terribly hot in Safari or Opera. This is easily rectified using divs to clear the floated elements,
but I didn't want to clutter up the code. Feel free to add them in your own experimentation)

For usability and accesibility reasons, every form element on a page should have an associated label. Not only do
labels let you focus a form element by clicking on its label text (no more fiddling around clicking on the exact circle that
is the radio button), but they enable non-visual browsers to create an association between the label text and the
form element, allowing each distinct item to be more readily identified.

To assign a label to a form element, you need to give the element an id, then reference that id using the label's
"for" attribute:

The form element doesn't have to be nested inside the label tag, but I've used this method as it gives an extra
level for the CSS to refer to.

Aside from the label tag, the only other item that may be unfamiliar to you is the "fieldset" tag. A fieldset tag
groups together semantically similar form elements, for instance the three elements that could make up someone's name:
title, first name, last name. By grouping these three elements using a fieldset tag it helps to quantify their
association, and allow visual and non-visual browsers alike to more easily navigate a form. The legend tag
works alongside the fieldset tag, providing it with a title, like so:

Once you've coded up the HTML for your form, it's then a simple matter of applying some CSS rules to turn it
from an inline mess to a floated wonder. Each of the templates has a description of how it's styled at the top,
this should help you if you decide to play around with the CSS rules. I've purposely not styled any of the form elements themselves (beyond width and positioning), as the focus here
is on structure and layout. Undoubtedly, further styling would increase the aesthetics and usability of the forms,
but such design is much more site-dependent and best left to your own imagination.

Gripes

Probably the only difficulty in styling semantic forms is the legend tag. It is insufferably variable across browsers.
In Mozilla, the legend tag is not left-indented from the body of the fieldset, in IE and Opera it is. In Mozilla,
the legend tag is positioned in between the fieldset's border and its content, in IE and Opera it is positioned inside the content.
This makes it very hard to move the legend inside the fieldset border, or position it flush to the left of the fieldset, as you
get varying effects across browsers. I'd use a CSS hack, but that's not me. This means you either neglect the legend tag – and
its obvious accessibility benefits – for hx tags (as in my last example),
or you retain the standard fieldset border, with legend at the top. I don't know ... I'm growing to like the fieldset borders.

Hopefully my efforts haven't been in vain, and you find something useful in my form experimentation; I at least know that I did.
If you have any queries about the techniques involved, don't hesitate to ask.

Previous Entry

Next Entry

Comments

1/72

Your efforts are most certainly not in vain; you've provided a clear explanation and great examples that make this is an excellent resource, thanks!

2/72

Brad commented on 24 March 2004 @ 11:47

Nice work on this one. I really like your use of fieldsets.

One thing: what if the LABEL and INPUT tags were separated? Like so:

<label for="textid">Name</label><input id="textid" type="text" />

Why would you do this? I think that's what the FOR attribute is used..err....for (so to speak).If you wrap the INPUT tag inside the label, you don't need to refer to it with the FOR attribute I think. Correct me if I'm wrong. :)

Anyway that's not a gripe, just a curiosity. These examples are fantastic. Thanks! :)

11/72

Great work! Form layout for complex forms is still a very unspoilt landscape and I think that most people are still using tables for its positioning.

I always wondered if the W3C didn't forget to design some kind of form layout grid or so.

A bit of topic, but I think that the future of forms will definately be some kind of WYSIWYG tool where you can design forms in and that spits out standards compliant code. Something like Microsoft's InfoPath, but then with CSS and XFORMS support.

12/72

I do have one question, why did you opt for ID= as opposed to Class= in the styling? Seems to me that Classes are reusable within a page where IDs must be unique. That ability to reuse might come in handy in a complicated form. Or I am missing something?

I must say I never seen such beautiful artwork and great design put together in such copious amounts anywhere else ever. Your site raises the bar. Great work!

Thank you,t.

13/72

Re: IDs for the form elements (I think you're asking?). IDs are required for any label's "for" attribute to work -- you have to be referencing an ID for a relationship to be created between the label and the target element.

None of the CSS uses the IDs as a matter of styling (except for distinguishing between the different styles of form layout), it's all element & class related.

14/72

hi, maybe i'm retarded but i'm trying to figure out your margined form but only one of your imported style sheets is actually there and it doesnt contain the classes youve used to position your form so i'm having a bit of a rough go of figuring out what you are actually doing. for instance <label class="first" for="title1"> i cant find what the first class is doing...

The "first" class is just there so that the first form element in each fieldset can have some margin-top applied to it. You could use a first-child selector instead of specifying a class, but they don't work in some browsers.

The main trick with the Margin Form is that the labels are floated left, so the label text aligns left, but the input fields are positioned relatively, and moved right, so they line up in columns.

16/72

dawn commented on 2 April 2004 @ 07:37

thank you! (i was looking for the css at themaninblue.com/css/forms.css which would explain why i couldnt find it... heh.)

17/72

The nice thing about nesting input's inside label's, is that you don't need to reference the ID of the input in the label anymore.

Quote from the HTML docs on labels:"To associate a label with another control implicitly, the control element must be within the contents of the LABEL element. In this case, the LABEL may only contain one control element."

20/72

Cool article. Also, you can style the LEGEND tag. I often leave the FIELDSET with no background to avoid the coloring inconsitencies, and a border/background around the LEGEND can make up for the fieldset's blandness.

26/72

Ummmm ... there shouldn't be any colours anywhere. I purposely only changed the structure of the elements.

27/72

Jessica commented on 27 April 2004 @ 10:00

Firstly, to The Man in Blue, thanks for a great website - this has proved very helpful for my own form design.

Secondly, to CSS Newbe regarding the yellow colouring. If you are referring to the colouring of text fields in IE and FF, IE (with the google toolbar installed) will automatically colour fields with names that it recognises e.g. Name, Address etc. Firefox doesn't do this, and so all input fields will appear with the standard colour. This had me tricked for a little while too!

28/72

Joe commented on 13 May 2004 @ 08:03

Greetings! Nice job with this one. Quite outstanding actually.

In applying this on my own, I came across a rather odd behavior that concerns only horizontal and columnar forms.

In Netscape 6 (yeah, I know, I know, quit laughing) you can't see the forms at all - only the fieldset outlines!

Eek.

Well, with some judicious CSS debugging, I discovered that commenting/removing "display: block" within #columnarForm label (and I presume #horizontalForm label) brings them back into view, albeit without the block display for the labels. Sigh.

Any suggestions on how to get around this while keeping the CSS nice and tidy? (I was thinking some DOM-friendly ECMAScript but wanted to give others an oppy to weigh in first.)

30/72

Joe commented on 14 May 2004 @ 03:08

Thanks for the pointer! Yes, that's a page I've gone to often - mighty handy. Alas, it does not appear to have anything that would let me target only Netscape Navigator 6. Or if it does, I'm missing it.

Hmm ...

31/72

Tucker commented on 24 May 2004 @ 11:54

Great article! Itís been such a help.

I have a query, which I hope you can help me with. I want to know if it is possible to mix and match different elements from all your templates!

Iím creating a Columnar Form but some of the elements are horizontal. For example, is it possible to keep the overall form in the Columnar Form but have the Credit Card elements/radio buttons layed out as in the Horizontal Form?

Also, is it possible to have the titles next to the input fields as you have in the Margin Form but still keep the overall form in the Columnar Format?

32/72

Erik Porter commented on 24 May 2004 @ 23:50

Joe,

I've always run into the same problem that you describe In Netscape 6 when trying to style tableless forms. If I remember correctly any number of CSS rules when applied directly to a label tag will cause this, not just display: block. In the past I've had to resort to wrapping labels with an extra span and apply CSS to that to avoid the problem, but I'd be interested in any better solutions snybody has found.

33/72

Francois Gagnon commented on 28 May 2004 @ 06:18

For your information, I'm using Opera 7.50 and the top of this page break badly.

The blue continents are over the text.

34/72

Bryce Ikeda commented on 29 May 2004 @ 05:10

Great examples, clear and concise. I take my hat off to the man in blue, just what I was looking for.

35/72

Joe commented on 2 June 2004 @ 22:51

Greetings! Revisiting the class names for these forms, I'm wondering if it's worth coming up with names other than vertical, columnar, horizontal, margin. Or would that be semantic overkill?

Don't get me wrong - for screen media, perhaps even print, I say these names are spot-on!

I'm thinking more for handheld media (where I'm guessing you'd want all of these variants to effectively be vertical), and perhaps other media as well (?).

36/72

The only attribute that indicates visual description is the id on the forms, and I only used the id so that I could keep all the styles in one CSS file. With only one form you wouldn't need the id.

The textual descriptions of the forms themselves need to have "Vertical", "Columnar" etc. in them, because that's what they're designed for, and what most people will see them as, so their title needs to inform them of this fact.

37/72

But then again, what would I call them otherwise, right? In practice, I've found vertical forms work well in "sidebar" areas of a web page, while the rest work quite nicely in the "main" area.

Depends on the form application, I s'pose. Actually, if I knew only one style was used/permitted in one area of the page, perhaps I could implicitly base it on that. Alas, that's not exactly true in my case. <LOL>

I think what I'll do then is just leave it alone, then have horizontal and columnar effectively styled as "vertical" for handheld media. Possibly margin too. Will keep experimenting ...

38/72

For reference though, my suggestion for legends is to give the legend a border, background colour etc. and make the "Half-in-half-out" problem a feature.

You can even get ultra-cunning (tm) with Javascript and use legends as tabs for a tabbed form interface.

Oh yeah, and your site is gorgeosity itself and I'm jealous 'cos I'm just a coder and can't design. Note full stop.

39/72

Joe D'Andrea commented on 7 July 2004 @ 23:05

Here's an interesting one. When using the form <label><input /></label> ... on MacIE 5.2.3 you actually tab to each LABEL as well as input. At least that's what I think is happening.

Worse, when you're "on the label" the related input field has the input focus but is NOT highlighted (per usual MacIE procedure) ... and to top it off, in this particular mode, any characters entered are echoed back TWICE! "Aieee!"

Workaround: Press "tab" again to get the highlight, and the echo is no more.

(Yes, I use Safari myself, but we've still checked our site in MacIE 5.2.3 - plus a few MacIE devotees still write every now and then with feedback. This was the latest.)

41/72

Apologies for my browser's brain-fart. The page was still relaoding after 20 minutes, and I must have pressed reload.

42/72

Paul Sullivan commented on 14 July 2004 @ 06:30

I have been experimenting with similar layouts for a while and seem to have found a couple of quirks.

1. If you do not nest the input within the label and set border-left on the fieldset then IE indents text-inputs by an amount equivelant to the margin.

2. Gecko seems to have a problem with margin-bottom. If you try to seperate a form element from the bottom border of the fieldset using margin-bottom nothing happens. The same seems to be true of margin-top. Padding works fine.

43/72

2. This happens generally with Firefox et al. I think Eric Meyer may have explained collapsing margins and why they happen, but I'm not sure. I always just use padding in such situations.

44/72

Paul Sullivan commented on 15 July 2004 @ 02:35

Thanks for the reply. Just to correct my earlier post, I meant margin-left not border-left. I have come to the conclusion that this is a variation on the IE double margin bug. I emailed Big John and he asked me to put up a demo of the problem which I am doing. I will let you know what he says.

45/72

Very nice description. I've had to do work on this recently and wish I'd seen it first.

One comment though. From a usability point of view would it be bennificial to check one option on each of the radio buttons?The reasoning: As soon as a user selects one radio option he cannot return to none selected. This may cause confusion over what to do or what effect it may have upon submission. If one radio button is preselected then the user can always return it to the default state and more importantly feel comfortable about the response.

54/72

I only came across this resource now; and I regret I didn't notice it before. It's a lovelly approach; I really like your use of fieldsets. I'm learning styling form fields and your examples cleared much of the messExcept for the ugly google's autofill automatic yellow coloring, even K-Meleon has no problems in displaying the forms the nice way

55/72

vic commented on 11 October 2004 @ 11:36

the column one breaks/wraps on 800x600 res :(

56/72

paolo commented on 19 October 2004 @ 07:26

First off, thank you for posting this info. I have found it helpful.

Now my questions:

Did you test your code with a screen reader and if so which one? I have tried Qualiweb Pro, Simply Web, and JAWS and each of these screen-reading browser had its own problems recognizing HTML form elements, given this code example for a simple search form:

QualiWEB Pro can't find the input text element with the code as written above. The label and input tags must be separated and text written between <label> and </label>. I'm trying to avoid writing label text because the search button image already has the word "search" as a label within itself.

SimplyWeb 2000 pretty much finds everything if I code by your guidelines.

Thanks for any help.

57/72

Kari commented on 23 October 2004 @ 06:06

This is a great resource. thank you.

I am trying to get a grasp on xforms since my development team is starting to do alot of xml and I will need to be styling these interfaces with css. Is there any good css tips available for styling xforms?

61/72

62/72

Wile E. Coyote commented on 7 December 2004 @ 06:12

What about floating textareas? I'm having a hell of a time floating textareas in IE....:-(

63/72

Charlie commented on 20 December 2004 @ 01:31

Hi, I am a newbie so please bear with me, I have looked through the CSS and I cannot ascertain what it is that is styling the border around the legend/fieldsets? also, what would be the correct way to code the Legends without them actually being visible in the browser?

66/72

Ok, the fieldset thing is cool when marking up a SMALL form with a few elements but for LARGE forms, in order to make the form useable and organized, itís hard to beat the simplicity of a TABLE. CSS techniques seem to be somewhat complicated in a place where a simple TABLE would work all around.

67/72

Timothy commented on 19 February 2005 @ 06:07

<span>(As I believed referenced in comments 24-26 and 63) When I view the forms using IE on my browser at home, I get more 'styling' than is explicitly declared. I get nice thin bluish borders around my input fields and the same bluish color for my legend text. Yet, my browser at work and some other locations show the standard black inset input fields and black legend. What is causing my browser at home to make it look more styled?<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p><o:p><span>

Popular Entries

My Book: Simply JavaScript

Simply JavaScript is an enjoyable and easy-to-follow guide for beginners as they begin their journey into JavaScript. Separated into 9 logical chapters, it will take you all the way from the basics of the JavaScript language through to DOM manipulation and Ajax.

Step-by-step examples, rich illustrations and humourous commentary will teach you the right way to code JavaScript in both an unobtrusive and an accessible manner.

About this site

The Man in Blue is the alter ego of Cameron Adams, a Web Technologist in MelbourneSydney, Australia. (That means he does graphic design, HTML/CSS, JavaScript, writing, server-side jiggery pokery, and anything else that takes his fancy that day.)

Cameron has been designing graphical/informational/software things on and off the Web since 1997. You can see more of Cameron's design work on his portfolio, and if you're interested his services are available for hire.