Grow your CSS skills. Land your dream job.

Tips For Creating Great Web Forms

Published by Chris Coyier

1. Use Labels

You don't need labels for your form to work, but as one CSS-Tricks reader once put it, it is an accessibility crime not to use them. Labels are what signify what the input box is for and associate them together. The use of the <label> tag is not only semantically correct, but it gives you the opportunity to style them uniquely with CSS.

2. Float Your Labels

This is how you achieve that table-like structure on forms without having to actually use a table. Just set a static width, float it the left, align the text to the right, and give it a little right-margin. Beautiful.

label {
	float: left;
	text-align: right;
	margin-right: 15px;
	width: 100px;


3. Careful To Not Wreck Your Default Styling

A lot of browsers have default styling applied to input buttons. This provides a nice consistent user experience, so if you choose to interfere with this, make sure you have a good reason. A common way to break this is by using a CSS Reset technique that includes something like this:

* {
  border: none;

That can be nice, as it will prevent unwanted borders showing up around objects you didn't intend, but it will also break the default styling for input buttons in Firefox. Some browsers are more resilient and some are hard to change even if you want to (Safari).

4. Use the :focus Pseudo Class

You can apply styling to your input areas and textareas that only takes affect when a user has clicked into that area using the :focus pseudo class. For example, you could change the border color on those elements like so:

textarea:focus, input:focus {
	border: 2px solid #900;

Most browsers support it, so you might as well use it. Think forward-enhancement.


5. Prefill With Hints, But Clear Them Away

It can be useful to prefill your input fields and textareas with little hints or reminders. For example if you have a general contact form and a textarea labeled "Message:", you may want to prefill that textarea with something like "Your positive comments or constructive criticism here." Or, you could have a name field which is prefilled with "First Middle Last" so that you can remind users that is the order they should fill in their name. You can do that just by including text within your tags:

<textarea name="Message" rows="20" cols="20">Hint goes here.</textarea>

But if you stop there, the user will need to manually delete whatever you enter there, and that's no good. You can add a little Javascript to clear that hint away when the user clicks inside that box. This little code snippet also only allows that to happen once, so if the user clicks away and then back in, they won't lose what they have entered.

<textarea name="Message" rows="20" cols="20" onfocus="this.value=''; this.onfocus=null;">Hint goes here.</textarea>

6. Make it work with Web Form Factory

Forms aren't there just to look pretty, they need to work. There are two primary functions a web form can have: to interface with a database or to generate an email. Web Form Factory is an open source service which takes your form and generates the code needed to make it do what it needs to do.


7. Consider a Prefab Solution

Web forms is territory that has been gone over again and again and again. This is one area where not "re-inventing the wheel" might be the best decision you can make.

I think everyone should check out Wufoo. Wufoo is just absolutely the greatest form creator of all time. Their prices range from free to reasonable, the creation wizard is amazing, and the implementation of the forms onto your site couldn't be easier.



  1. Permalink to comment#

    Excellent post, thank you.

  2. If you are a WordPress user I would suggest cforms which allows you to create more than one form and stylise them from different themes.

  3. Permalink to comment#

    FYI. The :focus trick doesn’t work out of the box on IE. You can use the JS on this page to facilitate that..

  4. Thanks Sanjay, that is a great solution to facilitate IE’s lack of support for the focus pseudo class.

  5. Paul Dragicevich
    Permalink to comment#

    For dummies like myself, after experimenting a bit, I came up with some markup for the second point, not sure if its the best way but its semantic, I think!

    <li><label for=”input1″> <input type=”text” id=”input1″> </li>


    CSS wizards please let me know if there’s a better way to do it! With appropriate styling for the unsigned list, of course, and the label style as above.

  6. Hi Paul,

    Yep, that’s the gist of it.

    Here is some simple form markup:

    <form method="post" action="do-something.php">
      <label for="Name">Name:</label>
      <input type="text" name="Name" /><br />
      <label for="City">City:</label>
      <input type="text" name="City" /><br />
      <input type="submit" name="submit" value="Submit" class="submit-button" />
  7. Any good resources for nice-looking (custom) forms in Safari? I lose more hair over styling forms in Safari.

  8. I’m afraid I don’t have any great tips for dealing specifically with Safari. Safari is kind of in a class by itself with how it forces it’s own focus states and buttons and dropdowns and stuff. It can be frustrating as a designer if you really have a plan for those things and are having trouble fighting Safari, but in general I find the default stuff just fine.

  9. Chris, regarding to your example of simple markup example. The value of the attribute for must be identical to the attribute id within the control element. Therefore:

    <input id="Name" type="text" name="Name" />

    I want to mention it to prevent any mistakes by your readers.


  10. Permalink to comment#

    Thank you for these excellent tips.
    This is a great site.

  11. That wufoo form website was not too bad. I have used it for a website I am developing at the moment :D

  12. Arg! Please do not do that onfocus clear value.
    Why? Well if a user starts to type something into the input then alt+tabs or otherwise leaves the window (say to copy a url to cite a refrenece etc) and then alt+tab’s back it will trigger an onblur event (when you alt+tab away) and an onfocus event (when you alt+tab back) which will clear what you were typing.

    A better way is to check that the current value == the default value before clearing, to do this on page load cycle through your inputs and check for a value store this as input.defaultValue and then do something like:

    onfocus=”if(this.defaultValue==this.value) this.value=”;”

  13. Permalink to comment#

    I had been trying to figure out the thing with form element focus for ages! Can’t believe I didn’t think of :focus. Great idea.

  14. @Aaron: Actually, it won’t. That scenario is addressed with the second code block shown there.

    onfocus="this.value=''; this.onfocus=null;">

    If it was just onfocus=”this.value=”; then it would clear every time, but this way it will not once you start entering text. Unless I’m not understanding you correctly?

  15. I wish people would stop saying that “most browsers” support the :focus pseudo class – it gives the wrong impression to people learning stuff.

    :focus is cool but don’t rely on it as IE6 (largest market share still regardless of what Microsoft say) does NOT support it!

  16. The reason I said “most browsers support it so you might as well us it” is exactly that. The :focus pseudo class is nice for usability and style, but it doesn’t affect functionality. So use it, and users with most browsers will benefit and users with IE 6 will still have a fully functional form.

    In fact, it might even encourage people to learn, since they may notice how it doesn’t work in IE and seek out a fix (javascript).

  17. Permalink to comment#

    Also worth mentioning is that you should avoid adding the JavaScript functionality through inline event handlers – it mixes content and behaviour. Take a look at the YUI YAHOO.Util.Event.addEventListener method, similar methods in other libraries or the core browser functions addEventListener and attachEvent (IE).

  18. Hi Ed,

    Wow, a real Yahoo! employee, how flattering =)

    You bring up an excellent point that is well suited to this blog. We use CSS for the purpose of separating content and design. This is an excellent practice, so why not keep it up and separate content and behavior?

    Thanks for point out those libraries, I really need to get myself caught up on those techniques.

  19. For another take on autopopulating inputs and textareas:

    And on the :focus issue in IE6, you can use the whatever:hover .htc to make it work in that browser:

  20. Permalink to comment#

    Nice form! I think you might have forgotten to remove a td from a older table-designed version of this one though. does not validate because of this.

    You could also remove the break-tags after each input and put a clear on them to get the same effect, just to make your code a bit more structure- and design-seperated.

  21. @Dyre Hult: Yep, I there was a stray <td> in there, doh! I got that out of there and the form is validating just fine now. I also updated the downloadable example from the article. Thank you!

    Those <br /> tags were also not serving any purpose anymore, so they have been removed. That’s the beauty of posting examples like this, because they are subject to such healthy critique they naturally get better and better!

  22. Brad Smith
    Permalink to comment#

    May I also suggest using accesskey=”” and tabindex=””

  23. Permalink to comment#

    This is Handy as well. thanks once more..

  24. Permalink to comment#

    This was great! What a well written and helpful post; I love that you included all the explanations why things should be as you described. Thank you! **bookmarked**

  25. Permalink to comment#

    nice forms, many thx!!!

    will use :focus for first time, lol!

  26. Well done, well done.

  27. Thank you for this tip, because i want to change my own web-form with this idea to improve the usability.


  28. Permalink to comment#

    Excellent post, thank you.

  29. Permalink to comment#

    I am hoping someone might be able to help me with a a issue I have with the nice and simple contact form.
    I implemented it on my site and it was working great.
    Than it just stopped working and will not send me the email with the contact info actually I get no email at all.
    I tested the original form files and let everything unchanged except I put my email in the $EmailTo = “My email field”; in the contactengine.php file.
    I am mystified what has gone wrong.
    Could it be my server? or dose anyone have any suggestions please.

    Thanks, Toni

  30. excellent post… very helpful

  31. That wufoo form website was not too bad. I have used it for a website about Sokobanja I am developing at the moment :D

  32. The best website

  33. Permalink to comment#

    Thanks Chris for the usefull tips and insights,
    my users now have a better browsing experience :D.

  34. Permalink to comment#

    This Simple Contact form is really awesome!! But is there any way to avoid the yellow color background that we get in the text form telements like email name etc.,??

  35. Permalink to comment#

    That wufoo form website was not too bad. I have used it for a website about Sokobanja I am developing at the moment :D

  36. Permalink to comment#

    I am definitely going to implement this and spread the word! Thanks for the great article, this is exactly what I was looking for.

  37. Thank you for this useful information on CSS and forms.

  38. didi
    Permalink to comment#

    Thank you for your good advice!

  39. Permalink to comment#

    I really liked the web form factory. Thank you

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".