Prettier Accessible Forms

by Nick Rigby

118 Reader Comments

Back to the Article
  1. By the way…now that form behavior is being completely rewrittren by Ajax and other dynamic technologies, don’t we need a new set of rules for styling them?  For instance, we’ll need the styles for error and confirm messages that appear within the form.
    Here’s an example Ajax powered newsletter signup form.

    Copy & paste the code below to embed this comment.
  2. Hi Bernd,

    I described a fix for Opera 9 earlier in the comments. Here’s the link directly to it:

    “Opera 9 Fix”:http://www.alistapart.com/comments/prettyaccessibleforms?page=3#26

    Thanks,

    Nick.

    Copy & paste the code below to embed this comment.
  3. I normally leave my forms pretty plain – I’m hooked on pretty forms now! Thanks.
    sam

    Copy & paste the code below to embed this comment.
  4. 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?

    Copy & paste the code below to embed this comment.
  5. 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.

    Copy & paste the code below to embed this comment.
  6. Well, “David”:http://www.alistapart.com/comments/prettyaccessibleforms?page=9#86, why don’t you look at the CSS source, copy the image URL and view the image?
    > !http://www.alistapart.com/d/prettyaccessibleforms/example_3/assets/images/cmxform-fieldset.gif!
    It’s a high gradient image. No CSS magic, just images.

    Copy & paste the code below to embed this comment.
  7. Oops – my mistake.  I missed the inclusion of the larger image completely.

    Copy & paste the code below to embed this comment.
  8. 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?

    Copy & paste the code below to embed this comment.
  9. 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”¦

    Copy & paste the code below to embed this comment.
  10. 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!

    Copy & paste the code below to embed this comment.
  11. 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.

    Copy & paste the code below to embed this comment.
  12. 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.

    Copy & paste the code below to embed this comment.
  13. 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

    Copy & paste the code below to embed this comment.
  14. 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.

    Copy & paste the code below to embed this comment.
  15. 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?

    Copy & paste the code below to embed this comment.
  16. 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!

    Copy & paste the code below to embed this comment.
  17. 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?

    Copy & paste the code below to embed this comment.
  18. 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.

    Copy & paste the code below to embed this comment.
  19. @ 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

    Copy & paste the code below to embed this comment.
  20. @ 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

    Copy & paste the code below to embed this comment.
  21. 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?

    Copy & paste the code below to embed this comment.
  22. I was sure I didn’t already read an answer to my question on Opera 9.01 and Null, but it’s there on page 3.

    Copy & paste the code below to embed this comment.
  23. 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.

    Copy & paste the code below to embed this comment.
  24. 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 :D

    Copy & paste the code below to embed this comment.
  25. 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[removed]; var labelWidth = document.defaultView.getComputedStyle( i, ‘’ ).getPropertyValue( ‘width’ ); var labelSpan = document.createElement( ‘span’ ); labelSpan.style.display = ‘block’; labelSpan.style.width = labelWidth; labelSpan[removed] = labelContent; i.style.display = ‘-moz-inline-box’; i[removed] = null; i.appendChild( labelSpan ); } ); //.end(); // Show forms $( ‘cmxform’ ).show(); }

    Copy & paste the code below to embed this comment.
  26. 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.

    Copy & paste the code below to embed this comment.
  27. 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.

    Copy & paste the code below to embed this comment.
  28. 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:

    <li>
    <fieldset>
    <label><input type=‘submit’ value=‘Submit’ /></label>
    </fieldset>
    </li>

    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?

    Copy & paste the code below to embed this comment.
  29. As a comment to the 2 column tableless design remark;

    you can now validate your tableless design at: http://w3tableless.com

    check if you’ve done it the right way.

    Copy & paste the code below to embed this comment.
  30. 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.

    Copy & paste the code below to embed this comment.
  31. 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.

    Copy & paste the code below to embed this comment.
  32. 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[removed];
      var labelWidth = document.defaultView.getComputedStyle( label, ‘’ ).getPropertyValue( ‘width’ );
      var labelSpan = document.createElement( ‘span’ );
      labelSpan.style.display = ‘block’;
      labelSpan.style.width = labelWidth;
      labelSpan[removed] = labelContent;
      label.style.display = ‘-moz-inline-box’;
      label[removed] = ‘’ ;
      label.appendChild( labelSpan );
      }
    } ) ;

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

    }

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

    Copy & paste the code below to embed this comment.
  33. 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.

    Copy & paste the code below to embed this comment.
  34. Hi,

    bin gerade duch zufall auf den Artikel gestosen, finde den Artikel echt toll, hat mir sehr weiter geholfen.

    Danke
    :-)

    Copy & paste the code below to embed this comment.
  35. I checked the CSS and it doesnt validate.

    “See for yourself”:http://jigsaw.w3.org/css-validator/validator?uri=http://www.alistapart.com/d/prettyaccessibleforms/example_3/assets/css/_library/cmxform.css&usermedium=all

    Just something to keep in mind if you plan to do this.

    I think overall it has a nice end result without using floats, but it’s sort of a toss up between floats and javascript.

    Copy & paste the code below to embed this comment.
  36. i like the approach and want to try it in my next applications. especially the way that you use a list to define the form rows. interesting. need to check how you managed the gradient.. looks nice ;)
    you can pass by my blog http://webdevbros.grafix.at i am sure its interesting for you.

    Copy & paste the code below to embed this comment.
  37. <a href=”?http://www.urmood.com/urmood_css_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 href=”?http://www.urmood.com/urmood_css_tableless_forms/”>
    Copy & paste the code below to embed this comment.
  38. I used your above tutorial, but my the list is messing with my page background (only on PCs though). Here’s the link:

    http://www.cinevegas.com/survey/non.html

    Please I need help!

    Copy & paste the code below to embed this comment.