- Accessible CSS Forms: Using CSS to Create a Two-Column Layout – replace tables with css layout form tutorial
- Figure 1: CSS Forms Layout Example (image)
- Table-Based Contact Form
- Personal Information
- Comments
- Building a CSS-based Form
- Figure 2: Unstyled CSS Form Layout Example (screenshot)
- Add CSS Float, mix well
- Set Form Width
- Bump up Legend Size and Underline First Letter
- Figure 3: Opera Breaks First-Letter Underlined Legends
- Break Clear of the Ordinary
- Miscellaneous Tweaks and Workarounds
- Indent Instructions to Second Column
- Dummy Label Element
- CSS Gotchas
- Figure 4: IE5x Mac Breaks Left with Display Inline
- Floating Safari Hides Input Buttons
- Figure 5: Safari Mac Can Hide or Obscure Buttons
- Padding the Cellmates
- Multicolumn Forms
- Conclusion
- Further Reading
Accessible CSS Forms: Using CSS to Create a Two-Column Layout – replace tables with css layout form tutorial
Websites have become less accessible and more complex over time according to recent studies. Learn how to buck the trend by creating fast, accessible CSS forms that work with modern browsers and gracefully degrade.
In a recent study of web design patterns, Dr. Melody Ivory found that accessibility is the most underutilized aspect of good web page design (Ivory 2005). In fact websites have become more complex and less accessible over time (Hackett 2003). Less than 20% of the Fortune 100 have websites that are fully accessible (Loiacono 2004). Accessible forms are one way to combat this disturbing trend. With CSS layout, you can create two-column forms without the use of tables to save space and time. This article shows how to create a simple two-column contact form using CSS to style structural elements that is both fast and accessible.
A survey of CSS-based forms revealed many variations on a theme (see Vandersluis 2004). Most use block-level floats and margins to position form elements on the page. However, in my testing I found IE5.x Mac to have rendering problems with many of these forms. After numerous iterations, I arrived at a solution that worked for IE5.x Mac as well as Safari 1.07 Mac, Firefox 1.07 Win/Mac, IE 6 Win, Camino, and Opera. Our goal here is to create a simple accessible contact form without the use of tables (see Figure 1).
Figure 1: CSS Forms Layout Example (image)
Table-Based Contact Form
First let’s look at the old way of laying out a form. Tables use columns and rows to align labels and input fields (see Figure 2).
Personal Information
First name: Last name: Email: Comments
Your comments:
Note how much of the XHTML code is used for layout. Note also that this is an minimalist example with little or no accessibility features. The resulting table looks something like this rendered in a browser.
Unfortunately, laying out a form with tables can make it difficult to access for folks with disabilities. Table-based layout also lowers your content to markup ratio, which reduces potential SEO rankings and speed. Fortunately there is a better way, CSS layout.
Building a CSS-based Form
The key to any CSS conversion project is to strip down your XHTML to bare structural elements, and then use CSS to contextually target as much style and layout as possible using few embedded classes or IDs. Forms are no different. What the table-based form above is missing are semantic elements the W3C provides in the (X)HTML specifications, namely FIELDSET and LABEL. Although they can be funkily interpreted for background colors, FIELDSET and LABEL give logical order to FORMs. FIELDSET groups like-minded form input fields and LABEL FOR links field labels with input fields through the ID attribute to make them more accessible and eminently stylable. Let’s take the above table-based form code and strip it down to the bare essentials.
>
This barebones contact form contains the same fields, but they are now surrounded by semantic markup, not layout. The first FIELDSET groups the personal data together, while the second groups the comment field into one group. This style-free form looks like this (see Figure 2).
Figure 2: Unstyled CSS Form Layout Example (screenshot)
Add CSS Float, mix well
The key to laying out a two-column form is to float the label (and input in some cases) element thus:
Note that CSS purists may object to the fixed width, attempts at relative widths using ems or percentages were met with browser rendering problems. The above code creates a two column layout using the label and input elements of the above form. Note that for multiple elements placed after one floated label the second and subsequent elements may break left. Since we use only one input element per label, we’re on safe ground here. Later on we’ll show how to indent instructive text to the second “column” with a margin-left command.
Set Form Width
Next we set a width for our form and style the fieldsets. Note how we use the form element to set a min/max width. Unfortunately fieldsets are not rendered identically by different browsers. Backgrounds can overlap, padding doesn’t behave, and they tend to take up the entire width of the screen on Internet Explorer. Auto, ems, and percentages were tried, but the form misbehaved stretching this way and that. A pixel value larger than the largest anticipated font size did the trick, avoiding wrapping. However we chose to set the width using the form element, which bypassed the problem.
Bump up Legend Size and Underline First Letter
Next we bump up the legend font size and underline the first letter of our labels to signify our access keys. Note that Firefox 1.07 Win and Explorer 5.2 Mac do not appear to support the first-letter pseudo-class on legend elements. Opera also breaks the legend after the first letter underlined (despite attempts to fix this with white-space:nowrap;, see Figure 3).
Figure 3: Opera Breaks First-Letter Underlined Legends
Due to these legendary problems (thanks to readers below who pointed the Opera problem out) we switched to underlining the first letter in our labels ( form fieldset label:first-letter; ) which works on all browsers tested and requires accesskey attributes in each input field.
form fieldset legend < font-size:1.1em; /* bump up legend font size, not too large or it'll overwrite border on left */ /* be careful with padding, it'll shift the nice offset on top of border */ >form fieldset label:first-letter < /* use first-letter pseudo-class to underline accesskey, note that */ text-decoration:underline; /* Firefox 1.07 WIN and Explorer 5.2 Mac don't support first-letter */ /* pseudo-class on legend elements, but do support it on label elements */ /* we instead underline first letter on each label element and accesskey */ /* each input. doing only legends would lessen cognitive load */ >
Break Clear of the Ordinary
We need to clear our floats somehow, and clearing on the structural elements didn’t work in all browsers tested, so we used a BR element, which also helps our form gracefully degrade for older browsers.
Miscellaneous Tweaks and Workarounds
Indent Instructions to Second Column
To add instructions to the right column you can set a left margin equal to the accumulated indent of the input fields. This is simpler than using a dummy label element.
Dummy Label Element
Speaking of which, we found that the alignment of our submit and reset buttons was more consistent using a dummy label element than a left margin. You can use the above technique to indent these elements but we found the positioning was inconsistent between browsers. We were trying to avoid CSS hacks and browser sniffing so the “kludge” label was the most expedient method (this could be renamed as “submit” for clarity).
CSS Gotchas
One gotcha to watch out for is in the notoriously finicky IE5 Mac. If you specify display: inline for the input and textarea elements they break left in IE5x Mac (see Figure 4).
Figure 4: IE5x Mac Breaks Left with Display Inline
Floating Safari Hides Input Buttons
Make sure you test your creation in Safari as well. We ran into disappearing or obscured buttons when floating both labels and input elements (see Figure 5).
Figure 5: Safari Mac Can Hide or Obscure Buttons
If you do choose to float your inputs, we surmise it is the floats applied to our input buttons, removing floats and displaying inline solved the problem (see code below). We chose to avoid the problem entirely by floating only our labels.
form input#submit, form input#reset
Padding the Cellmates
We tried adding padding between the flush right labels and flush left input elements using margins and padding on the right side of our labels. This didn’t work as well as we would have hoped, giving inconsistent positioning on our textarea element. Adding margins to the left of our input and textarea form elements worked more consistently in IE6 Win.
The final product can be seen below and in a separate CSS form complete with JavaScript to focus the cursor in the first input element.
Here is the CSS and form code.
Bold fields are required. Underlined letters are accesskeys.