Styling Forms with CSS

CSS can work wonders with boring Web forms. In this tutorial, you start with an ugly HTML form and turn it into something beautiful.

HTML forms are fantastically useful things, but by default they tend to look like something only a mother could love. Fortunately, with the aid of CSS, you can really transform the look of an HTML form, and make it much easier on the eye. This tutorial shows you how.

An example form

Let's take the ugly checkout form featured in the Creating accessible forms tutorial. Here's the ugly form with no CSS styling, and here's the same form, styled using CSS.

Take a look at the source of the pretty form — the CSS is in the head element near the top of the page. Let's briefly work through how we styled the form elements.

Styling the form element

  width: 400px;
  color: #3E4A49;
  background-color: #FEF7D6;
  padding: 20px;
  border: 2px solid #4899BE;
  font-family: "Trebuchet MS", Arial, Helvetica, Sans-serif;
  font-size: 0.8em;

Here we've set a fixed width on the form to prevent it stretching too wide, and set a nice colour and background colour. The padding gives the form room to "breathe". Finally we've set a pretty blue border around the form, given all the text in the form a nice font, and taken the font size down a bit to make it more visually appealing.

Styling the fieldset elements

  padding: 0 20px 20px;
  margin: 0 0 20px;
  border: 1px solid #3E4A49;

Now we style each of our fieldset elements with some padding, margin, and a nice solid border to replace the default inset border.

Styling the legend elements

  color: #FFFFFF;
  background-color: #4899BE;
  font-family: Arial, Helvetica, Sans-serif;
  font-size: 0.9em;
  font-weight: bold;
  padding: 5px;
  margin-bottom: 0;
  width: 9em;
  border: 1px solid #3E4A49;

We give the form legends a nice white-on-blue colour scheme and set a bold, smaller Arial font face for a bit of variety. Some padding stops the legend looking cramped, and we set a zero bottom margin to ensure that the gap between the legend and the first field below is consistent across all browsers. Finally we set a fixed width on the legends so they look nice and consistent, and give them the same border colour as the fieldset.

Styling the label elements

  display: block;
  float: left;
  clear: left;
  text-align: right;
  width: 30%;
  padding-top: 0.25em;
  margin: 1em 5px 0 0;

Now comes the clever stuff. To make sure that our form labels and fields line up nicely, we set the normally inline label elements to display: block so that we can float them to the left of the fields. We use clear: left to ensure that each label clears the float above it and starts flush with the left margin. Aligning the text right makes all the colons line up nicely. Finally we set a width on the labels (required for floated elements), a small amount of padding (to keep the label text vertically aligned with the field), a top margin to add vertical space between the fields, and a 5-pixel right margin to separate each label from its respective field.

Styling the form fields

input, select
  margin: 1em 0 0 0;
  width: 50%;
  border: 1px solid #FEF7D6;
  padding: 2px;
  background: transparent url("field_bg.gif") no-repeat 0 0;

Now we style the form fields themselves. We give them the same top margin as the labels and set them to a fixed width (50% of the form width). We then give them a border with the same colour as the form background (i.e. invisible) and set a background image to give that nice inner shadow style (an effect well known to you if you're a Safari user!). We also add a bit of padding so that our field text doesn't sit on top of the shadow.

input:focus, select:focus
  border: 1px solid #4899BE;

We use the :focus pseudo-class to give each field a blue border when it receives focus (again, a nice effect that Safari does by default). (Sadly :focus isn't supported by Internet Explorer on Windows. Oh well!)

Styling the form buttons

  text-align: right;
  margin: -15px 0 -5px 0;

  width: auto;
  background: #FFFFFF;
  border: 2px solid #4899BE;

Finally we style our buttons div (see below) so the the form control buttons are aligned right, and adjust the top and bottom margins so that the buttons are nicely spaced vertically in the form. Then we style the button itself with a normal (auto) width, a white background and a thick blue border.

Markup changes

We did cheat a bit and make a couple of changes to the form markup that couldn't be made in the CSS:

<legend accesskey="B"><span style="text-decoration: underline;">B</span>illing details</legend>
<legend accesskey="S"><span style="text-decoration: underline;">S</span>hipping details</legend>
<legend accesskey="P"><span style="text-decoration: underline;">P</span>ayment details</legend>

We've added access keys for the "Billing details", "Shipping details" and "Payment details" legends. When you press the access key for a legend, the browser usually gives focus to the first field in the fieldset that the label is attached to ("Name" or "Card number" in our case). Try it and see! We've also underlined the access key letter in each legend.

Here's the end result again.

That's it. Go forth and make beautiful forms!

Follow Elated

Related articles

Responses to this article

There are no responses yet.

Post a response

Want to add a comment, or ask a question about this article? Post a response.

To post responses you need to be a member. Not a member yet? Signing up is free, easy and only takes a minute. Sign up now.

Top of Page