Affecting the presentation of form fields on Web pages

The visual appearance of input fields in forms on Web pages, such as the width of a text input field or the color of a submit button, can be affected using presentational markup or style sheets (CSS) or both. This document discusses both ways and their practical effect on browsers. Some old browsers partly take text level markup around form fields into account, but modern browsers generally ignore it and are inclined into applying style sheet rules to fields.

Content

Introduction: how forms are displayed

Popular graphic browsers, such as Internet Explorer and Netscape, use roughly similar default presentation for forms. There is variation in minor details like fonts and field widths, of course. The following screenshots illustrate that the popular presentation need not be the only one:

A sample form displayed on IE 4 The same form displayed on Lynx 2.8 on Unix
[Screenshot of IE 4 displaying a form graphically] [Screenshot of Lynx displaying a form in text-only format]

The example illustrates that forms can be used in text-only mode too. There is no fundamental reason why one couldn't fill out and submit a form using e.g. a completely speech-based user interface, too. So as an author, you should expect much more variation in form presentation that can be seen between IE and Netscape with default settings. To illustrate the point further, the following table contains the sample form as presented by IE 4 and Netscape 4 under the control of a style sheet.

Display on IE 4 Display on Netscape 4
[A form presentation with light green background, some fields in light orange, etc. ] [A strange form presentation with the first field with light green background, etc. ]

Sadly enough, the presentation on Netscape 4 is rather horrible - worse than the presentation without stylesheets, since Netscape applies the stylistic suggestions wrongly (applying rules for the entire FORM element erroneously to its first field only!). This problem can be circumvented using "Todd's trick": put "Netscape-risky" CSS rules to a separate .css file (say unsafe.css) and include an @import for it (say @import url(unsafe.css)) into your main style sheet. If we do this to our example (demo available), the problem mentioned above vanishes. An alternative is to circumvent the bug by not using p markup inside the form; cf. to section Form background color, borders, etc.

Note that not all presentational details (e.g. the color of the "Browse" button) can be affected even on IE 4.

The next question to ask is: Can you, as an author, improve things by making presentational suggestions?

A user to whom form presentation really matters can perhaps write a user style sheet. Since it would be written for a particular browser, it could be tuned to work well on it. As an author, you are in a much worse situation. Your suggestion might work fine on your favorite browser, and fail miserably on others, especially due to browser bugs in style sheet implementation.

You could stop reading now if you decide that it does not pay off to try to tune form presentation. Just remember that the presentation may vary and will vary. If you decide otherwise, please proceed. Or you might now take a look at the colorful pages Colour My Forms and Colour my forms, one example at a time by Matthias Gutfeldt to see various ideas of form styling in action (to the extent that your browser supports that).

The alternatives: HTML markup and CSS rules

Although HTML is basically a simple hypertext markup language, not a page layout language, there are some elements and attributes for suggesting presentational details in HTML:

As regards to style sheets, the methods of making presentational suggestions are relatively simple per se. For example, to suggest that a one pixel wide solid green border be drawn around each form, you would write the style sheet rule
form { border : solid green 1px; }

The difficulties are mainly related to deficiencies and bugs in implementations. To use style sheets safely, you need to study the lists of reported browser bugs, but you cannot rely on them only. The lists are incomplete, and some bugs cannot be reported compactly since they bite in special circumstances only, when a particular combination of style sheet rules is present. Thus, you should carefully test a page using style sheets.

A case study: "forcing" buttons to equal size

The possibilities for affecting form field presentation using HTML markup or style sheets or both varies greatly, depending on the presentational suggestions. The following case study is just an illustration.

We won't discuss image buttons here. Although they let the author specify the exact width of a button in pixels when images are displayed, they tend to cause more problems than they might solve. See a separate document About image buttons.

Assume that we have the following form:

<form action="handler">
<table>
<tr><td><input type=submit name=subm value="Supercalifragilistic">
 </td></tr>
<tr><td><input type=submit name=subm value="Foo">
 </td></tr>
<tr><td><input type=submit name=subm value="Bar">
 </td></tr>
</table>
</form>

A typical browser then presents the buttons in different sizes, due to different lengths of the text in them. If you regard this as a problem, you could suggest the sizes of the buttons. At the simplest, when you wish to suggest that all input elements on a page occupy the same width, you could write something like the following into the HEAD part of the document:

<style><!--
input { width : 28ex; }
--></style>

This would suggest the width property for INPUT elements on the page. This works on IE 4, unless overridden by user style sheet. However, the text will be horizontally centered within the button, and it seems that a style sheet rule suggesting left alignment (using the text-align property) is ignored even by IE 4.

By HTML specifications, there is no HTML markup which would suggest a width for an INPUT TYPE="SUBMIT" element, or an INPUT element in general. However, some versions of Netscape seem to take a WIDTH="n" attribute as specifying the width in pixels; this appears to be an undocumented feature. A basic problem with it is the use of pixels, since the font size in pixels is unknown. Netscape seems to handle the attribute so that it specifies the minimum width, in the sense that if the text in a button requires more space than n pixels, a larger button is used. This is nice for usability but it implies that the technique cannot be used to force buttons to equal size.

Additionally, there is the usual hack of putting trailing spaces into the values of the VALUE attributes so that they have the same number of characters. This is something that the HTML 4 specification warns against:

User agents may ignore leading and trailing white space in CDATA attribute values (e.g., "   myval   " may be interpreted as "myval"). Authors should not declare attribute values with leading or trailing white space.

However, this hack looks harmless in this case if you regard it as what it is, a presentational suggestion made in a hackish way, and don't rely on it. (If the script that processes the form submission uses the value, it should thus strip off leading and trailing spaces first.)

But the hack does not do the job of making the buttons of equal width unless a monospace font is used. The effective way to achieve this on Netscape 4 for example is to put the INPUT elements within TT markup. This means something like the following:

<tr><td><input type=submit name=subm value="Foo                 ">
 </td></tr>

On the other hand, IE 4 ignores TT markup around INPUT. But it applies a style sheet suggestion to the same effect.

Combining these techniques, we get the following code which seems to cause the buttons appear in the same size on IE 4 and Netscape 4 (but not on Opera 3.51 for example). The text is in monospace font, and the actual width of the button varies from one browsing situation to another:

<style type="text/css"><!--
input { width : 28ex; font-family : Courier, monospace}
--></style>
<form action="handler">
<table>
<tr><td><tt><input type=submit name=subm value="Supercalifragilistic">
 </tt></td></tr>
<tr><td><tt><input type=submit name=subm value="Foo                 ">
 </tt></td></tr>
<tr><td><tt><input type=submit name=subm value="Bar                 ">
 </tt></td></tr>
</table>
</form>

Note: In a more realistic situation, where the page contains other kinds of INPUT elements too, you'd use e.g. CLASS attributes to specify to which of those elements the style sheet is to be applied.

The following table shows the rendering of a test document with the above-mentioned content on some browsers (with style sheets enabled):

Display on IE 4 Display on Netscape 4 Display on Opera 3.51
[all buttons of equal width] [all buttons of equal width but wider than on IE 4] [buttons of roughly the same width]

Opera 5 seems make the buttons of exactly equal width.

See also section Fixing the size of form controls? in Alan Flavell's Multiple Submit Buttons in HTML, which describes an interesting way to avoid the problem in some cases, by using submit buttons with the same text on them and the descriptions of their meanings alongside with each of them.

Widths of text input fields and textareas

The width of a single-line text input field (input type="text") can be suggested in HTML, using the size attribute. For a multi-line text input field (textarea), you must specify the suggested width, using the cols attribute. For both elements, the suggested width is specified as the number of "average characters" and it specifies the visible width only. (For input type="text", the maximum number of characters can be set using the maxlength attribute. For textarea, no such attribute exists; see How to limit the number of characters entered in a textarea .)

Browsers vary quite a lot in their interpretation of those attributes. Variations of 30 % and more in the visible width have been reported. It is not simply a matter of the browser name; it depends on browser version, platform, and settings too, especially on font issues.

Here's how your current browser displays an input field with size="25" containing first twenty x letters, then the digits 12345:

It is quite possible that you do not see all the 25 characters or that you see some extra space after them. It's not an error, just variation, though a considerable difference in either direction might be regarded as poor quality of implementation. Unfortunately such implementations are common.

Using style sheets, it is naturally possible to suggest a width in normal CSS units. Note that in CSS, there is no unit corresponding to the width of an average character! The ex unit might be a rough approximation, but just on the average. It is probably best not to try to use CSS for input field widths, since the HTML way is more logical (as regards to units) and works better in practice.

The presentation of form fields can often be improved by suggesting a monospace (non-proportional) font, because the HTML attributes size and cols work most consistently when a monospace font is used. (By definition, a monospace or "fixed-size" font is such that all characters occupy the same width.) There are two important practical reasons to consider doing so:

Since some browsers pay attention to HTML markup around form fields while some browsers apply CSS suggestions regarding fonts, you could combine the techniques to make it more probable that a monospace font is used. Example:

<tt><input type="text" name="foo" size ="25" style="font-family:monospace"></tt>

Applied to our example above, this gives the following appearance on your current browser:

This does not help on Opera 3.6. Authors shouldn't worry too much about this, since Opera users generally know their browser. They can set their browser preferences so that a monospace font is used in text input fields: Preferences -> Document Appearance... -> select Forms Text Field from the menu and pick up a monospace font (like Courier) for it.

If you suggest a global font (e.g. using body { font-family: Arial; } in your style sheet), remember that the font may then apply to form fields as well, unless you explicitly suggest a font face for them too (e.g. using input, textarea { font-family: monospace } in the style sheet).

Even this technique fails on some versions of Netscape 4 for textarea elements: if a font face is suggested for an element enclosing the textarea element, either with <font face> markup or in CSS, then that font is used for the textarea, even if you explicitly specify a different font for it! Quite often the best solution is to remove that font face suggestion, such as body { font-family: Arial; }. But if you really want to suggest a global font, the way to avoid the Netscape problem is to replace the style sheet rule by e.g. .body { font-family: Arial; } (note the dot) and use <div class="body">...</div> markup for any content before and after the form as well as for any block-level content before and after the textarea inside the form, and corresponding markup with span instead of div for any text-level (inline) content before and after the textarea in the block where it appears. Yes, this is clumsy.

The simple style sheet above would affect all input elements, including submit buttons. Currently you would need to use classes or some other ad hoc method for distinguishing between different kinds of input elements. For example, you could use
input {font-family: monospace; }
input.btn {font-family: Arial, sans-serif; }

and use class="btn" in any input element which is not type="text". This may sound redundant, and it is, but the attribute selectors defined in CSS2 for the purpose (e.g. input[type="text"]) are very poorly supported by browsers.

Aligning the content of a text input field

Especially when a text input field is for numeric input, one would like to have the contents of the fields right-aligned. This would be particularly nice when there are several such fields in a table:

The example above uses a style sheet containing text-align:right for the input fields. This seems to work in the intended way on Internet Explorer (from version 4.0 onwards, at least on Windows platform) and on Mozilla 1.0.

According to the CSS1 specification (and similarly by the CSS2 specification), the property text-align applies to block-level elements only, so one should not expect it to work for text-level (inline) elements such as INPUT. (And it has been reported that on IE 5.0 on Mac, it does not work: the fields of the example above have default (left) alignment.) One might think that by adding display:block to the style sheet we could formally make the element a block-level element in the CSS sense. (Note that you should then be prepared to seeing the field displayed in a block-like manner; if the field is the sole content of a table cell, this wouldn't matter.) On the other hand, this would cause problems in Netscape 4: it would the align the input box as a whole (just as when using the attribute ALIGN on HTML, see below). However, it is unclear how the rendering of elements like INPUT should be described in CSS, and setting display:block does not seem to improve the odds of getting the field content right-aligned.

To summarize, use text-align: right in order to right-align a text input field. It does not work on all browsers, but it seems to work on the great majority of modern browsers.

In HTML, the INPUT element can have an ALIGN attribute, so one might try <INPUT TYPE="TEXT" ... ALIGN="RIGHT"> instead of or in addition to using a stylesheet. That's however not a good idea at all. First, the specifications are vague about the meaning of such a construct. In the HTML 4.0 specification, the definition of the INPUT element refers to a generic definition of the ALIGN attribute, which should probably be read so that for INPUT, it refers to the text inside an input box. But no browser seems to have interpreted things that way. Internet Explorer 4.0 and Opera 3.60 seem to ignore the attribute, Netscape 4.0 aligns the input box as a whole, i.e. aligns it to the right margin of the page or the surrounding element (using left alignment for the text inside it)!

So is there anything one can do about it for Netscape 4? To some extent yes. You can use JavaScript to achieve some of the effect. Using the technique outlined in the answer to the question "How can you format numbers as right-aligned in a text field?" in the JavaScript Forms FAQ you can, for example, make the browser right-align the field when the user focuses on another field (by clicking or tabbing). This isn't quite what you probably want, and of course it works only when JavaScript is enabled, but used in addition to a stylesheet it probably covers what can be covered. Example:

<script type="text/javascript" language="JavaScript"><!--
function pad(number,length) {
    var str = '' + number;
    if (str.length > length) {
        first = 0;
        while (str.charAt(first) == ' ' && first < length)
           first++; 
        str = str.substr(first); }
    while (str.length < length)
        str = ' ' + str;
    return str;}
//--></SCRIPT>

<form action="http://jkorpela.fi/cgi-bin/echo.cgi"
name="formName" method="post">
<table><tr>
<th>Type a number:</th>
<td><input type="text" name="number" size="5"
style="text-align:right;"
onchange=
"this.form.number.value=pad(this.form.number.value,5)">
</tr></table>
<p><input type="submit"></p>
</form>

This looks like the following in your current browser. You can test what happens if you type 123 and use the tab key to proceed to the submit field:

Type a number:

The padding causes space characters to be added to the actual field value, not just the visual appearance. The form handler must thus be prepared to handling numeric data with leading whitespace, but that's an obvious requirement for robust processing anyway.

Warning: Browsers are known to implement the WIDTH attribute with great variation: the number of characters that actually fit into the input box can differ significantly from the value suggested by the WIDTH attribute. This happens especially for large WIDTH values, and it means that the padding method is unreliable. Doing your best to suggest monospace font reduces the problems here.

About SELECT elements ("pulldown menus")

The width of a SELECT element

The rendering of a SELECT element varies. Typically the width of the presentation is determined by by the browser according to the length of the longest option contained. (Option means the content of an OPTION element.)

If an author wishes to suggest that the presentation be wider - and it seldom makes sense to try to make it narrower - you could use the (relatively harmless) hack of appending some number of &nbsp; entities to the longest of the options, e.g.

<option>Bar&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option>

But this is of course a rather limited method - and really a hack.

Alternatively or additionally, you might suggest a width using style sheets. At the simplest, that could be something like

<select name="somename" style="width:20em">

to suggest a width of 20 em units. But as explained above, even browsers which generally support CSS1 to some extent often ignore style sheets when rendering form input fields, so don't expect too much. For example, the code above has the desired effect on IE 4 but not on Netscape 4 or Opera 3.60. Warning: on IE, if the width suggested is narrower than the presentation of an option requires, the option is displayed truncated, with no possibility to see the whole text (without looking at HTML source)!

Netscape recognizes a WIDTH attribute for a SELECT element too, with a value to be specified in pixels. The problem with this is that pixel-valued measures are generally not suitable for use on the Web, since the properties of the actual presentation medium (such as pixel size and its relation to the font size) are not known. Compare to notes on the WIDTH attribute in the discussion of submit buttons.

Font size affects the width indirectly. But it seems that attempts to set font size for SELECT elements is very risky.

Font size in a SELECT element

It seems that IE 4 interprets font size suggestions for SELECT elements often wrongly. For example, font-size:small seems to increase font size.

I have composed a simple page for testing the effect of font size suggestions. IE 4 (and IE 5) interprets them quite inconsistently. One might perhaps use font-size:larger to suggest increased size, but for reduced size, any method that seems to work on IE 4 will cause serious problems. (For example, font-size:xx-small) will cause problems on browsers which implement style sheets correctly, making text extra extra small.)

Due to such bugs in CSS implementations, using HTML markup (e.g. <small> and </small>) around form fields is probably much less risky than using CSS for the purposes of changing font size. In particular, using the small element (for example, <small><select ... > ... </select></small) you can reduce font size on Netscape 4. It even works too well in the sense that the size is reduced even if the user has told Netscape to ignore font size suggestions on pages! (Such a setting removes the effect of small for normal text, and a user doing that probably has a good reason for it.) There's no effect on IE 4, which means that you avoid the problems mentioned above. But optimally, design the page so that you don't need to suggest reduced font size.

When authors think that they need to reduce font size in SELECT elements, they are usually trying to create some "navigational" pull-down menu into a (narrow) "navigational" frame. As the discussion above shows, there is no good solution to the problems caused that way. It is better to remove the ultimate cause of the problems. See Navigational pulldown menus in HTML and Dan's Web Tips on Frames.

Netscape 4's background color "feature" with radio buttons

The Netscape 4 browsers on Windows platforms have the strange feature that radio buttons appear in small boxes which have the color of the page background rather than the background color of the nearest environment (such as table cell background color suggested using <td bgcolor="...">, or a form background color suggested using style sheets).

In some cases this problem can be fixed using style sheets, but not the obvious way, due to bugs in Netscape 4's CSS support. I have written a separate document which shows some attempts to fix the problem.

The size of radio buttons and checkboxes

The default presentation of radion buttons and checkboxes is usually not very good from a usability point of view: the buttons and boxes are fairly small, so it can be difficult to hit them with a mouse under unfavorable conditions (like a mouse you are not that familiar with). See also Accessibility issues of checkboxes and radio buttons.

It seems that on Netscape 4, the sizes cannot be changed, whereas on IE 4, style sheets have the desired effect if you set the width and height properties to reasonable values. Normally you should set both of them to the same value, preferably using the em unit to make the proportions right. On the other hand, this is actually a bug, since those properties should not apply to inline (text-level) elements like input!

You could use a style sheet like
input.radio { width: 2em; height: 2em; }
and with the attribute class="radio" in all <input type="radio" ...> elements. The string radio is of course just an author-selected class name, with no magic meaning by itself.

This is just a demo to show the appearance of a radio button and a checkbox with their dimensions set to 2.5em (probably bigger than you want, just to make the effect, if any, clearly visible):
radio button 1 | radio button 2
checkbox

Beware that the method described above relies on incorrect browser behavior. If you see normal-sized buttons, then that's how things should be. If you add the declaration display:block for the relevant elements in the style sheet, then it will be correct for a browser to apply the width and height properties. However you will then need to take some precautions, since display:block means block-like presentation, with line breaks before and after. As one possibility, you might consider adding float:left.

"Extra vertical space after a submit button" (actually, any form)

[A grey Send button in a colored rectangle; under it, a yellow rectangle.] A relatively common problem is the appearance of extra vertical space, roughly corresponding to one empty line, after a form on a Web page. (See attached IE 4 screenshot for an illustration; the yellow rectangle is empty space where a table background shines through.) The problem is often classified as "extra vertical space after a submit button", but this is not the correct diagnosis.

Basically, it is caused by the way browsers normally display forms. It's mostly when authors put forms into tables that the extra space becomes a problem. Quite often, probably most often, the best solution is to take a different approach; see the document How to use tables to structurize forms in HTML, especially the note on the nesting a table inside a form in some cases.

Under some circumstances, the extra space can be removed using a style sheet which suggests margin-bottom:0 for the form element. However, this is ineffective on Netscape 4.0 for example.

For more information, see the separate document Problems with extra vertical space after forms.

Similar considerations apply to vertical space before a form. Such spacing may occur, depending on the browser and the context, and suggestion a value for margin-top in CSS may affect it.

The appearance of the Browse button in file input

Generally, if you use an input type="file" field in a form, you cannot affect the appearance of the Browse widget that appears, except on some browsers in rather uninteresting ways like the size of the button (but not the text). For some more information on this, see notes on the Browse button appearance in File input (or "upload") in HTML forms.

This is just a demo to show the appearance of the Browse button on your browser, for illustration:

Form background color, borders, etc.

It is often difficult to users to see which parts of a page belong to a form, or to note the presence of a form at all. A distinctive background color, perhaps even a background image, for a form, or a border around it, might help considerably.

Nowadays, we normally CSS for such purposes, so the following notes are mostly historic. In CSS, you simply set the background color, border, or other properties on the form element. Beware that you should explicitly close any open p (paragraph) element before the form. Otherwise, you might get bitten by a nasty form rendering bug on IE 7.

Since there are no suitable presentational attributes for a form element in HTML, we might use the mildly hackish way of putting the form into a single-cell table and using suitable attributes for the table and td elements. Example:

Your input:
<table align="left" border="2"
  bgcolor="#00ff00"><tr><td>
<form action="...">
Your input: <input name="x"><br>
<input type="submit">
</form>
</td></td></table>

A practical problem with this is the extra space below the form that several browsers leave there. Using style="margin-bottom:0" in the form tag prevents that on many browsers, but not on Netscape 4 for example.

Another way, which is in principle more logical and more flexible, is to use a style sheet. Example:

Your input:
<form action="..." style=
"background:#0f0 none; color:#000; border: solid #060 2px;">
Your input: <input name="x"><br>
<input type="submit">
</form>

Notes:

Your input:

Print a page without forms?

It would usually be natural to omit forms when printing a page. After all, forms (e.g. query forms or feedback forms) are mostly intended to be filled out and submitted online. There can be other elements too which don't make much sense in printed copies.

For your own use, e.g. when you wish to get your own page printed and distribute paper copies or publish it in printed media, you could use Internet Explorer 4 or newer which supports the technique explained in the sequel. This will take effect also when other people print your page, if they use such a browser. Note that the approach uses techniques specified in on W3C recommendations; it's just that other browsers don't support them yet.

You can use an external style sheet and refer to it using a LINK element with the attribute MEDIA="print". In the stylesheet, you can use the declaration display:none to suggest that an element be not rendered at all. For an example, see a page containing contact information about me; it contains two forms and associated texts which are best suppressed when printing the document (since they are forms to be used online only). I use the simple stylesheet

form, .noprint { display : none; }

and this means that on browsers supporting these features, all forms are left out when printing, and so are all elements with class="noprint". I use the SPAN and DIV elements (at the text level and at the block level, respectively) when there is no natural element (like P) to which I can attach class="noprint". It would probably be better to organize a document so that things related to a form, such as verbal explanations, which are to be suppressed on printing, are written inside the FORM element. But the method described above illustrates the general idea of suggesting that some parts of a Web page be left out in printed copies.

Help! My form field does not show at all!

Authors sometimes notice that a browser does not display a form field at all. This might be caused by a syntax error which makes the browser ignore some markup, so - as usual with HTML problems - you should validate your HTML first.

For your convenience, here is a simple interface to the WDG HTML Validator. Just type the URL of your document and submit:

But you might also have form fields outside FORM elements, which is formally valid, though often not meaningful. For some reason, Netscape decided to ignore such fields. Thus, the cure is to put the field(s) into FORM element(s). To take a simple case, if you are using the TEXTAREA element just to display some data in a scrollable box, you need to slap <FORM> and </FORM> around it. Technically, for valid HTML, you would need to include some ACTION attribute into the <FORM> tag, but that's basically just a formality, since the form can't be submitted. (You could make the ACTION point to the document where the form occurs, just to handle meaningfully the improbable case that some odd browser lets the user submit the form somehow.)