Member Sign In
Not a member?

A Wired.com user account lets you create, edit and comment on Webmonkey articles. You will also be able to contribute to the Wired How-To Wiki and comment on news stories at Wired.com.


It's fast and free.

Sign in with OpenID
Sign In
Webmonkey is a property of Wired Digital.
processing...
Join Webmonkey

Please send me occasional e-mail updates about new features and special offers from Wired/Webmonkey.
Yes No

Please send occasional e-mail offers from Wired/Webmonkey affiliated web sites and publications, and carefully selected companies.
Yes No

I understand and agree that registration on or use of this site constitutes agreement to Webmonkey's User Agreement and Privacy Policy.
Webmonkey is a property of Wired Digital.
processing...

Retrieve Sign In

Please enter your e-mail address or username below. Your username and password will be sent to the e-mail address you provided us.

or
Webmonkey is a property of Wired Digital.
processing...

Welcome to Webmonkey

A private profile page has been created for you.
As a member of Webmonkey, you can now:
  • edit articles
  • add to the code library
  • design and write a tutorial
  • comment on any Webmonkey article
Close
Webmonkey is a property of Wired Digital.

Sign In Information Sent

An e-mail has been sent to the e-mail address registered in this account.
If you cannot find it in your in-box, please check your bulk or junk folders.
Sign In
Webmonkey is a property of Wired Digital.

Stylize Forms With CSS

/skill level/
/viewed/
0 Times

Web forms are one of the uglier elements on web pages. These pull-downs, text boxes, radio buttons and checkboxes are often blocky, awkward and out of place in the overall design of the page. There's a good reason; styling forms is challenging.

The problem is complicated by the myriad of ways to mark up a form using HTML. Since the markup often changes from site to site, it's difficult to create a clean, reusable code base you can move from one website to the next. We figured out a way, of course. If we didn't you wouldn't be reading this right now.

So read on. We're going to break down the elements of web forms and talk about how to handle them in your stylesheets.

Got a tip we forgot to cover? Log in and add it to this page. The article is on a wiki, after all."

Contents

What you'll need

  • A working understanding of HTML, especially <form> elements
  • Decent CSS knowledge
  • An eye for web page design

Understand the HTML

For every <form> element, there are a number of tags available. Not all of them are necessary, but here's an overview of some of the tools at your disposal:

  1. form -- hopefully obvious, this is the container tag
  2. fieldset -- often overlooked the <fieldset> tag is a handy way of grouping related form elements
  3. legend -- used in conjunction with <fieldset>, legend allows you to add a caption to each fieldset. Think of it as a title for your fieldsets
  4. label -- the label has two purposes, first it tells the user what sort of data the input requires and it also creates a code-level link between the data being collected and the control element
  5. input -- the meat of your form, this is the tag that actually collects the user data and passes it on

As an example of how you might use these elements to mark up your form, let's take a look at one of the most common forms on the web -- the comment form. Here's what your HTML might look like:

<form action="#" class="myform">
    <fieldset>
        <legend>Leave a Comment</legend>
        <ul>
            <li>
                <label for="name">Name:</label>
                <input id="name" />
            </li>
            <li>
                <label for="email">Email:</label>
                <input id="email" />
            </li>
            <li>
                <label for="comment">Comments:</label>
                <textarea id="comments" rows="7" cols="25"></textarea>
            </li>
            <li>
                <label for="remember">Remember Me:</label>
                <input type="radio" name="remember" value="true" />Yes
                <input type="radio" name="remember" value="false" checked/>No
            </li>
        </ul>
    </fieldset>
    <p><input type="submit" value="Leave comment" /></p>
</form>

Let's break this down and see what's going on. First off we have the form container tag. Obviously you'd want to switch out the "#" for the path to your form processing script. Next we use a fieldset tag to group together all of our form elements except for the button at the bottom which we've wrapped in paragraph tags.

Next up we add a legend tag so people will know this is the comment form. Then we use an unordered list to group our form elements. Why? Well, for one thing it makes it easy to style. Each %lt;li> tag acts as a container for a row in our form with the label and input conveniently grouped together. The other reason is semantic. A form is gathering a list of data. Now you could make the argument that a definition list might be the more semantically valid choice, but it makes styling a bit more complicated. For simplicity's sake, we'll stick with the unordered list.

Adding Some Style

Now that we have the HTML elements in place let's add some CSS styles to make our form look better.

form.myform {
    margin-left: 155px;
    width: 300px;
}
form.myform fieldset {
   margin-bottom: 10px;
   margin-left: -155px;
}
form.myform legend {
    padding: 0 2px;
    font-weight: bold;
    font-size: 1.6em;
}
form.myform fieldset ul {
    margin: 0 0 0 155px;
    padding: 0;
}
form.myform fieldset li {
    list-style: none;
    padding: 10px;
    margin: 0;
    clear: both;
}

form.myform label {
    font-weight: bold;
    float: left;
    text-align:right;
    margin-left: -155px;
    width: 150px;
}
form.myform p{
    margin-left: 155px;
}

What we've done here is just add some basic margin and padding so that all our elements nicely spaced and then remove the default list element styles.

The only thing slightly tricky in this CSS is adding a left margin to the whole form and then pulling the fieldset and label tags back with a negative left margin. This has the effect of creating a two column look to our form. The left side holds all the labels, the right side all of the inputs.

Here's roughly what your form should now look like :

(screenshot taken in Firefox 3.0)
(screenshot taken in Firefox 3.0)

It's a bit spartan, but a good starting point. Before we move on we should point out that, while it doesn't affect our form, the Internet Explorer 6 "3-pixel bug" often pops up when styling multiline forms. It can make things like inline checkboxes very difficult to deal with. Fortunately there's a solution that isn't too hard to implement. Check out Position is Everything for the details.

Making It Prettier

Now we have a nice structure to our form and there are countless possibilities for styling the other various elements. Here's one take that we whipped up. This code will create a nice pale blue form with shaded text inputs and highlighting for the active text box. Paste the following code into the style definition below what we used above:

form.myform input, form.myform textarea {
    border: solid 1px #85b1de;
    background: #fff url('formbg.gif') repeat-x;
    background-position: top;
}
form.myform input:focus, form.myform textarea:focus {
    background-image: none;
    background-color: #ffffff;
    border: solid 1px #fded7f;
}

These styles add a nice blue border around all our input areas and includes an image with a slight gradient to shade the text areas. To round out the bluish look, add a background to the fieldset tag like so:

form.myform fieldset {
    margin-bottom: 10px;
    margin-left: -155px;
    background: #d0d9fd;
}

Your form should now look like the screenshot below, which shows the new blue look with the yellow highlight to let users know which field is currently selected. If you can't see the yellow highlight CSS won't work in IE 6. To accomplish something similar in a way that IE 6 can handle, you'll need to resort to JavaScript.

(screenshot in Safari on a Mac)
(screenshot in Safari on a Mac)

One thing to note about styling the background using the fieldset element: IE 6 may apply the background beyond the fieldset border causing a bit of spillover. The problem is that IE 6 applies the background color to the legend tag as well. The solution is to position the legend tag outside the usual document flow by using position:absolute;. Check out Matt Heerema's blog for more details on how to handle the IE 6 workaround.

The End Result

Here's an example of the code in action. Of course, filling out and submitting this form does nothing. It's an example. If you really want to leave a comment, head over to this article's discussion page.

Alternate methods

If the whole thing seems just too much for you, have a look at the JavaScript library Niceforms which handles some of the heavy lifting for you. In our experience, Niceforms doesn't degrade too well in some instances.

Other resources for styling forms include A List Apart's Pretty Accessible Forms and Eric Meyer's Formal Weirdness, which covers some of the cross-browser issues you might encounter.

Conclusion

As we've seen, styling forms is not the easiest thing in the world. However, once you understand the basic tags and the options available, it isn't terribly difficult to create well-styled forms that can go a long way to making your site much more usable and attractive.

Edit this article
Reddit Digg
 
Subscribe now

Special Offer For Webmonkey Users

WIRED magazine:
The first word on how technology is changing our world.

Subscribe for just $10 a year