Efficient creation of sensible and usable forms

Sensible Forms: A Form Usability Checklist by Brian Crescimanno takes a look at various areas of web form design and gives good advice for making forms usable. Nothing new or revolutionary, but a solid article that will help developers create better forms.

Creating forms has to be the single most time-consuming aspect of web development. In far too many website projects I end up feeling that I would have needed to spend much more time on the forms to make them more usable and intuitive. Often I also feel less than happy about the markup and CSS used to control their layout.

I’m sure many others feel the same way about forms, so I’d like to ask a few questions:

  • How do you tackle websites that make extensive use of forms?
  • Do you have a repository of form templates that you can choose from or do you start from scratch every time?
  • Do you take the time to carefully plan each form or do you just muddle through?
  • What about form markup and layout? Do you have predefined markup and CSS rules for every (or most) control plus label combo you run into, or do you cut and paste from earlier projects, adding or changing any combinations that are new or slightly different?

Please share any tricks you have that make creating usable forms easier and more efficient.

Update: I was checking my referrer logs and found that other people are asking similar questions: Forms Markup and CSS.

Posted on January 13, 2006 in Quicklinks, Usability

Comments

  1. Sketch a layout on paper before starting to code. Think about what information is related, and the importance of it to your site, then order appropriately.

    Make use of fieldsets.

    Oh, and alignment in forms, without tables, can be done with:

    fieldset label{ display: block; width: 90%; text-align: right; }

    fieldset label input, fieldset label select{ width: 12em; margin-left: 20px; }

  2. January 13, 2006 by SchizoDuckie

    I am currently working on a form of PHP on Rails (kinda). PORK, in short.

    As i use mostly database-based forms, i am working on something that analyzes the complete relation structure of the database schema, and converts that into one standard backend where you can CRUD, and connect different tables into eachother.

    As for the forms themselves: I use a self-created PHP5 formgenerator which works kind of like this:

    function displayEditor($title)
    {
    $editor = new formGenerator($title, $this);
    $editor->Ordered = new DateEditor(‘Order ordered’, ‘DATE’); //$objectType(label, validation type).
    //DateEditor productes an input with a calendar next to it.
    $editor->Opened = new DateEditor(‘date opened’);
    $editor->Payment = new textInput(‘Total $’, ‘CURRENCY’);
    $editor->Status = new enumSelect(‘Status’, ‘SELECT_ONE’);
    $editor->Printstatus = new enumSelect(‘Printstatus’);
    return($editor->display());
    }

    I have a lot more different types of objects and validation types defined over the last fe w years. Think like: SELECT’s filled from queries, Ajax’ed controls, file uploads, image selects from server, etc.

    The validation is mostly javascript as of now. The formgenerator als auotmagically creates the javascript rules, and attaches a formvalidation object to the current form’s onsubmit.

    Validation is then executed onfocus and onkeypress, and the user gets a description what he has to currently input appended under the current form element. Ofcourse, if not all validation rules are met, the form cannot be submitted.

  3. I’ve become used to writing forms with a PHP class called fp_form. It works wonderfully well and it adds functionality like javascipt validation, correct labelling, fieldsets, etc … on the fly. Unfortunately the website of the creator went offline so further development of the class is suspended i guess. Maybe i’ll pick it up if i ever have the time since it published under GNU licence.

    What concerns layout i start from scratch every time since most form require different methods of layout. The HTML is generated by the class i mentionned earlier and the styling is handled with CSS. Recently i experimented with horizontal forms. The method is usefull in some occasions, certainly in shorter forms for login/registration purposes. I always try to avoid longer forms since personally i feel that 90% of all forms online request too much information, info they’ll end up never using anyway. Waste of time and cause of frustration.

  4. I have a standard Javascript validation that I use on most forms.

    As far as form layout is concerned, the definition list is my best friend, generally with the <dt> holding the <label> and the <dd> holding the <input>, <select>, or <textarea>. This varies by project, but I usually start here.

  5. How do you tackle websites that make extensive use of forms?

    Paper prototyping is a practice that I’ve started employing - because today, forms come with alot more operational minutia than they used to. Otherwise, there’s typically a preexisting form that I’m working from.

    Do you have a repository of form templates that you can choose from or do you start from scratch every time?

    Surely we all write code in an evolutionaly style, so that one form today has similar code style elements to the form we wrote 6mos ago. I use no standard template, but if I were doing alot of contract work and had to set up formmail every other day, I sure would.

    Do you take the time to carefully plan each form or do you just muddle through?

    Carefully? No. Probably closer to muddle, since I rarely get carefully crafted requirements. ;o)

    What about form markup and layout? Do you have predefined markup and CSS rules for every (or most) control plus label combo you run into, or do you cut and paste from earlier projects, adding or changing any combinations that are new or slightly different?

    Most forms I’m working on are relatively unique, so I’ll start by hand-coding the markup, and it just sort of evolves from unstyled structural markup to the intended design. Some cut-n-paste happens when moving from the prototype over to integration with the server generated code, but just as often that will involve a total re-write, sadly. But by that time, I’m intimately familiar with any “gotchas” that can creep into the layout, and how to avoid them.

    Hope my answers were, um… answers. Cheers!

  6. Does anyone know about some really good and thorough form-generator, based on database tables or so?

    If not, then it’s time to develop one in PHP myself.

  7. January 14, 2006 by Roger Johansson (Author comment)

    Thanks, there are some good tips here already!

    Paper prototyping sounds very useful, and having some kind of form generator on the back-end seems efficient. As always when using such solutions I am a bit worried about losing control of the generated markup - I have seen too many examples of really awful “HTML” coming from the drag-and-drop IDEs that seem to be so popular with programmers.

    No tables for form layout, please :-). Definition lists… hmm, I’ll have to think about that.

    When writing validation scripts, make sure any validation is also run on the server for those who do not have JavaScript enabled.

  8. I typically just muddle though. But can I just say, I hate forms.

    I’ve been using a combination of Khoi’s form template and my own CSS models. I wonder, what’s your thoughts on wrapping the input elements in label?

  9. January 15, 2006 by Roger Johansson (Author comment)

    Sean S: I prefer using the id and for attributes to associate labels with their respective form controls. Three reasons:

  10. This Firefox 1.5 regression bug can really annoy you when you design form using FIELDSET and floats inside. Too bad that “nobody’s working on this”…

  11. Something we tend to do where I work is to create the form in mark-up without applying any CSS to it. That way you can see if it makes sense without author styling.

    For one reason or another I tend to go for the labels above the inputs with judicious use of brs, as this leads to a logical layout when the author styles are not applied.

    Fieldsets are always useful for grouping of related fields and these can be used to provide more interesting layouts too. For example, I have recently been working on a form laying out addresses where the delivery address and billing address fields are side by side in separate fieldsets, with a third fieldset containing references and delivery details stretched across the bottom of the two address fieldsets.

    I like the idea of creating a set predetermined markup and style templates as a basis for each project, as this would help cut down the time that each developer takes starting from scratch every time.

  12. For display I generally use logically grouped fieldsets that contain two-column tables. The first column contains header fields with labels, the second one connected controls. The table has a colgroup with two cols defined: one set to something around 20%, the other 80% for controls.

    For generation we use two approaches. For forms used on websites, we write our code by hand. It’s relatively easy and there is usually only about a dozen fields.

    For web apps we use our own container-based widget system that takes care of HTML generation (including JavaScript form validators and AJAX helpers):

    function _panelAddProduct()
    {
        $cnt = & new formWidget('post');
        $cnt->push(new paraWidget('===== New product ====='));
        $cnt->push(new paraWidget($this->showPath($pcid)));
    
        $box = & new fieldsetWidget('Details');
        $box->push(new checkboxWidget('promotion', 'Promotion', '1', '', false));
        $box->push(new checkboxWidget('highlight', 'Highlight', '1', '', false));
        $table = & new formTableWidget();
        $table->push(new formTableEditboxWidget('short', 'Reference code:', 'code', '', ''));
        $box->push($table);
        $cnt->push($box);
    
        $tab = & new tabbedWidget('Language version', 'Language');
    
        // [...]
    
        $cnt->push($tab);
    
        $cnt->push(new submitWidget('save', 'Add product'));
    
        $cnt->addHiddenField('action', 'add_product_save');
        $cnt->addHiddenField('pcid', $pcid);
    
        return $cnt->toHtml();
    }
  13. “This Firefox 1.5 regression bug can really annoy you when you design form using FIELDSET and floats inside. Too bad that ‘nobody’s working on this’…”

    Ha, somebody at Mozilla must read this blog, it’s fixed now!

  14. Michael Newton - you are right

Comments are disabled for this post (read why), but if you have spotted an error or have additional info that you think should be in this post, feel free to contact me.