How to Style Forms in CSS
Date: Mar 17, 2006
Forms give you an easy way to get information back from visitors to your Web site. Although they might be the most common way to get feedback from your Web page, forms shouldn't be a hassle for your users. Jason Teague shows you how to use a bit of simple CSS to create attractive and interactive HTML forms.
Forms are an easy way for you to get information back from visitors to your Web site. However, many Web developers think that it’s enough just to throw a few form fields into a table, and let them fall where they may in the Web page. They then expect the would-be informant to sift through this mess of roughly aligned text and 3-D beveled boxes to figure out what information is needed (see Figure 1).
Figure 1 Without the styles, the HTML provides structure but is difficult to read.
EXAMPLE: http://www.webbedenvironments.com/examples/StylingForms/indexNOSTYLES.html
However, with only a little extra effort, you can control the appearance of forms (text fields, select boxes, buttons, labels, and so on) by using CSS. You can also greatly enhance the forms’ functionality with interactive styles—all without ever having to break out the HTML tables.
As with other HTML elements, CSS can easily control most form elements to define their borders, colors, and fonts, allowing you to design forms that better integrate with the look and feel of your Web site. In addition to the typographic and color controls, CSS can be used to better position form labels around their respective form fields. CSS makes it easy to quickly change a form’s layout, whereas tables are pretty much a one-trick pony.
Parts of a Form Element
Left to their own devices, HTML forms are displayed according to the styles dictated by the visitor’s browser and operating system. Often, these styles (which can be radically different from browser to browser) are clunky and unattractive. However, there are several properties under your control:
- Text: Includes both the text for the form label and the text within the form field.
- Background: Either a solid color or a background image can add a lot of contrast to make form fields stand out without becoming overwhelming.
- Padding: Space around the content of an element (from content to border).
- Borders: Line around an element.
- Margins: Space around the element (from border to other elements).
- Position: Place labels and form fields where you want them without having to resort to tables.
- Dimensions: Width and height.
- Other: Set exactly how the cursor appears.
Beyond styling the static form fields when they first appear in the Web browser, styles can also be applied to form elements when the mouse is over them (hover), after the mouse has clicked the element (focus), or when the user is interacting with the form element (active). Figure 2 shows the form with styles applied.
Figure 2 The same form with styles applied. Not a lot of extra work, but a much better user experience.
EXAMPLE: http://www.webbedenvironments.com/examples/StylingForms/index.html
Setting Up the Styles
Using CSS, you can specify styles that are applied directly to various form HTML tags. However, each form element has its own idiosyncrasies when it comes to CSS, and some browsers don’t allow you to change certain form elements at all. Therefore, unlike other HTML tags, you do not want to change the definitions of many of the most common form tags; instead, create different classes to be applied directly to the tags.
Fieldsets and Legends
The fieldset is an optional border around a form that can be used in conjunction with a form legend to set the form or parts of the form off from the rest of the page. With CSS, you can define the border and background that will go behind the form, as well as the general foreground colors and fonts to be used for the form text.
The legend is a label for the form that sits over the border of the fieldset in the top-left corner by default. The legend is a great way to add a textual description of the form that will stand out. (See Figure 3.)
fieldset {
font: 0.8em "Helvetica Neue", helvetica, arial, sans-serif;
color: #666;
background-color: #efefef;
padding: 2px;
border: solid 1px #d3d3d3;
width: 350px;
}
legend {
color: #666;
font-weight: bold;
font-variant: small-caps;
background-color: #d3d3d3;
padding: 2px 6px;
margin-bottom: 8px;
}
Figure 3 You’ll want to define the background, foreground color, border around the form, and general font appearance. The legend is an optional part of the fieldset that allows you to add a title.
Labels
Although labels for form fields can be set using any tag—or even no tag at all—the <label> tag was specifically designed to be used with form fields. The advantage of the label tag is that you can directly associate a particular label with a particular form field element so that clicking the label is the same as clicking the form element itself. For example, for a checkbox, you can click the associated label, and the checkbox is checked or unchecked.
You need to set labels up as block elements with a specific height and float them to the left. The width of the label then causes the form fields associated with them to all align flush on the right side, creating a very neat appearance that is easy to read and with no tables in sight.
label {
font-weight: bold;
line-height: normal;
text-align: right;
margin-right: 10px;
position: relative;
display: block;
float: left;
width: 125px;
}
You also want a class associated with the label tag called something like fieldLabel. This class is used to override the general label style when you need a label that sits directly next to the form element with which it is associated (as with the radio buttons).
label.fieldLabel {
display: inline;
float: none;
}
Input
There are actually several kinds of input elements, each defined by a different type of attribute, and each with its own idiosyncrasies. It’s generally not a good idea to set a universal style for the <input> tag because these styles are applied to all the various kinds of inputs, including text, checkboxes, and radio buttons. Instead, create a class for each input type and apply them directly to the input tags as needed.
Text Input
The default appearance of text input fields is determined by the operating system, but they generally have a clunky 3-D beveled border that can be very unattractive. However, you can control the border, background, foreground color, and font for form input boxes. Generally, you want them to appear as boxes that contrast other content on the page.
input.formInputText {
font-size: .8em;
color: #666;
background-color: #fee;
padding: 2px;
border: solid 1px #f66;
margin-right: 5px;
margin-bottom: 5px;
height: 15px;
}
One thing to keep in mind, though, is that some browsers (most notably Apple Safari) do not allow you to change the border of form elements.
In addition to the default static state for the text field, add a hover pseudo-class for the formInputField class. This pseudo-class creates a simple rollover effect whenever the visitor mouses over a text field; in this example, turning the box blue (see Figure 4).
input.formInputText:hover {
background-color: #ccffff;
border: solid 1px #006600;
color: #000;
cursor: pointer;
}
input.formInputText:focus {
color: #000;
background-color: #ffffff;
border: solid 1px #006600;
cursor: text;
}
Although the hover and focus states are an effective way to show which form element is about to be clicked, :hover does not work in Internet Explorer for Windows, which only allows the :hover pseudo-class to be applied to link tags and does not recognize :focus at all. This means that :hover doesn’t work with form fields. You can use JavaScript to achieve a similar result, though it takes a bit more effort.
Figure 4 Although you do not have to use the label tag to label form fields, it is highly recommended, especially since you can connect a label to an individual form element, so that clicking the label is the same as clicking the form element.
Text input fields should still look like input fields, but they don’t have to wreck your design. You can also change the appearance of the form field when the user interacts with it.
Select Input
Browsers vary greatly in what parts of the select input you can control with CSS. Most allow control of background color, foreground color, and fonts; however, most browsers don’t allow you to control the border. Safari and Camino don’t allow you to change the background and border for the elements at all, overriding all style changes with the Mac OS Aqua theme.
This is used to add styles to drop-down or multiselect form elements. (See Figure 5.) Although I have set the border for this class, many browsers will ignore this or place it only around the existing border.
select.formSelect {
font-size: .8em;
color: #666;
background-color: #fee;
padding: 2px;
border: solid 1px #f66;
margin-right: 5px;
margin-bottom: 5px;
cursor: pointer;
}
Again, you can add both :hover and :focus pseudo-classes to the form element to increase its interaction with the user.
select.formSelect:hover {
color: #333;
background-color: #ccffff;
border: solid 1px #006600;
}
select.formSelect:focus {
color: #000;
background-color: #ffffff;
border: solid 1px #006600;
}
Figure 5 The select field.
Radio/Check Input
Although styles affect radio/check input, it is usually not with the intended result. Most browsers simply apply the styles to the rectangular box around the element, leaving the central element unchanged. They are usually best left alone.
Button Input
Most browsers allow you to change the font and foreground color for buttons. However, Safari and Camino do not allow you to change the background and border for the buttons, overriding all style changes with the Mac OS Aqua theme.
Many browsers don’t allow you to affect anything other than the foreground color and font of the button, but Mozilla browsers and Internet Explorer allow you to change the border and background for the button. In this example, I added a background image to create a customized graphic button that looks very different from the standard form button.
input.formInputButton {
font-size: 1.2em;
vertical-align: middle;
font-weight: bolder;
text-align: center;
color: #300;
background: #f99 url(bg_button.png) repeat-x;
padding: 1px;
border: solid 1px #f66;
float: right;
cursor: pointer;
}
Add a :hover pseudo-class for the formInputButton class, which allows you to set a style for when the visitor hovers over the button. In this example, I simply created a new background graphic by turning the existing graphic 180 degrees, so it looks as if the button is pressed. You can then also set an :active state for the button so that the button reverts back to its normal state before the form is sent off. (See Figure 6.)
input.formInputButton:hover {
background-image: url(bg_button_hover.png);
}
input.formInputButton:active {
background-image: url(bg_button.png);
}
Figure 6 When the user hovers over the button, it looks depressed.
Adding the Classes
After you set up your classes, it’s time to set up your form. Don’t worry about making it look pretty in the HTML code (that’s what the CSS is for), but do use the for attribute with labels to associate them with a form field.
<label for="firstName">Name</label>
<input class="formInputText" type="text" name="firstName" id="firstName" value="First" size="12" maxlength="16" tabindex="1" onfocus="clearField(this)" />
I’m also using a simple JavaScript function that allows me to prepopulate the value of the field and then erase it when the user clicks in the field.
function clearField(obj) {
if (obj.defaultValue==obj.value) obj.value = ’’;
}
Of course, this technique can also be used to add further dynamic interactivity with the form.