In this article I'll explain how to format form elements by using CSS.
Finally, I'll provide a series of screenshots taken from the various browsers.
The markup
We start with the following markup:
<form action="#" method="post"> <fieldset> <legend>Personal information</legend> <div class="row"> <label for="name">Name:</label> <input type="text" name="name" id="name" /> <label for="email">Email:</label> <input type="text" name="email" id="email" /> </div> <div class="row"> <label for="male">Male</label> <input type="checkbox" value="male" id="male" name="male" /> <label for="female">Female</label> <input type="checkbox" value="female" id="female" name="female" /> <label for="country">Country:</label> <select name="country" id="country"> <option value="USA">USA</option> <option value="Italy">Italy</option> </select> </div> <div class="row"> <h2>Comments</h2> <textarea rows="10" cols="40"></textarea> </div> <div class="row"> <input type="submit" id="btn" name="btn" value="Send" /> </div> </fieldset> </form>
We're going to stylize the following elements:
formfieldsetlegendlabelinputas:- text field
- checkbox
- submit button
selecttextarea
Note that we've used proper attributes for each element, due to accessibility reasons.
General styles
The following styles set only the backbone for further and more advanced styles.
form, fieldset {
margin: 0;
padding: 0;
}
form {
width: 500px;
background: #ffe;
color: #000;
font: small Verdana, sans-serif;
}
We've resetted the default margin and padding on the form and fieldset elements.
Then we've specified a width for our form, plus font and colors.
Adding some padding to the form
We need some vertical padding to create a certain amount of vertical spaces above and below the blocks. So we can write the following:
form {
padding: 1em 0;
}
Fieldset and legend
Now we can start stylizing the fieldset and legend elements. Styles are the following:
fieldset {
display: block;
width: 90%;
margin: 0 auto;
border: 1px solid #666;
}
legend {
padding: 0 0.2em;
background: #c00;
color: #fff;
font-weight: bold;
text-transform: uppercase;
margin-left: 0.5em;
}
fieldset is actually a block-level element, but we've declared it explicitly in order to prevent browsers
from applying their internal algorithms for handling form elements. Then we've specified a width and we've centered this
element through horizontal automatic margins. On the contrary, legend is an inline element, so we've only added
a left margin and some horizontal padding. Just for the record, Internet Explorer 7 (and lower) doesn't need a left margin to
keep this element separated from the fieldset's left border, so we've used the following code only for Internet
Explorer:
<!--[if lt IE 8]>
<style type="text/css" media="screen">
legend {margin-left: 0}
</style>
<![endif]-->
What's more, legend is one of those elements that is actually "locked" by browser's algorithms so that
we can specify only a few styles on it.
Creating centered rows
After centering the main content of our form, we want to center the other elements. This can be done very easily.
div.row {
width: 90%;
margin: 0 auto;
padding: 1em 0;
}
We use vertical padding instead of margins in order to avoid some problems with Internet Explorer 7 (and lower), namely the wrong computation of margins in a form.
Input and label
Now we can stylize the text fields and the label elements.
label {
vertical-align: middle;
font-weight: bold;
}
input {
font: 1em Verdana, sans-serif;
vertical-align: middle;
}
input#name, input#email {
width: 100px;
border: 1px solid #c00;
background: #fff;
}
To vertically align the elements, we've used the vertical-align property set to middle.
Another important thing to keep in mind is that the actual dimensions of text fields are determined by the type and
size of the font in use. For that reason, we've specified a font family and a font size on each input element, so
that the vertical alignment can be handled correctly.
However, the rendering of checkboxes is really inconsistent, so we've skipped these elements. Again, this kind of elements seems to be "locked" by the default algorithms of most browsers.
Select
The styles for the select element are really simple.
select {
font: 1em Verdana, sans-serif;
vertical-align: middle;
width: 95px;
}
As for the input element, we've vertically aligned this element and specified the same
font family and size used above. In this case, Internet Explorer 7 (and lower) has some problems with
the specified width, so it needs the following code:
<!--[if lt IE 8]>
<style type="text/css" media="screen">
select {width: 99px}
</style>
<![endif]-->
However, the rendering of the option elements is really inconsistent, so we've skipped these elements. Again, this kind of elements
seems to be "locked" by the default algorithms of most browsers.
Textarea and submit button
These elements have the following styles:
textarea {
display: block;
width: 100%;
background: #fff;
border: 1px solid #c00;
font: 1em Verdana, sans-serif;
overflow: auto;
}
input#btn {
background: #c00;
border: 1px solid #800;
color: #fff;
font-weight: bold;
}
The textarea element is an inline-block element, so we've declared it as a block-level
element. The declaration overflow: auto should prevent browsers from showing the trackbar
for the vertical scrollbar, but this solution doesn't work in all cases. What's more, Internet Explorer
7 (and lower) has some problems with the correct calculation of the width of the element and it needs
the following code:
<!--[if lt IE 8]>
<style type="text/css" media="screen">
textarea {width: 99%}
</style>
<![endif]-->
Final result
Our final layout appears as follows in the four major browsers.
-
Firefox
-
Internet Explorer
-
Opera
-
Safari