Hello. I'm Aleksandar Vacić, professional web developer and wine maker in the making.
Learn more about me or see what I can do for you.

My work & services

Styling form fields

As long as I can remember, forms have always been problematic. They need to be short but complete, good looking but not confusing, informative but not cluttered.

These requests are often opposite, especially because designer’s view of those aspects is sometimes…hm, different then client’s.

Basic rules

I believe there is only one basic rule: do not change the overall look of the form elements.

People are used to form elements from the operating system they use. Elements like text fields, checkboxes, drop-down lists and buttons are something people deal with in their usual daily apps, and when they see them on the web, they imidiatelly know what to do with them, i.e. how to fill-in/choose data.

The usual victims are text fields and buttons, as they’re easiest to change.

How many of you recognized that this above is input-awaiting field? Hm, ok. What about your dad? It doesn’t matter if he does too. There’s always people that will be confused. And don’t expect them to call customer service – they are embarassed to not know how to fill-up the form and they will simply leave.

It’s nothing to laugh about. What is obvious to one, is stupid to another and unusable to third. Avoid that.

Another reason against the above is that you can’t style drop-down lists similar to that, so the whole form would look unfinished. Change colours or borders, but don’t remove borders or blend the fields into background.

With this in mind, lets see what we can do.

Structure

Form must look acceptable when unstyled, as well as being usable and accessible. W3C specs give us just enough form elements that we barely need something else. You can use fieldset to group elements, legend as heading for such groups and label for field captions.

What else we need? Well, we need to separate the fields. CSS gives us plenty of tools to make the form blocky without extra elements, but since label and form field elements are inline type of elements, in the unstyled version form will look like a mess, especially if you have small helper texts next to some fields:

Please note that password is case-sensitive.

There are few options: use br, div or p. Now, if you use any of the first two, elements will be in their own lines, but will be glued one to another:

Please note that password is case-sensitive.

As known, p is always rendered with one line after it, so it sounds like a good solution. After all, all form elements are of inline type, even if they look blocky. Real problem is that you can’t place another block element inside of paragraph – only inline elements can be nested in. And that is very limiting and I don’t want to backstep sometime in the future when some complicated form comes along the way. So, we are left with the combination of div and br – a bit of extra markup, but one that has no limitations and has good side that extend beyond the mere styling.

Now, lets review the markup rules:

Example form I’m gonna use features all of this – it’s an actual registration form from the commercial web site. Take some time to review the markup before we dive into…

Styles

In theory, using CSS and chosen structure, we should be able to style the forms in many various ways. Because of incredible series of browser bugs and/or incomplete support, real life styling options are only few, possibly just one.

I will present several ways, but you’ll see that each one of them has problems in one browser or another. Also note that in each of the examples I remove the brs – their sole purpose of existence is in the unstyled version.

fieldset br {
	display: none;
}

Labels for mandatory fields have class="mandat" which you can style every way you think is appropriate.

There is one little gem in all the styles. If you look at the date of birth group, you will see that each field has its own label, but they are so obvious that we don’t to label each element. Therefore, labels for month and year fields has additional class called removed, styled like this:

.removed {
	display: none !important;
}

Accesibility kept and neatness achieved. Well, I know. Totally correct would be to caption the whole group with paragraph and caption the day field as Day of birth (hidden as other two) – you can take that extra mile if you find it appropriate.

Float labels

This is probably the most used layout in the old, table-based way: line-up field captions in one column, aligned to the right, and place the fields in other column, aligned to the left. Here, it’s done rather easy: convert the labels to blocks, give them average width (I usually go with 10-15em) and float them to the left. Each block will clear the previous one. Check example 1 for full style, and here is the basic stuff:

fieldset div {
	clear: both;
	position: relative;
}

label, fieldset div.cr p {
	margin: 0;
	display: block;
	width: 13em;
	text-align: right;
	float: left;
}

fieldset div.cr label {
	text-align: left;
	margin-left: 13em;
	width: auto;
	float: none;
}

Here you see why the div for checkboxes and radio buttons has separate class. In this layout, those elements look best when aligned with the field column. So, for those labels we remove the floating and give them left margin identical to the width of the labels.

Now comes the best part. One of the common requests I mentioned at the beggining is that form should be informative but not cluttered. Some of the fields have such helper texts, but if displayed, they would spoil the neatness of the form. CSS offers the beautiful way of dealing with it; the :hover pseudo-class:

fieldset div span {
	display: none;
}
fieldset div:hover span {
	margin-left: 20em;
	display: block;
	position: absolute;
	z-index: 100;
	float: right;
}
* html fieldset div span {
	display: block;
}

Last rule is for IE/Win, as it does not support :hover on anything but a elements. I would gladly ignore it, if it wasn’t for the percentage of market it holds. It would be even better if we could do div:focus, since then the helper text would popup even if you don’t use the mouse (i.e. if you tab through the fields)….ah, wishful thinking.

Now, the dark side. This does not work at all in Camino 0.7, due to its severe bug concerning labels. None of rules you apply to label are rendered in Camino, and in this case that’s particularly problematic as fields are placed over the labels and you don’t see them at all. I expect it to be fixed in next version. So, for this style, Camino users: sorry, no joy.

Of course, browser that don’t support :hover (apart from IE) does not display the explanation (mainly Opera 6). Again: sorry, no joy.

Float fieldset

This is my favourite, the best one for liquid layouts. If you have big screen, you will save yourself some scrolling, and if you look at it on small screen (like PDA) the fieldsets would gracefully slide one below the other.

Essential part is to float fieldsets to the left without the specified width. Since the basic idea is to save space, labels will just be blocked, but not floated.

fieldset {
	float: left;
}
label {
	display: block;
}

Very simple and effective. This doesn’t work correctly in Opera 6, which just keeps stacking fieldsets one next to another, going beyond the right viewport edge. Bah. As known, IE5/Mac will render 100% width on all floated elements that don’t have specified width. Bah again. Anoyingly, Opera 7 does the same. Err…lame.

All other styles are just make-up. In this particular example, I tried to move the legend next to the left border, and sort of done it. It works in Opera 7, Safari and Mozilla. IE/Win required some extra nudging to the left, but not quite there. I leave it to you to set left margin 1px more and see what happens. If it isn’t tragic, it would be hilarious.

Block fieldset

This one if good to style with background images on the right side. For the fields and their respective captions, you can use any one of the previous two. Second (as used in the example) is a bit better as you have more room for the image.

Nothing fancy about it, but I included it here to show one particular problem. In IE and Opera, upper edge of the fieldset is lined up with the upper edge of the legend, but the fieldset’s border is drawn aligned to the middle of the legend. Thus, when you apply background color to the fieldset upper border, you get rather ugly rendering. Safari and Mozilla get it right. Be careful.

Fieldset tabs

This is the least usable thing, as only Safari (checked in 1.2 only) get it right. I wanted to move the legend to the left and then with a little script help make it switchable. Well, we will have to wait for something like this. I’m puzzled why Mozilla won’t move the legend beyond the left edge of the fieldset, as you can move it above. Bah…bah… This one is even better to make real tabs (again with some scripting) but the browser support again forces us to wait.

In the end…

…I’m feeling a bit down-hearted. First two layouts are good and usable, but I would be much happier if I could get those tabs to work. With extra markup is doable, but I don’t want to do it since I already have enough extra markup. Maybe in the future…

And with just two layouts, you can’t make that much difference in the world out there, do you..?

tags: CSS
Comments: 28

Posted 6 years, 1 month agopermanent link

trackback URL: http://aplus.rs/css/styling-form-fields/trackback/

Voices from the crowd, 28 so far

aleksandar,

thanks for pointing me towards your site on the webdesign-l mailing list. i think i prefer the first layout type called “float labels”.

i’m wondering how you handle validation of the form and notifying the user of errors? i tend to group all the errors at the top of the form in a box that is displayed if errors occur. however i think it’s easier for the to have errors appear next to fields in some way, but i haven’t come up with a good solution for this.

thanks for the insight.

by chris
1937 years, 3 months after the post

Chris, just check out the next post on my site. :)

by aleck
1937 years, 3 months after the post

I’m using to split form in rows and this tag is making “border” between form “cells”

also you can use input {…} not .textfield {…} — then html code will be smaller

and div input {.. width: auto;} — for checkboxes and radio boxes

ideally form should be:

optional
Name
Last name

and all style should be added with CSS (without additional div, p , etc elements) — but this will be possible only with CSS 3

by yoyo
1937 years, 3 months after the post

This article has » in the submit button but the author has missed out the trailing semi-colon. This means the symbol won’t render in Gecko-based browsers (Mozilla, Firefox, etc).

Also: the tabindex for the comment form fields are a little screwy as I can’t easily press tab to go from this text box to the “Name” or “Send your comment” inputs.

Nevertheless, a good article.

by David Carrington
11 months, 1 week after the post

Great stuff. You really helped a techie create some beautifully styled forms here.

by Marc Schipperheyn
11 months, 3 weeks after the post

Here’s how to do the focus for the helper text:

fieldset div:hover span,
fieldset input:focus + span {
margin-left: 20em;
display: block;
position: absolute;
z-index: 100;
float: right;
}

this displays the helper text when the preceding input is focused. Change (or add) other form elements as appropriate.

by Sean Williams
1 year after the post

Sean, thanks. It works like a charm in Firefox. I have not tried other browsers, but I believe that eventually all but IE would work.

by Aleksandar
1 year, 1 month after the post

If you use the ‘float labels’ version, and you need two inputs and labels on one line, just override the float: left and display: block for those labels:

HTML:

Street:
Number:

CSS:

label.oneline {
display: inline;
float: none;
}

by Nicky Peeters
1 year, 1 month after the post

Great Ideas,

My pages has come to life, also the code is clearer.
This and your post on validation has changed how I see & build web pages.

Thanks for making this available.

JM from Mexico City…

by Javier Martnez
1 year, 3 months after the post

My admin section i want to designed in some special look.
in php language. But the all form fields looking very boaring so i use this css and it looking very atteractive…

Thanks From,
Vinod N. Suryawanshi..

by vinod suryawanshi
1 year, 4 months after the post

good!

by asdf
1 year, 5 months after the post

Just in the midst of building a similar registration form and since I liked this article so much I thought I’d try to contribute a couple thoughts:
1) I like the idea of the tooltips for usability, but am thinking that another option is to have a Help cursor for the labels and provide the tool tip info as a title attribute for it. Downside is you don’t get the instant popup with the tips by default (would have to be set in OS or browser settings); upside: cross browser compatible… less markup.
2) RE: Accessibility… It turns out elements set to display none in CSS are actually not readable with some popular screen readers… hence the reason why many people are no longer using the Farner Image Replacement technique popularized in Zeldman’s book. IE: the DOB fields will be a lot less obvious than you might think. Only alternate methods I know are in the CSS Zen Garden Book… so no helpful links, sorry.

by Jacob
1 year, 5 months after the post

For some reason I cannot get the mandat removed class to do what it is supposed to. I am using the float labels form style and I am trying to get multiple fields on one line such as the birthday fields you have on your form. All that happens is the field label dissapears leaving the input box beside the last input box to its left.

No sure what I could be doing wrong.

Any advice would be very helpful.
Thanx.

by Jessica
1 year, 6 months after the post

I have tried :
css:

label.oneline {
display: inline;
float: none;
}

as Nicky Peeters suggests in an above comment but it takes the one line out of the alignment. The html is missing from the comment. Not sure if there is another way.

by Jessica
1 year, 6 months after the post

Jessica, no one can’t help you without the test URL. Post the test page somewhere, link it here and I’ll take a look when I can. Also, does this happens in all browsers or just some particular one?

by Aleksandar
1 year, 6 months after the post

http://celestialmonuments.com/homevisit/homevisit.html

It looks good in IE except for the input boxes on the same line. They are spread out to the right too much and in Firefox the input boxes overlap and I cant get the fieldset to have a set width in Firefox.

I would really appreciate your advice. :)

by Jessica
1 year, 6 months after the post

There is no “removed” class in the source code and for the date of birth only one input field exists. Are you sure this is the right page? :)

You need to use correct, full, DOCTYPE as well. I’m not sure styles would work properly in quirks mode (I would be surprised if they do).

by Aleksandar
1 year, 6 months after the post

I added the removed class to the second field of each line that had multiple fields on one line. The label is missing for each.

On that page I need to have apt# next to address input field.

there are a few more on that page that way.

I changed the doctype as well.

I still see an overlapping of input boxes in firefox.

I dont know what else I am needing here.

by Jessica
1 year, 6 months after the post

I found some time to look at this, but page is now missing (returns 404). :(

by Aleksandar
1 year, 6 months after the post

:) im sorry, here it is again:

http://celestialmonuments.com/homevisit/homevisit.html
thank you for taking a look.

by jessica
1 year, 6 months after the post

Jessica, the page looks just fine. Apt number is next to the address field and nothing overlaps.

by Aleksandar
1 year, 6 months after the post

Hi, Your tutorial is great — thanks so much for putting such a fine piece of work together. I have a question however, as I haven’t been able to make some elements function correctly and I’m not sure where I’ve gone wrong.

http://www.overlookpoint-montana.com/brochure2.htm attempts to use a textarea which doesn’t show up in IE (it does in Firefox, but not aligned). Also, I can’t get my first radio button to line up. Any suggestions?

by Vicky
1 year, 8 months after the post

I was looking everywhere to find out if those little dots in a password field can be made to look different. What if, for example, I want square dots instead of circular ones? Any idea?

by Sorin Rayban
1 year, 9 months after the post

Sorin, I’m not sure which circular dots are you refering..? “Dots” inside the password field are asterisks (*) — browser default when typing in password fields. You can change them only by chaning font. But that sign is the same everywhere.

by Aleksandar
1 year, 9 months after the post

Hi, I found your article concise and useful. Thank you. And I would like to ask when I use the label floats approach but the interesting thing when I float the label to left inherently textboxes are align to right. Are you controlling it with the width of fieldset? I had to put another float:left for textfields to align them left right after label.

by dejawoo
2 years after the post

dejawoo, I did not experience that. If the label is set to have fixed width and floated left, then input, as inline element, will slide next to it.

by Aleksandar
2 years after the post

Your wonderful form css was working just right on Firefox and failing nicelly on IE. Now IE7 tries to make the span visible, but fails by displaying the span on the rollover waaaaay to far to the right of the screen. Any fixes?

by Matt
2 years, 11 months after the post

Mozilla has the rather annoying flaw that you can’t move the legend about very much, as you pointed out. The solution is to put a span in the legend to contain the text, give the span block display and then position the span absolutely relative to the rigid legend box.

by Rafael
3 years after the post

Post your opinion


? You need to enter your email, but rest assured it will not be published.

? Enter the link and it will be published.
? This blog strives to behave properly, as per XHTML 1.0 Strict spec. You can use the following tags, but please use them wisely:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
? I have enabled comment moderation so if your comment does not shows up after you submit it, don't worry. I will review it and if it's nice and to the point, I'll approve it. This measure is up mostly to fight spam and trolls.

Tags or categories or topics...

Lots of ramblings on this blog...might be easier for you to find your juice through these tags:

Post a job. Find one. authenticjobs.com