demosthenes.info

A blog by Dudley Storey on , , , , , , and anything else that strikes his fancy.

featured articles

popular favourites

Form Layout With CSS

In a past entries I’ve discussed the correct markup and best practices to make a good, semantic, accessible form. At the time, the appearance of the form in the browser was terrible, but I emphasized how important it was to not add extra markup. Forms are not paragraphs, and they do not need <br /> tags or tables to display correctly. That is, not surprisingly, the role of CSS.

Step One: Make Accesskey Shortcuts Obvious

Part of the process of designing a good form is using markup to make it accessible by users of differing abilities. Each label in our form should have a unique access key value of a single letter. While correctly configured browsers will make these access key options obvious, we want to make sure that everyone who desires to use them is very clear on which shortcuts are present. If you’ve consistently used the first letter from the text of the label for an accesskey, (which is recommended) the CSS to achieve this is very simple:

  1. label:first-letter { font-weight: bolder; colour: red; }

(Of course, you can customize the appearance of the first letters in any way you wish).

Sometimes using the first letter of every label is impossible, simply because it has been used elsewhere in the form, or because that key press combination is reserved by the system. In that case, you must use other characters in the label text.

A good example of this would be two separate fields in a form, one asking for Phone Number and the other for Postal Code. We cannot use “p” as an access key value for both fields. This means adding a little markup to our XHTML. To this:

  1. <label for=”postalcode” accesskey=”c”>Postal Code</label>
  2. <input type=”text” name=”postalcode” id=”postalcode” size=”9” maxlength=”7” />
  3. <label for=”phonenumber” accesskey=”n”>Phone Number</label>
  4. <input type=”text” name=” phone number” id=” phone number” size=”10” maxlength=”8” />

We add the following:

  1. <label for=”postalcode” accesskey=”c”>Postal
  2. <span class=”shortcutkey”>C</span>ode</label>
  3. <input type=”text” name=”postalcode” id=”postalcode” size=”9” maxlength=”7” />
  4. <label for=”phonenumber” accesskey=”n”
  5. >Phone <span class=”shortcutkey”>N</span>umber</label>
  6. <input type=”text” name=” phone number” id=” phone number” size=”10” maxlength=”8” />

And change the CSS to:

  1. label span.shortcutkey { font-weight: bolder; colour: red; }

Note that you have to use one approach or the other: using both first-letter and this span technique for labels in the same form will result in style conflicts. The span approach also has the advantage that it works in older browsers that do not recognize the :first-letter pseudo-class, such as IE6.

Step Two: Make The Form Presentable

Elegant form (charlotteswebdesign.ca)
An elegantly designed form by Megan Ray

There are many possibilities for cleaning up the appearance of our form via CSS. Let’s start with the simplest:

Option 1

Label and input on separate lines

  1. label { display: block; }

This style declaration forces each label on its own line. You’ll notice, however, that the submit button remains inline. There’s a way to fix that:

  1. label, input[type=”submit’] { display: block; }

Diverting for a moment: CSS2 allows you to select elements based on attribute values. You can use this for many purposes, including selection with wildcards. For example, the following selector:

  1. img[title~=”Thumbnail”] { border: 2px solid black; }

Will match all images with a title attribute that contains the word “Thumbnail” as part of its value, such as:

  1. <img src=”thumbs/antelope.jpg” title=”Thumbnail image of an antelope” />

Option 2

Label and input on same line, label evenly spaced, using block, float, and clear.

Returning to forms: many designs call for labels to be beside their associated form fields, to save on space. In that case, there are two possibilities. The first is an extension of the technique we just used:

  1. label { display: block; width: 10em; clear: left; }
  2. label,input { float: left; }

The CSS reads as follows: when the browser encounters a new <label> tag, display it as a block element (so we can give it a width), and make sure that everything is cleared to its left (i.e. nothing comes before it on the line, or influences where the line falls). That will force each element onto a new line when it appears, floating to the left of the following element.

The only problem you may encounter with this technique would be putting two input tags next to each other, such as a divided postal code, or an area code and phone number. In that case, you could overrule the embedded or linked style with an inline style on the affected element.

Option 3

Label and input on same line, label evenly spaced, using display:table-cell

Another possibility for lining up our labels comes from using variants of display: table, the basics of which we covered in a previous section. Essentially, we want our labels to act as if they are in a single column of a table, which should make the width provided to them exactly the same. To the HTML we have used above, we apply the following CSS:

  1. label, input { display: table-cell; }

The problem is that the browser does not know when to place label-input pairs on a new line. We’ll do so by adding a div around each pair, and adding appropriate CSS:

  1. <div>
  2. <label for=”postalcode” accesskey=”c”>Postal Code</label>
  3. <input type=”text” name=”postalcode” id=”postalcode” size=”9” maxlength=”7”/>
  4. </div>
  5. <div>
  6. <label for=”phonenumber” accesskey=”n”>Phone Number</label>
  7. <input type=”text” name=” phone number” id=” phone number” size=”10”
  8. maxlength=”8”/>
  9. </div>

As they are block elements, the divs will automatically divide the label-input pairs onto separate lines. The divs are only used in the context of a form with valid markup, so we can use a descendant selector in our declaration:

  1. form div { display: table-row; }

Now, in addition to placing the label-input pairs on separate lines, each div also acts like a table row, meaning that each column of implied “cells” takes up the same width.

web developer guide

featured comment

by JoelB in Goodbye, JQuery Validation: HTML5 Form Errors With CSS3

what i'm reading

A Storm of Swords: A Song of Ice and Fire: Book Three
A Storm of Swords: A Song of Ice and Fire: Book Three

what i'm watching

Californication: The Third Season
Californication: The Third Season

what i'm playing

Mass Effect 3 Collector's Edition
Mass Effect 3 Collector's Edition

what i'm hearing

Dub FX
Dub FX

blogs

podcasts

no ads ever

This blog is free of advertising, and always will be.

creative commons licensed

The content of this blog is free to use in whatever way you wish under the Creative Commons license.