Prettier Accessible Forms
Issue № 218

Prettier Accessible Forms

A note from the editors: While brilliant for its time, this article no longer reflects modern best practices.

It can be time consuming to make web forms both pretty and accessible. In particular, laying out forms where the form label and input are horizontally adjacent, as in the image below, can be a real problem. We used to use tables, which worked well in this scenario—but forms don’t constitute tabular data, so it’s a semantic faux pas.

Article Continues Below

I’ve tried to create a form-styling solution that is both accessible and portable (in the sense that I can move the code from one project to the next). Floats have often provided a solution to my problem, but given the complexity of some layouts and the numerous float bugs associated with Internet Explorer, it’s not always easy to reuse a float solution. I wanted to create something that anyone could easily reuse on any project: a style sheet that, when applied to a correctly marked up HTML form, would produce the basis of the required layout. So here it is—my attempt at portable, accessible forms.

Example Forms
Example Forms

Marking up the form#section2

The most important part of a form is the HTML we use to build it. Fortunately, HTML gives us a nice assortment of tags to build our forms in an accessible way. These are fieldset, legend, and label. If you are unfamiliar with these tags, here’s a brief overview:

fieldset and legend#section3

The fieldset element allows us to group form controls into logical, related “chunks.” legend then allows us to add a caption to that fieldset, which helps users understand the context of the form controls contained within that fieldset. In some screen readers, the legend is associated with each form control within a fieldset and is read out after each tab of the keyboard, so that a particular control can always be referenced back to its legend.

label#section4

The label element is used to associate information with a specific form control, while also enforcing a code-level association between form control information and the control element itself.

Let’s look at a simple fieldset example (line wraps marked » -Ed.):

<fieldset>
  <legend>Delivery Details</legend>
  <ol>
  <li>
      <label for="name">Name<em>*</em></label>
      <input id="name" />
    </li>
  <li>
      <label for="address1">Address<em>*</em></label>
      <input id="address1" />
    </li>
  <li>
      <label for="address2">Address 2</label>
      <input id="address2" />
    </li>
  <li>
      <label for="town-city">Town/City</label>
      <input id="town-city" />
    </li>
  <li>
      <label for="county">County<em>*</em></label>
      <input id="county" />
    </li>
  <li>
      <label for="postcode">Postcode<em>*</em></label>
      <input id="postcode" />
    </li>
  <li>
      <fieldset>
        <legend>Is this address also your invoice »
address?<em>*</em></legend>
        <label><input type="radio" »
name="invoice-address" /> Yes</label>
        <label><input type="radio" »
name="invoice-address" /> No</label>
      </fieldset>
    </li>
  </ol>
</fieldset>

The HTML is fairly simple, but you will notice a few things in the structure. I’m using an ordered list (ol) inside the main fieldset. I’m doing this for two reasons:

  1. I can use each list item (li) as a container for each row in the form, which is handy for styling.
  2. It is, in my opinion, semantically appropriate (i.e. a list of form controls in some kind of logical order).

Additionally, the ol provides additional information for some screen readers that announce the number of list-items when they first encounter the list.

Fields that have two or more control options are nested inside an additional fieldset. This logically groups the control options, as discussed above, and the legend acts as a caption for each option within (in our case, radio inputs). Each option is then wrapped inside its own label tag. This is the most accessible approach, and really aids users of assistive technologies.

Styling the form#section5

The styling of the form is the fun part. My aim was to produce a main forms style sheet that can be imported to give a form the basic structural styling we need. Here it is.

form.cmxform fieldset {
  margin-bottom: 10px;
}
form.cmxform legend {
  padding: 0 2px;
  font-weight: bold;
}
form.cmxform label {
  display: inline-block;
  line-height: 1.8;
  vertical-align: top;
}
form.cmxform fieldset ol {
  margin: 0;
  padding: 0;
}
form.cmxform fieldset li {
  list-style: none;
  padding: 5px;
  margin: 0;
}
form.cmxform fieldset fieldset {
  border: none;
  margin: 3px 0 0;
}
form.cmxform fieldset fieldset legend {
  padding: 0 0 5px;
  font-weight: normal;
}
form.cmxform fieldset fieldset label {
  display: block;
  width: auto;
}
form.cmxform em {
  font-weight: bold;
  font-style: normal;
  color: #f00;
}
form.cmxform label {
  width: 120px; /* Width of labels */
}
form.cmxform fieldset fieldset label {
  margin-left: 123px; /* Width plus 3 (html space) */
}

As you can see, the styles are pretty basic; those with a keen eye will notice the display property set to “inline-block” on the labels. If you are unfamiliar with “inline-block,” here’s an explanation from the W3C site:

This value causes an element to generate a block box, which itself is flowed as a single inline box, similar to a replaced element. The inside of an inline-block is formatted as a block box, and the element itself is formatted as an inline replaced element.

This is the magic, and the good news is that it works in Internet Explorer for both Windows and Mac. If you are tempted to use this value in other scenarios, I must point out that in Internet Explorer for Windows, it only works on elements that have a default display of “inline,” which a label does. The bad news, however, is that Mozilla-based browsers (Firefox, Netscape, etc.) do not directly support this property, but we can fix it, and I’ll come to that shortly.

So, these are the core styles required to give the form its most basic appearance.

I wanted to create a style sheet that contains basic form styles that act as part of a larger library of reusable style rules. In theory, they would not need to be modified by an author, but could simply be included in any site to set the baseline rules. (This core set of form styles is the first part of my vision for creating a library of style sheets that handle the common CSS conundrums.) The best part is that authors who want to modify something like the width of the label elements, can easily overwrite the default further down in the cascade or with a more specific selector. And to truly customize each form, you can add your own styles in a separate style sheet like I have done in this “pretty” form example.

Bugs#section6

As I mentioned above, users of Mozilla-based browsers won’t see what all the fuss is about. Unfortunately, Mozilla does not currently support the “inline-block” display type, which is a bit of a problem. However, Mozilla has a browser-specific display value, “-moz-inline-box”, which acts, for the most part, like “inline-block.” The problem with this value is that if you have a really long label, the text disappears under the adjacent form control. Text does not wrap inside an element displayed as “-moz-inline-box.” But if we place the label text inside an element displayed as “block” inside the “-moz-inline-box” element and give it a width, it behaves as it should.

Adding all that by hand into the document is going to mess up our nice, lean, mean HTML —plus we may decide to change the form layout later, and who wants the extra markup in there? Luckily, there’s an easy way to fix this using JavaScript and the DOM (line wraps marked » -Ed.):

if( document.addEventListener ) »
document.addEventListener( 'DOMContentLoaded', cmxform, false);function cmxform(){
  // Hide forms
  $( 'form.cmxform' ).hide().end();  // Processing
  $( 'form.cmxform' ).find( 'li/label' ).not( '.nocmx' ) »
.each( function( i ){
    var labelContent = this.innerHTML;
    var labelWidth = document.defaultView. »
getComputedStyle( this, '' ).getPropertyValue( 'width' );
    var labelSpan = document.createElement( 'span' );
        labelSpan.style.display = 'block';
        labelSpan.style.width = labelWidth;
        labelSpan.innerHTML = labelContent;
    this.style.display = '-moz-inline-box';
    this.innerHTML = null;
    this.appendChild( labelSpan );
  } ).end();  // Show forms
  $( 'form.cmxform' ).show().end();
}

The JavaScript uses the wonderful JQuery library (which also, obviously, needs to be included) to simplify the processing. I will briefly explain how this works.

Firstly, I hide any form that uses the “cmxform” class.

// Hide forms
$( 'form.cmxform' ).hide().end();

We do this because otherwise the user might see the form “fixing” itself as it renders in the page, which can look a bit strange.

Secondly, using the JQuery methods and a combination of CSS selectors and XPath, I collect all labels that are a direct descendant of an li, that do not have a class of “nocmx”.

$( ‘form.cmxform’ ).find( ‘li/label’ ).not( ‘.nocmx’ ).each( function( i ){ ...

The reason I use the “nocmx” filter is so that users can add that class to labels that require a different styling. This can be very useful, as I have discovered from using this method for a while. Then, for each collected label, a span is created inside to fix the “inline-block” problem.

$( 'form.cmxform' ).find( 'li/label' ).not( '.nocmx' ).each( function( i ){ … }

Finally, all the originally hidden forms are made visible again, and everything looks sweet.

// Show forms
$( 'form.cmxform' ).show().end();

Note: I’m using the Mozilla-specific document.addEventListener() method to launch the script. This really is ideal, as it only runs for Mozilla (which is all we need) and it launches as soon as the DOM has been loaded.

Although JavaScript might not appear the most elegant solution, it is completely unobtrusive and, when JavaScript is disabled, the form degrades gracefully.

There’s also a small amount of tidying up to do in Internet Explorer though. For Windows, we need to tweak the positioning of the legends so they line up neatly. This can be achieved by giving the legend a negative left/right margin as shown below:

form.cmxform legend {
  padding: 0 2px;
  font-weight: bold;
  _margin: 0 -7px; /* IE Win */
}

For IE5/Mac, we need to tweak the display of the legend, to fix an odd display bug, by adding the following:

/**//*/
form.cmxform legend {
  display: inline-block;
}
/* IE Mac legend fix */

This rule allows us to supply a rule specifically to Internet Explorer for Mac. If you are uncomfortable in using browser specific rules in this way, feel free to remove them.

You could add these fixes to browser-specific style sheets, but I wanted this technique to be as portable as possible, so all the styles are in one place.

Finishing up#section7

We’re done. All you need to do is include the relevant “cmxform” files and then add the class of “cmxform” to any form you need to. (If you are wondering where the name “cmxform” came from, it’s there because I developed this technique while working for Cimex Media in London.) Enjoy!

Note: This form technique has been tested with Safari 2.0.3, Firefox 1.5, Opera 8.5, Internet Explorer 7b2 , Internet Explorer 6, Internet Explorer 5 (Windows), Internet Explorer 5.2 (Macintosh), Netscape 7.2 (Macintosh), and Netscape 8.1 (Windows).

About the Author

Nick Rigby

Nick Rigby is a freelance web standards and accessibility developer for his company, Puretic. In between work he enjoys football, music, being creative, and writing the occasional article for nickrigby.com.

118 Reader Comments

  1. I’m not a css-guru or something like that, but I think the habit to use scripting for styling, which I see more and more these days, isn’t a very good thing. I’m convinced that there are tons of other ways to create a similiar, semantically correct, layout. If you want to create a website that’s accesible in all browser and you want to use a css-property that isn’t supported you just shouldn’t use it.

  2. Nick, great article and an important topic, since form-styling can be really difficult.
    But your example (example_3) does not work in FF 1.5.0.4 (no extensions).

    @Luc: I don’t think so, because if you want to or have to achieve a complex layout sometimes it’s the only way.

  3. Christian, you are right. But I experienced massive problems if a floated form is inside other floats (in IE, naturally).
    Regarding my other post (#2); I did not mention it’s FF/Win. FF/Mac does fine.

  4. I’ve created several comparable layouts in the past with just grouping the label and input control with a div and using floats.
    The point I’m trying to make is that if you have to turn to scripting to display a relative simple static layout correct, you should automatically be triggered to find an alternative solution, because your problaby taking the wrong a path to a solution.

    Quote frome Molly E. Holzschlag’s article “World Grows Small: Open Standards for the Global Web”

    “Rely on JavaScript as an enhancement for, not a replacement of, website features.”

  5. Apart from the aforementioned issues with the JavaScript in use here, this seems like a solid solution for a practical problem.

    I’ve been trying to figure out a good way to style up semantic forms, and this looks like a step in the right direction as far as I’m concerned.

    Good article, and thanks for sharing.

  6. Thanks for all the comments so far.

    I agree that JavaScript shouldn’t normally be used for styling, but in this scenario I broke a rule, but it offers an unobtrusive fix for a specific browser. The forms work with or without JavaScript/CSS enabled and the complete method offers a robost, accessible and portable solution to a common problem.

    I’ve been using and testing this method for a fairly long time now, and in my experience it works incredibly well, so I hope someone else can find it useful.

    @Chris Leipold: Which patform are you on? Firefox 1.5.0.4 is working ok for me.

    Thanks again for all the comments.

  7. If I turn the CSS off, the example looks like rubbish. It looks a bit better in Lynx, but still not intuitive. For example the question “Which of the following sports do you enjoy?” has all the answers listed in one row – if it’s a list of answers, why not mark it up as list?

    And whenever I see this “mandatory fields marked *” kind of thing, I think, why don’t they just add text “(mandatory)” or “(required)” after the field name?

    BTW, the example is buggy: I see “null” written at the beginning of each field label (“nullName”, “nullAddress”, …).

  8. I want to mention, that despite the fact I partially don’t agree with the author’s vision, I do appreciate he took the time and effort to share his solution with the community. Don’t want to sound to negative, just keep on sharing your toughts ^_^

  9. Oh… those “null”-s I mentioned, they are generated by JavaScript. I’m using some weekly build of Opera 9, so it might be some bug in this build, but not very likely (works fine in FF and Konqueror).

  10. @Nick, it seems to be my fault.
    I have FF 1.5.0.4 on Windows. My colleague has the same and for him it works fine.
    @5:
    “Rely on JavaScript as an enhancement for, not a replacement of, website features.”
    But that’s right what it is. It works without JS. It works also without CSS. It’s just nicer with both.

  11. First of all, thank you for taking the time to write an article for ALA.

    But I just don’t see why half of what you have done here is needed? There are, as I’m told, approximately 4,356 ways of doing something but this seems to be the long way around.

    The first thing I’m kind of stuck upon is the use of the ordered list, but that’s really a minor detail since we can debate semantics all night before we realize that no two persons think alike.

    There are much easier and more cross browser ways of achieving exactly the same thing. Without all the JavaScript and the poorly supported inline-block. I still haven’t seen any issue with a carefully constructed form that uses floats wisely.

    It just seems a bit too bloated for what it’s going to be used for”¦

  12. Thanks for the aricle.

    I do like how you have used an ordered list for each form item and i would have liked to see the radio buttons being listed as 5.1 and 5.2 🙂

    I don’t think js should have been used, people are right by saying that too many js solutions are being created to do (with a big of creativity) what css can do.

    Finally, I also noticed that it partially worked in IE7 Beta 2. What didn’t look correct where the legends what didn’t align correctly.

    Cheers
    GK

  13. Thank you for another take at providing semantic markup for forms. However, I was really disappointed with the CSS/JS solution.

    I have always managed to get a very long way with floating the labels and input fields to the left combined with, the “clearing without structural markup” technique for standards compliant browsers and the usual hasLayout hacks for MSIE.

    In only a couple of minutes I produced an identical result without the extensive use of Javascript for Firefox 1.5 and MSIE6. With some more time you might not get it identical in older browsers, but surely that is not a reason to include a Javascript solution for today’s standards compliant browser?

  14. bq. And whenever I see this “mandatory fields marked *”? kind of thing, I think, why don’t they just add text “(mandatory)”? or “(required)”? after the field name?

    I was hoping someone would mention this. It’s to do with convention, and convention morphing into semantics.

    The convention has been established, like it or not, that an asterisk next to a form label implies that the field is ‘required’, it has done in visual mediums for a long time, requiring little-to-no explanation in almost every imaginable usage. Its continued, consistent use for this has led to even users of non-visual browsers (such as screen-readers) recognising it as meaning ‘required’ [1].

    The crux of the matter is that an asterisk, either visually or audially, now _means_ ‘required’, so any further explanation is generally spurious and a waste of time, space & effort.

    1. This assertation comes from a great deal of work a colleague of mine has done directly with disabled users, and their experience of using screen readers.

  15. I understand the reservation against using JavaScript, and if you really can’t bring yourself to use it, then this solution isn’t for you.

    The plus points, however, and the reason I have spent a huge amount of time developing this solution are:

    – The JavaScript requires only two includes. That’s it. And it works accross a wide range of browsers with or without JavaScript enabled
    – The markup is clean, neat and completely accessible
    – The main cmxform.css stylesheet is small, neat and uses minimal browser hacks. It can easily be used in any project.

    I have spent a great deal of time trying to find a neat way of building forms that I can use from one project to the next. I wanted to give people something that they can use in their products, regardless of the sorrounding markup. Something which can be plugged in with the least amount of fuss.

    I believe this is a really nice solution and for that reason I wanted to share it. I hope people give this method a try and realise how robust and portable it is.

    Thanks again for all the comments.

  16. I have to state my support for the author on this scripting issue.

    The CSS is supposed to be a “library” to be included without modification into any project. Not the cleanest way to make one single form look nice. I am not sure I will have use for it myself but I can see the benefits.

    Even though it has been commented on already I also have to join in to say that the scripting is implemented unobtrusively for the purpose of keeping the HTML cleaner. If it is not to your liking just add the tags manually. It is not like te whole technique is based on javascript.

    The thing that struck me though… (now I am really trying to make enemies in all camps)
    …was the visual layout itself. It is usually preferable to have the labels right-aligned to visually link to their fields better. This is defenitely true when the length of the labels differ greatly. But this is something that anyone can modify to their liking. The technique in the article is still valid IMHO.

  17. bq. Rely on JavaScript as an enhancement for, not a replacement of, website features

    I agree entirely with that sentiment – which is why I think JS is perfectly justified in this situation.

    The form works. It works without Javascript, it works without CSS. What both of them do is offer an enhancement to the form, by making it look better.

    In general, I agree that styling is better done with pure CSS than scripting, but there are some times when this can’t be done. On my own website, I use :hover pseudo-classes on arbitrary elements to make styling changes – this works in Opera and Gecko but not IE (does it work in IE7?). I could (when I have time and can be bothered!) include a script to modify the DOM so that this feature would work in IE … which would be a sensible use of Javascript to augment the styling of the page.

  18. bq. And whenever I see this “mandatory fields marked *”? kind of thing, I think, why don’t they just add text “(mandatory)”? or “(required)”? after the field name?

    Because it generally doesn’t look as good to have “(mandatory)” written out in full next to every field – a coloured asterisk is unobtrusive yet clearly visible. If the asterisk is applied to the label, and is explained at the start of the form, there should be no accessibility or usability issues.

    In general, I prefer to avoid the use of mandatory/optional fields, and only ask for the information that I really do need!

  19. Just scanned the article, and jumped over recent comments:

    * Using lists for input elements is at least “questionable”. And in this case, you could achieve almost the same with “label” elements.
    * Emphasizing asterisks is not really appropriate. Additional text would be more helpful, I fear.
    * Use other filters/workarounds/hacks for your CSS (WTH is going on in the “form.cmxform legend” rule, accidentally put a “strong” element in there?), and ignore Mac IE.

  20. I think this is a nice flexible approach to working with forms, but I don’t think it’s the most portable, nor do I think it’s the most efficient. I agree with the sentiment of many of the other comments about using javascript to add style.

    I’ve “written about forms”:http://pennypacker.net/articles/bulletproof_web_forms_part_one myself lately and while I don’t claim to have all the answers (and I’m certainly not as succinct), I’m using an accessible and XHTML strict method to achieve “a similar result”:http://pennypacker.net/stuff/webdevarticles/forms/ex3.html

    I do like the idea of the ordered list for the purpose of screen readers, however. That’s something I’m very eager to experiment with.

    Thank you for the article, I found parts of it thought provoking, even if I don’t agree with every point that it makes.

  21. *Rene*: I’d hazard to guess that this is caused by the use of addEventListener (which does not run only on Mozilla, as the author points out). The reason it only worked in Mozilla for the author is because the DOMContentLoaded event was originally a Mozilla specific event, but is now in Opera 9 (*which is now out of beta*). The DOMContentLoaded event was only added recently, so it is not in all of the beta copies of Opera 9.

  22. There is a problem with Opera 9 outputting “null” before the labels, which is a result of the JavaScript running.

    It’s no problem that the JavaScript runs for Opera, and it can easily be fixed by changing this line in the JavaScript:

    *this.innerHTML = null;*

    to:

    *this.innerHTML = “”;*

    I will hopefully get this changed updated in the article and example files.

    Thanks for pointing it out.

  23. I have an issue with the lead-in to this article… The client-side development/design team at the agency where I work has decided, as a group, that since forms output tabular data, it is permissible to use tables to display forms.

    Is using bulleted lists to display forms really more semantically correct?

  24. I’ve been using definition lists for essentially the same thing using the argument that semantically, it just makes sense.

    Delivery Details

    Is this address also your invoice address?*

    That way, you wouldn’t end up with a wrapped fieldset at the end. This is, of course, assuming that you agree that the input labels define their input fields. If you don’t, why not?

  25. bq. The client-side development/design team at the agency where I work has decided, as a group, that since forms output tabular data, it is permissible to use tables to display forms.

    Not at all. You might as well say that since your computer sits on a table, it’s OK to use tables for anything that you run on your computer…

    Forms *don’t* output tabular data – what they return is far more aligned to a

    definintion list. The fact that it _can_ be exported into a table _if_ that’s how you choose to run it is neither here nor there.

    Having said that, I don’t have a problem with using tables to get the form to appear as intended – as long as it linearises properly to give the same output as you or I might see on the screen. No, it’s not ideal – but at the same time, it isn’t the worst sin in the world of web design.

  26. I was very impressed with the technique, at least until I got to the part where you include a fairly large library of javascript in order to hide the fact that you require a non-semantic element for Mozilla based browsers.

    But it seems like you are really going out of your way to avoid the use of tables, and ending up with something that is almost as much markup (it would be about the same number of tags, if you weren’t hiding the divs with JS), and much more JS. But when you get down to it, it is in fact tabular data. You have multiple rows, and two columns. The first column, like many tables, is used to identify the data in the remaining columns. The columns and rows form a grid that allow you to associate the items in the columns with the items in the rows.

    The fact that it has the minimum number of columns to qualify as a table does not make it any less of a table, you have just used different mark-up, along with tricky CSS and JS to recreate a table. One could easily imagine more columns, such as a column of check marks to indicate required fields, or a column of hints for each row of what is allowable data for each row.

  27. *Brad*: I will give you that it is much simpler to put everything into a table, but it is not tabular data when you get down to it. When you get down to it, it is essentially a “question list”, which is essentially a subset of a definition list (i.e., question : term :: answer : definition ). You’re even allowed multiple dd’s to each dt, so that allows you the ability to provide multiple answers (e.g., checkboxes) to each question.

  28. Is this code actually intellectual property of Cimex Media? If I develop a sweet script at work, I don’t think it is mine to distribute. Just a thought…good article.

  29. *Jens*: While I’m torn on using what type of list to use (I’m currently leaning towards a definition list, and would use an unordered list before an ordered list like in the article), the point that I believe you’re missing is not that you’re emphasizing an asterick, but you’re emphasizing the text used to indicate that it is a required field. This article is meant as a library to be used from project to project, so you’re free to use whatever text within each tag that you please.

  30. Could you use this for required fields: *?

    Probably not, since it is not an actual abbreviation, but it seems like a good way to hide the bulky text.

  31. You’ve clearly put a fair bit of work into this, but I’m sorry to say that it’s got some serious problems, JavaScript aside:

    # There’s just no way in hell that an ordered list can be considered semantic markup for this. (This is an ordered list, a form simply isn’t.)
    # The colors look cool but are a form-over-function (har, har) usability problem: they give undeserved/irrelevant emphasis to the lower fields and the variable background color makes the asterisks harder to see, which seems to defeat the whole point of the exercise.
    # I’m a big believer in TMTOWTDI(There’s More Than One Way To Do It), but this seems like a really complicated way to solve a problem that’s been solved for a long time. Marking required fields with a colored asterisk isn’t exactly a new concept.

    To me, this is squarely in the “because you can” bucket, not the “because you should”.

  32. @Nicolai Grossman

    Tell me why an ordered list can’t be used here? The form elements are presented in some kind of logical order, so it works fine. Plus, it gives additional information to users of assitive technologies, in that the number of list elements are read aloud when the list is first encountered.

    The colours have absolutely nothing to do with the method that is presented in this article. This is just my version of how the form *could* be styled. The cmxform.css template file contains no styling and is presented as a template to give the form it’s default properties. The styling is then down to the author that is using the method.

    Again, the asterisk is my way of solving a particular problem. If you want to use a different method, go ahead.

    I think you are really missing the point of what I am presenting here. This method has taking a huge amount of time to develop, has been testing with assistive technologies (such as screen readers) and works accross a majority base of browsers.

  33. I usually use definition lists when styling forms. As in the Article, fields are logically grouped using fieldsets. Then, I put the label for the field(s) that follow into a

    , and all fields that belong to the item are put into a

    each. I know that it’s not really a list of definitions, but definition lists have the advantage that they show what’s belonging together prett well. Also, you can style

    s to be clearing, floating left, and having a specified width, so you wouldn’t need that javascript hack of yours. Just a suggestion 😉
  34. There are definitely ways to achieve the same visual formatting effects shown here, cross-browser, without using JavaScript. I strongly believe if you can achieve an effect without using JS then you should.

    Firstly let’s be honest: using JS to “fix” CSS implementations is a hack, and like any other hack should always come second to seeing if an alternative, more robust ‘workaround’ approach can work. Second, given many stats seem to show around 10-15% of users with JS disabled (yeah, scary), you should surely always aim to deliver the best experience you can without Javascript.

    Bottom line is I don’t believe Javascript is necessary here (unlike “Jeremy’s image gallery”:http://alistapart.com/articles/behavioralseparation in today’s other article, for example). Like previous commenters I have had a lot of success using floats (and a smattering of positioning) to style forms, including creating table-like layouts for complex (ie multi-fieldset/legend) forms from table-free markup. Predictably I don’t have anything written up I can share just this minute (!!), but it looks like there’s scope for more work – and lots more sharing of good ideas – in this area.

  35. Although I think it’s quite an interesting article I always wonder what’s the idea behind all these kinds of hacks that people use in order to get rid of tables in cases like these.

    I guess any kind of list would be more appropriate than a table in this case. But if you have to use hacks like the Mac/IE5.2 CSS hack and/or use JavaScript for lay-out (not event triggered) then why not ‘hack’ the understanding that it’s better not to use a table in a case like this? I mean, it’s a ‘hack’ that has been proved to be succesfull extensively. Why introduce new, more complex hacks for an old and simple one?

  36. Okay everyone. Thanks for all the comments so far, although I think things are going off topic slightly.

    * The HTML has been written in a very accessible way, in order for it to be available and most usable in many different devices and environments. I am using the available HTML tags in the best possible way I think I can.
    * There may be a significant number of users that disable JavaScript, but given that JavaScript is only required in Firefox, the 10%-15% user rate that has been quoted is probably inaccurate. However, the point is that the form works without JavaScript enabled, so for me, I see absolutely no issue here.
    * It is possible to re-create this layout using many other different methods. However, this method was produced to be as portable as possible, so it could be easily plugged into any site as a library CSS item. I feel I have achieved that. Remember, this is one method, you are not forced to use it and you should use a method that you feel most comfortable with.

    This technique works incredibly well for me, and that is the exact reason why I am sharing it with the community.

    Thanks for everyones comments so far.

  37. I am surprised that no one has mentioned the use of the -moz-inline-box property.

    What is the point of coding to standards if we use a proprietary non-standard property to overcome a problem that could be handled properly?

  38. Referring to the mozilla specific extension -moz-inline-block, I find it reasonable and acceptable to use this propietary extension. Though it is non-standard, Mozilla simply created the proprietary extension to implement a feature currently only in working draft form. Therefore, the whole JS ‘hack’ will become moot once the CSS 2.1 working draft becomes a recommendation. (as mozilla will simply remove the -moz prefix)

    On a side note, I find mozilla’s approach much better as opposed to the other browsers which implement working draft features. If removed from the recommendation, these proprietary extensions will then remain as implemented properties without the proprietary prefix they should have. In mozilla’s case, it is correctly named as such, and is easily (and almost immediately) modified to remain in step with the spec (recommendation).

  39. Way back when I read Designing with Web Standards for the first time, I remember Jeff warning about catching “divitis” when switching from table-based design to CSS.

    Seems to me like today we’ve thrown out divs (with no semantic meaning) in favor of lists. We markup with lists and think up a reason to justify them later.

    I loved the finished form in this example… a gorgeous product for not a lot of work; but a “list of form fields?” Come on 😉

  40. I think a major issue is whether the solution someone presents gets better over time. In other words will this solution require radical change in 2 or 3 years hence. Since the Javascript is easily removed the solution is good on that basis. OK, there are disagreements about whether OL is correct but this is a small point, and people no doubt can change it if they wish.

    It is clear that the author has taken great pains to test this so we don’t have to. Thankyou! Content separated hacks whether they are JS or CSS are a way of life at the moment, and they at least enable us to use the HTML we want to which is the key, and has convinced the browser manufacturers that they need better support for CSS in the future. This is a good thing.

    Can the same thing be done with floats? Perhaps, but the author and others have problems with them too so this is another solution to add to your armoury. Copy and paste some Javascript, and you are done. In the future, do a grep search to remove it.

    Thanks
    Good work 🙂

  41. I quite like this solution, and whilst I do agree with many of the issues raised with ordered lists and the javascript, I like the ideas in play here.

    My question for Nick, is why are you using “inline-block” as the display property for the label element at the top level, then change it to block further down? I couldn’t find anything specifically addressing this in the article.

    I ask because I recently had to develop a similar form design solution that didn’t end up as clean as yours.

    “Form input
    “:http://www.cue-the-sun.com/ato/add.html

    “Form output
    “:http://www.cue-the-sun.com/ato/view.html

    “More complex
    “:http://www.cue-the-sun.com/ato/FDF_trials/fdf_indent.html

  42. Firstly, nice article, I like the “make it work” approach over absolute purity (javascript’s ok if it works quickly and easily in my book).

    One point of feedback, the layout doesn’t seem work on Firefox 1.5.0.4 on Linux, the form inputs are aligned left against the labels instead of sitting neatly in a row.

    Good article, got me thinking…

  43. Nick, great article! From now on using

      inside my forms… As many others I’ve been using div’s inside the fieldsets to be able to style the rows.

      You could set the

  44. Keith,

    This works fine on my version of Firefox/Windows XP. However, it looks like it’s something to do with the size of inputs/textarea. I have not explicitly defined these in the example, so if you were do do this, the problem may well be fixed. I would be very interested to know if it does fix the problem

    Thanks.

  45. Nick, that’s it. I didn’t realise that widths hadn’t been set in the code; I just assumed the examples would already be “tricked out” to look like the screen grab near the top of the article.

    Setting explicit widths on the inputs and textareas does fix things, but you then have to distinguish between regular text inputs, and checkbox/radio inputs as one size does not fit all.

    Interesting approach, and it’s always good to see alternative ways of doing things. Like other commenters, however, I’ve found that the same sort of effect can be achieved using only CSS and without recourse to proprietary properties. Every dependency you can eliminate opens up the number of users who will experience the form as you would wish.

    Good article.

  46. Keith,

    The examples should look like the screen grab. Normally you would add a size value to an input like:

    When you do not specify a size, a default size is used, which is possibly different in some browsers. It looks exactly right in all the browsers I tested with, but it is obviously different on yours. The thing is, the inputs in your example look way out. Is this the same for all browsers on your machine?

    Thanks.

  47. I’d be the first person to emphasize that tables should not be used for layout (except with tabular data), but I fail to see how the form presented in this example is not tabular data.

    Imagine a form to collect information about your pickup basketball team. You’d have a column of row names, and then five columns with input fields. There’s the name row, followed by five name fields to fill in. Then there’s the position row, followed by five text boxes in which you put each player’s position, etc. The name/value pair relationships are clear, and each field is labeled (“Name – Player one. Name – Player two,” etc.)

    How is this not a table? And then if it only has _one_ column of information to fill in, how is this any less a table?

    Using tables for simple forms such as the one in this example also has the benefits of lists that were outlined in earlier comments — a screen reader gets to the table, and it reads, “Table with two columns and five rows” (so, just from the structure of the table, you know how many items there are not just down, but across, too), then it reads the summary and/or caption that you’ll have added to your table, “Contact information form,” or something else equally descriptive.

    I’m open to being convinced otherwise, but to me, this type of form is clearly tabular data with name/value pairs.

  48. This works fine on Safari, but the form fields aren’t aligning properly using Flock’s 0.7 beta on the Mac. Same thing when using Firefox 1.5.0.2 on the Mac — the form fields don’t align evenly and are instead simply aligning left following the label for each.

    The rest of the fields, however, display fine.

  49. Anthony,

    I’m not able to test in Firefox 1.5.0.2, but I just tested in an earlier version (1.0.7) and it works fine. I’ve also tested in Flock 0.7b and again it works fine. I’m using OSX 10.4.6. Do you have JavaScript disabled?

    Thanks.

  50. I haven’t done much testing on the topic, but I wonder if styling the label element as display: compact has been given serious consideration?

  51. I agree with almost all comments on this article

    # don’t use javascript for styling, unless it’s for the crappy IE browser. Let all other browsers simply use CSS
    # don’t try and find a use for lists when there is none. Though I must agree without CSS it looks nice. But I think the main issue is that without CSS it should be usable, not nice looking. a simple break will do.
    # don’t use -moz-inline-box, don’t use inline-block (not yet that is)

    For interested readers, I wrote an article in search of all possible float solutions for forms that have no additional markup. Let me know if you have more methods that I could include.

    “floating forms article”:http://test5.caribmedia.com/CSS/Secrets/members/michiel/floating-forms.html

  52. Wouldn’t the javascript be “better” (for some values of better, offer not valid in all states, some settling may occur it transit) if it looked for inline-block and replaced it with something better on broken browsers?

    I realize that the article isn’t about inline-block, per se. But to me, it’s one of the features I wish worked in FF/IE. :-/

    Ciao!

  53. I appreciate the article, Nick. Nice work. Compelling discussions as well.

    I would like to get your – or anyone’s – thoughts about setting the size of input fields. While it is not addressed specifically in your article, I think it has relevance given that we are attempting to make forms “prettier” and more “accessible”.

    My question concerns setting the input size to be the same length in all cases (except for input types “radio” and “checkbox”). I grant that – when all the same size – the inputs do make a prettier form. Your form does this, and it indeed looks great. Yet, what about considering the input in relation to the data it expects – and adjusting the input’s size attribute accordingly?

    A specific example is an input for Zip Code for a US address. I feel it presents a usability issue to the user when the width of a Zip input is as long as the input for Street or City. A US Zip is necessarily shorter and it makes sense – and is fair to the user – to indicate that visually, even at the expense of creating a “jagged right line” of inputs on the form. Thoughts?

  54. This may be a bit off-topic, but what is so wrong with tables? Why is a table in a form such a “semantic faux pas?” I could draw up that form in a fraction of the time, and do it using less bytes if I use tables. All I hear now-a-days is how horrible it is to use a table. Why use a simple table when you can create a huge stylesheet file and mess with divs that never show up correctly in all browsers?

    Back on topic, nice example though.

    Back off topic, I can feel the heat from the flames already.

  55. bq. Yet, what about considering the input in relation to the data it expects — and adjusting the input’s size attribute accordingly?

    That is sometimes appropriate, but in many cases you won’t know the length of the input. If you’re asking for name, or town, or email address, you have no idea how long it’s likely to be – so set a size that will be big enough for most people and others can scroll if they have to.

    bq. A specific example is an input for Zip Code for a US address. A US Zip is necessarily shorter and it makes sense — and is fair to the user — to indicate that visually, even at the expense of creating a “jagged right line”? of inputs on the form.

    I know this is slightly off your point, but consider the possibility that people from other countries will be entering their address in your form – might it be better to have a textbox so they can enter the address in whatever format is most appropriate rather than be constrained by one that is designed specifically for US addresses?

    In answer to your question, I think it would look fine either way, whether the postcode box is the right size for the input, or lined up with the other fields. Part of it will depend on the rest of your form, and how many fields there are of the standard length.

  56. In the case of input fields with an expected specific length there is only one way to have the length of the field match the length of the data across browser-platform combinations:
    # do not use CSS to set a width
    # set the attributes _maxlength_ and _size_ to be equal
    # set the font-family to a monospace font

    I have experimented with this and it was the only way, for example with a five-digit zip, to guarantee that the data input exactly matches the length of the input element. This was tested with Opera, IE (from 5 to 7 on Mac and Windows), Firefox, Safari and Netscape 6.

  57. Nick

    [Ref comments 48, 50, 51, 52]

    As I was reading your last comment (#52) it dawned on me where the problem lies, and likely explains the similar reports you have had regarding Flock and FF on Linux.

    In your example, you are not explicitly setting the width of text input and textarea elements in the CSS, but instead leaving it to the “default” size, or, in the case of the textarea, using the cols attribute in the textarea tag to set cols=”25″. If not explicitly set by CSS, the width of such elements will be affected in Firefox and other browsers by the user’s settings for default font and font size. It appears that my (and other people’s) default settings are larger than yours, hence the observed differences.

    We have no way of knowing a user’s browser settings, so it is risky either to leave the field widths unspecified, or to use the size/cols attributes in the HTML tags. To be safe (well, as safe as we ever can be, in this game) we need to set widths in the CSS to make sure labels and inputs don’t bump into each other, or knock each other out of the way.

    Of course, every individual form will demand its own styling, _including input and textarea field widths_ — but maybe that needs to be made clear.

    I hope this is helpful.

  58. I appreciate that the article you wrote does allow developers to create accessible forms, however the need for Javascript seems to be crazy in my opinion. Although the Javascript is unobtrusive, it still creates more work for the developer. It is possible to create the same form using

    &

    tags for Markup and only CSS to style it. It’s still very accessible, has more semantic meaning and no need for Javascript. What would happen if the user had Javascript turned off? Answer: It would no longer be a “Prettier Accessible Form”. I really don’t want to sound like I’m moaning, as it is a step in the right direction, but I urge you all to check out Dan Cederholm’s technique for forms.
  59. Firstly let me say that I enjoyed seeing a form layout that took a stab at semantics and didn’t use floats, which have been plagued me quite a few times in designing over the years. There’s certainly no God-sent CSS template that addresses the form (and there may never be), but please keep exploring these new ideas as they’re always welcomed and enriching.

    In trying variations on this CSS, I discovered that if you set _text-align: right;_ on the

  60. and use _padding-right_ to shift the inputs/labels to your liking, then you can obviate the need for js/proprietary tags. This also minimizes the need for CSS hacks. Granted, you have to be willing to deal with right-aligned label text, but the result is very clean/crisp. Here’s a very short “example”:http://www.geocities.com/pgates18/Content3.htm for your perusal.

    Of course, as often occurs in the Web Design world, solving one problem reveals at least one new problem. Inputs and TextAreas can generally be made to render equally across many browsers. The select element misbehaves in this regard, however (I’ve only tested in IE6, FF1.5, Op8.54/9). Opera is the only one of the three browsers I’ve tested (assuming the widths are equal in the CSS) that naturally renders the select the same width as the other form elements. IE and FF both render 2px shorter in the case of my experiment.

    Maybe I didn’t solve anything — just trying to follow the tradition of sharing ideas!

  61. @ Kevin

    I personally find forms with equal-length fields to be pretty, but not very usable. To me, different sized fields act much the same way as whitespace in a passage of text allowing me to more easily keep my fix on whatever I should be concentrating on. Another example is the alternating colors of a check register. By providing varying visual data. Generally, I will try to change the field size after 4-5 lines.

    I also agree that the size of the field gives a hint on what it’s meant to be which means you don’t have to read all of the labels as intently. For instance, If you see the pattern:

    *************
    *************
    **********
    **
    *****

    It’s pretty obvious that the last two fields are State & Zip

  62. @ Kevin

    I personally find forms with equal-length fields to be pretty, but not very usable. To me, different sized fields act much the same way as whitespace in a passage of text allowing me to more easily keep my fix on whatever I should be concentrating on. Another example is the alternating colors of a check register. By providing varying visual data. Generally, I will try to change the field size after 4-5 lines.

    I also agree that the size of the field gives a hint on what it’s meant to be which means you don’t have to read all of the labels as intently. For instance, If you see the pattern:

    *************
    *************
    **********
    **
    *****

    It’s pretty obvious that the last two fields are State & Zip

  63. It’s my first time posting here.

    Looks like my fields turned into HRs also. Here’s what I meant (i hope):

    OOOOOOOOOOOO
    OOOOOOOOOOOO
    OOOOOOOOOO
    OO
    OOOOO

  64. For me the tabular data issue is moot because I prefer against using tables because of the hell involved with javascript inserting and manipulating them (which, I suppose, evokes a whole new set of complaints, but on my current particular project I’m working on an internal website which requires JavaScript anyway for remote scripting purposes).

  65. Shoot. Should have mentioned that I’m really digging the use of lists.

    Think beyond address forms, people–ordered or unordered lists are perfect for things like questionaire’s or any extensive forms. This little _approaches_ being what prototype.js is for js, for css. Obviously, compliancy is an issue but in the current world of CSS compliance, it almost always is anyway.

  66. I echo many people’s feelings here, as soon as I saw the JS to ‘fix the layout’, it was never going to be a popular solution. The idea isn’t to bloat the code and slow down browsing running functions.

    Stick with the floats or use tables for the forms. I’ve noticed no problems with the form on my site using floats, which has been checked on many browsers Four Shapes contact form. However, that form isn’t too complicated.

    Your form is nicely designed, but I don’t think it will be used too often.

  67. Someone once demonstrated to me what a screenreader actually does when presented with a list element. It spoke at length about the list item at each element, before describing the contents.

    No further demonstration/explanation was necessary, and since then I’ve refrained from using lists inappropriately for nav menus (when div/span sets will do*) and never inside forms.

    *div/span groups will straight swap in CSS (with less default style removal) and can also work better on unstyled (mobile?) pages.

  68. I like the use of -moz-inline-block; I dislike all the javascript. That’s alot of work to fix what in all liklihood is a non-issue.

  69. I do apologise in advance because I’m normally very open-minded and listen to many different sides of a discussion, but in rare occassions like this one I get really annoyed.
    In a nutshell: will all you standards-Nazis get over yourselves!

    Where ANYWHERE in this articles does it say “this process is 100% reliant on JS and CSS and it’ll all break and look rubbish without it – to hell with standards!!”.

    I’d strongly suggest you go back and read it again – this process works perfectly well without JS. The only reason JS is in there is to fix the continuing rift between CSS implementations in browsers – and here I was thinking 1997 was almost 10 years ago.

    So instead of ranting and raving about how using JS to style is the work of Satan (and the process doesn’t style through JS the code simply fixes browser errors) why not focus that energy into bullying the browser manufacturers to get their act together and implement the established, 1,000 year old specs completely and accurately.

    Only THEN when we have 100% of browsers 100% compliant can you all go off and complain about hacks, fixes and workarounds if a process or piece of code deviates from standards.

    But of course this is never going to happen because new technologies are invented and maturing all the time.

    Sheesh if you don’t like it, don’t use it!

    Personally I’m going to rectify the erratic behaviour of long labels but making sure I don’t actually have any, but I’m not going to jump down the author’s throat just because he’s said “I’m going to fix omissions in a browser through script”.

  70. I was fascinated by the article and tried to implement all into a current project and it all worked well… except in the new Opera 9.
    The word “null” is inserted before all label contents.
    I am not a DOM-specialist, so there isn’t much that I can say or do about it…

    What does: this.innerHTML = null; in the script really do?
    ?

  71. The same behaviour with the example form of the article.
    “null” before each label element.

  72. Forgive me if this has been discussed earlier in the threads…

    I’ve seen a host of single column form solutions but they all service very small forms. What if you have a large amount of fields that need to be collected? Are there any two column css form solutions?

  73. Never assume your audience has a white background on thier browser. I’ve got old-school grey, and it looks terrible!

    As an aside, anyone else having trouble typing in this box, or is my keyboard suddenly broken?

  74. Can someone explain how the stretched gradient is acheived please? I’ve tried copying the background: url(….) CSS but I just get the 1×2 pixel image repeated across the bottom of my fieldsets. I can’t figure out how to stretch the image to 100% of the height of the fieldset.

  75. Oops – my mistake. I missed the inclusion of the larger image completely.

  76. Maybe this was not the point of the article, but if word “Accessible” is used in the title, I can’t understand why clicking the labels of the radio buttons doesn’t (isn’t designed to) work!? For me, connecting labels with input fields using FOR and ID attributes is a must. Unfortunately not all the web designers use this rule – see checkbox under the “Search ALA” input 😉 Laziness? Unawarness?

  77. I really like the way it displays in Firefox but I have to say that using JavaScript for the form makes it not quite accessible in my books. I like the architecture of the form as far as the code but using JavaScript just made me go “ugh!”?. Why are tables so bad when using forms? I think forms is a good use to put a good old table”¦

  78. I’m intrigued by the fuss Nick has caused by using an ordered list, because I’ve seen them being used to structure forms for years. Almost all the paper forms I need to fill in for my government, my university or my workplace—in fact, even surveys—have been represented as an ordered list of fields. This structure is especially useful because it is allows one to instruct the reader to “skip” a range of fields if they are not required.

    Given that it is an established standard, how precisely is this not legitimate? The only convincing argument I can see for _not_ using them is presented by Pid Ster, who explains that the form becomes less accessible for screen readers; and then, the impractical purist in me cries that this is surely a fault of the software, not the structure. (Incidentally, can any more experienced readers tell me if this is the case for all speech readers?)

    Definition lists I find particularly challenging, mainly because I’m not totally sure about their semantic intent. What is a definition list meant to imply? Is it really legitimate to use them merely for association? Aren’t labels and fieldsets sufficient—for forms, at least? In fact, isn’t that their explicit purpose? Tables, in my opinion, are preferable for data presentation, not data entry. I know that they often mean less markup, less complex CSS and less cross-browser hassle, but (in my opinion) they are also less semantically appropriate.

    Not that I consider definition lists or even tables to be a complete semantic _faux pas_, but they don’t immediately strike me as the best structures.

    As for using ECMAscript to amend browser CSS support: the form degrades gracefully and is reasonably attractive without the fix, which itself is relatively unobtrusive. Admittedly, a perfectly workable solution could be created using floats, but the author’s stated aim was to develop a solution which could be “dropped” into place, and float-based layouts are often very brittle (an issue I’ve experienced first-hand).

    I mainly use paragraphs to markup forms, and in future I may well use a few lists. Excellent work, Nick!

  79. Thanks Nick, I appreciate there is no magic solution to this problem. Personally, using the javascript or ol element doesn’t grieve me as much as others here, and I still think this is better than tables.

    I’m only mentioning this because nobody else has brought it up – but using the external library is a bit of a worry – it’s 10kb of extra data that needs to be downloaded. I’m sure the library does all kinds of good stuff, but only if you use it.
    I’m struggling to keep my pages looking good, functional, and less than 100kb before compression, so an extra 10kb for the form is a bit expensive.

    Is there a way you can extract what you need into a standalone piece of script? I”m sure you could achieve what you need with a page or so of script, rather than requiring the library with all it’s other features.

  80. How can anyone argue against that a form is a list of questions and answers? US residents: have you never filled out a tax form, or a DMV form, or any other kind of form? Even your W2’s are numbered!

    I number fields for everything. It makes support calls so much easier, too. “I don’t understand question 6.” I’m glad to see other developers starting to do the same. DL/DT/DD lists are good, too. As a website that supports a large number of impaired users, we get many compliments over our use of numbered lists.

    The earlier solution linked ( “Paul Armstrong”:http://paularmstrongdesigns.com/examples/css/awesome-form.html ) is far worse IMO than this form setup. You think using a list is bad form? What about changing the logical order of elements so they float correctly? Paul makes it so you have to list the checkbox first and then the label. Blind users will really enjoy _that_.

    I have a feeling most people that are against the JS didn’t even look at the example with JS disabled in Mozilla — it may look a little “off” but it is still usable.

  81. I am excited to see your use of ol to mark up form items. I think this markup is just right. I actually disagree strongly with the use of tables and definition lists to mark up form controls.

    The semantic realationship between the text and its input exists already, it is created by the label tag and the input tag (with appropriate attributes, of course). I think your use of OL is perfect for establishing the semantic relationship between the different input/label couples which compose the form.

    I had previously used a more minimal markup :

    <label><input>text text text</label>

    The problems with my method were : 1. inverted order of text and input, and 2. with CSS turned off the form was still technically useable but turned into a soup of form controls and text.

    Javascript for layout makes me very hesitant… I don’t like the idea that it might be used to shortcut actual thoughtful CSS development. On the other hand I’ve inherited *divML* projects, where more than 40 divs were used to create three boxes of equal height in a row.

    When one has tried to do CMS development on a bloated project like that it starts to be easier to see the value of using Javascript to add extras that aren’t necessary for the page to function especially when it means we can keep the markup clean.

    Nicole

  82. Excellent article Nick, thanks for taking the time to write up your method.

    My only concern about relying on JS workarounds for style is unforeseen collisions with Prototype or Script.aculo.us (or any other Ajax library). Have you tested this method with Rails form helpers, or other server-side solutions that dynamically generate forms and form interactions?

    Not busting your chops, just asking. This article helped me see forms in a new light.

  83. I’m having a different problem using this on my own page with firefox, but it doesn’t affect the examples. I did try not including any of my normal styles (using just the example instead). Basically firefox ignores the width’s for the labels and the form itself. Anyone know why?

  84. Hi all,

    I’m trying to apply Nick’s great example into a current website … and got a really good looking/working EDITABLE form cross-browser …

    What happens when you’re not editing and want to VIEW THE FORM later?

    Currently using label and input css markup is cool … but nothing’s available for the text later when viewing only.

    What do people propose to that? The DL/DT solution would solve that … but I wouldn’t mind getting Nick’s solution working!

  85. the snag is … you can’t do them with the current css 🙁

    I realise now why Nick’s demo shows all radio and checkboxes on single lines in their own fieldsets – I’ve just tried doing multi-column radio/checkboxes and sure enough, the
    breaks the line and wraps to the start of the next line, under the label left-aligned 🙁

    Any ideas anyone?

  86. I am very much anti-JavaScript, but face it, it’s use here is unimportant towards accessibility, nohng breaks if it is turned off.

    I did live in Germany till recently, my wife is German and all my three girls are Half German. I do not appreciate Ross Clutterbuck’s comment (78) about “Standards-Nazis”. It is very inapropriate when “Zealots” or “Crusaders” would have worked nicely. It is time to get over yourself, the war ended 50 years ago and not even my wifes parents and kids grandparents were involved in it.

    My one important input here is less JavaScript as the use of innerHTML as mentioned in comment 26. Best of my knowledge innerHTML is not supported by XHTML when correctly served as XML, only if served as Tag Soup. Hence this would not work in my personal sites. So any XHTML conscious designers should keep that in mind when using application/Xhtml+xml MimeType.

  87. @ Eric Brown and further readers:
    “The earlier solution linked ( Paul Armstrong ) is far worse IMO than this form setup. You think using a list is bad form? What about changing the logical order of elements so they float correctly? Paul makes it so you have to list the checkbox first and then the label. Blind users will really enjoy that.”

    Yes they will! Checkboxes and Radio bottons are supposed to have the label after them. Anything else will confuse the issue. “Better Accessible Forms”:http://accessify.com/features/tutorials/accessible-forms/ at Accessify.com

  88. @ Eric Brown and further readers:
    “The earlier solution linked ( Paul Armstrong ) is far worse IMO than this form setup. You think using a list is bad form? What about changing the logical order of elements so they float correctly? Paul makes it so you have to list the checkbox first and then the label. Blind users will really enjoy that.”

    Yes they will! Checkboxes and Radio bottons are supposed to have the label after them. Anything else will confuse the issue. “Better Accessible Forms”:http://accessify.com/features/tutorials/accessible-forms/ at Accessify.com

  89. Hello. Opera 9.01 is inserting ‘Null’ in front of the label values for me, with the intended label then dropping down a line. Anyone got a fix for that?

  90. I know I’m awfully late to the party, but I was wondering about the statement in the article that, “forms don’t constitute tabular data.”

    I’ve heard other people say this, and I really don’t get why. Especially given the concept of label/data pairs. In fact, I would suspect that when most forms are submitted to a database the data is submitted in a near identical format (e.g. The first column being an identifying label, and the next column being the data (although, I still think it would be semantic, even if the order was reversed… just kind of whacky in L to R reading languages)).

    I’m wondering if I’m missing something.

  91. I dont have anything to add to the discussion. I just wanna say that the idea of using lists for structuring is very…ummm…unique.

    I won’t argue about semantics or anything. coz as long as it works, it’s totally fine by me 😀

  92. Here is a poor attempt at re-implementing this using Prototype.js since JQuery clashes. This requires that the form has an id=”cmxform”, I’m sure people out there that actually know what they’re doing could improve upon this.

    
    if( document.addEventListener ) document.addEventListener( 'DOMContentLoaded', cmxform, false );
    
    function cmxform(){
      // Hide forms
      $( 'cmxform' ).hide();
      
      // Processing
      var someNodeList = $('cmxform').getElementsByTagName('label');
      var nodes = $A(someNodeList);
      nodes.each( function( i ){
    
        var labelContent = i.innerHTML;
        var labelWidth = document.defaultView.getComputedStyle( i, '' ).getPropertyValue( 'width' );
        var labelSpan = document.createElement( 'span' );
            labelSpan.style.display = 'block';
            labelSpan.style.width = labelWidth;
            labelSpan.innerHTML = labelContent;
        i.style.display = '-moz-inline-box';
        i.innerHTML = null;
        i.appendChild( labelSpan );
    
      } ); //.end();
      
      // Show forms
      $( 'cmxform' ).show();
    }
    
  93. Someone above was asking about a tableless two column css layout.

    Working for a non-profit which serves the disabled, this article was my original inspiration for developing the above.

    I eventually found the use of fieldsets preferrable to unordered lists because of the extra junk that comes with them in screen-readers. Besides, they make natural large containers, I wish I had discovered them years ago.

    This article is right-on in promoting the use of labels, which I now use religiously. I simply happen to like the div/span approach.

  94. Someone above was asking about a
    “tableless two column css layout”:http://www.yeago.net/work/2006/09/two-column-css-layout.html

    Working for a non-profit which serves the disabled, this article was my original inspiration for developing the above.

    I eventually found the use of fieldsets preferrable to unordered lists because of the extra junk that comes with them in screen-readers. Besides, they make natural large containers, I wish I had discovered them years ago.

    This article is right-on in promoting the use of labels, which I now use religiously. I simply happen to like the div/span approach.

    ps: severe apologies for the double-post. forgot to Textile.

  95. Let me first say that this article has become a great resource for me and has changed the way I think about and create forms. But I’ve found a problem that I’m surprised that no one has mentioned here. I’m developing on a Mac, and everything looks perfect on Safari! But in the rest of the browsers I’ve seen, there are inconsitencies. I’ve done a little modification to the CSS for my own purposes, naturally, and set the label width to 33%, as I’m using them in some varying CSS column layouts and this causes the labels to collapse so that the inputs are right along the right side of them. This happens everywhere bu Mac Safari and MSIE. The only other inconsistency is that MSIE seems to give a left margin to fieldsets. I set up my Submit button like so:


  96. So that it would line up with my checkboxes and other inputs, but it shift a good inch to the right. Any ideas on how to fix this situation?

  97. Hi,

    Both on IE 6 and Firefox on Win2k, when a legend has more than 1 line, it’s not broke but continues on a single line.

    It’s at the exact position of “Is this address also your invoice address ?” but longer.

    Even if I force the width property of the legend, it’s not working, evenwith ” !important”.

    If you have any idea “¦

    Cheers.

  98. Firstly, I think this article does provide a nice insight and a perfectly valid method for form layouts. I think whilst the use of Javascript to fix style hacks is far from ideal, it is a solution which should work for the vast majority of people and thus is not a big usability issue. The downside is simply the untidiness of having extra “˜hack fix’ code.

    I would, personally, disagree with your assertion that it is wrong to represent form data in a tabular form. I believe that it is perfectly acceptable to represent any data however you like providing the semantics are easy to understand, mathematically solid, and do not contravene existing standards unless there is a specific reason for doing so. In the case of forms, I would say that it’s as easy to understand the semantics of a table form layout vs. a list based layout. Because there aren’t any fixed standards in place for form semantics I can’t see why using tables can be considered a poorer solution to using lists.

    For most situations you can classify a form as a set of related fields with undefined size, and classify a field as a typical (key, value) pair. To give an example, taking the first three, fields of your form (Name, Address, City) using set notation you could mathematically represent a typical record of data as ((Name, “˜Homer Simpson’), (Address, “˜742 Evergreen Terrace’), (City, “˜Springfield’)). As the set contains pair based items only, you can consider a 2-column table where the first column represents the head of the pairs and the second represents the tail of the pairs. Clearly, it is a direct mapping between two representations and the related XHTML code would be pretty self explanatory.

    I think there is a certain hesitation to use tables in the designer world for fear of being ridiculed for being out-of-touch. I think in this case a table solution would be perfectly understandable and increase the clarity of the page’s stylesheet.

  99. The alternative javascript (in comment #106) for use with Prototype.js only works with one form on the page and with it’s ID being ‘cmxform’, not the class. This alternative works pretty much the same as the original script, only using prototype.js instead of jquery.

    function cmxform(){

    // Hide forms
    $$(‘form.cmxform’).each(Element.hide);

    // Processing
    $$(‘form.cmxform li label’).each( function( label ){
    if (label.classNames() != ‘nocmx’) {
    var labelContent = label.innerHTML;
    var labelWidth = document.defaultView.getComputedStyle( label, ” ).getPropertyValue( ‘width’ );
    var labelSpan = document.createElement( ‘span’ );
    labelSpan.style.display = ‘block’;
    labelSpan.style.width = labelWidth;
    labelSpan.innerHTML = labelContent;
    label.style.display = ‘-moz-inline-box’;
    label.innerHTML = ” ;
    label.appendChild( labelSpan );
    }
    } ) ;

    // Show forms
    $$(‘form.cmxform’).each(Element.show);

    }

    if( document.addEventListener ) document.addEventListener( ‘DOMContentLoaded’, cmxform, false );

  100. Why are submit buttons never included in fieldsets?

    Since submit buttons can have meaning themselves, it would seem appropriate to me. I’ve never understood this.

  101. A different solution to tableless forms

    Nice article Nick, one of the best examples I’ve seen.

    I’ve been looking for a good css alternative to table based forms for a while now. I found this article along with a few other articles, all with different implementations. However, the majority of them used div, span, lists, p, br etc, which personally I don’t think is semantically correct. Javascript/css combinations like Nick’s seem to be a favourite too, which I’m not a fan of, sorry.

    Most of the examples I’ve seen don’t validate to XHTML 1.0 Strict, and fall apart in different browsers. They also didn’t cater for radio buttons, check boxes etc, so I’m glad to see Nick’s article includes these.

    ANYWAYS, as nothing else I have seen suited me I’ve been working on my own tableless form which covers all the points above and seems pretty bulletproof:

    Tested and working in Windows: IE 5, IE 5.5, IE 6, IE 7, FF 1, FF 2, Netscape 6*, Netscape 7*, Netscape 8, Opera 5**, Opera 6**, Opera 7, Opera 8, Opera 9

    Having read the previous posts, this is a different solution that might suit some of you better. Thought I’d share it and see what you think:

    A different solution to tableless forms

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA