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:
form
fieldset
legend
label
input
as:- text field
- checkbox
- submit button
select
textarea
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