This blog has moved here: | FOLLOW ME ON TWITTER @woork
Sunday, June 8, 2008

Clean and pure CSS FORM design

Some readers of my blog hate html tables and often ask to me which is the better way to design FORMS with CSS, without using tables to place each form element in a table's cell.

How I said some time ago... tables are not evil. Sincerly, in some case I used pure CSS code to design forms but, in general, I prefer to use tables. It's simpler and faster than use only CSS property "to simulate" a table structure. In any case, for CSS lovers, this tutorial illustrates a proposal about how to design a pure CSS form without using html tables.

You can download the source code and use it in your web projects.

Download source code

Step 1: HTML Code
Create a new page index.html and copy and past this code into the tag <body>:

<div id="stylized" class="myform">
<form id="form" name="form" method="post" action="index.html">
<h1>Sign-up form</h1>
<p>This is the basic look of my form without table</p>

<span class="small">Add your name</span>
<input type="text" name="name" id="name" />

<span class="small">Add a valid address</span>
<input type="text" name="email" id="email" />

<span class="small">Min. size 6 chars</span>
<input type="text" name="password" id="password" />

<button type="submit">Sign-up</button>
<div class="spacer"></div>


How you can see from the code above, the structure of our CSS form is the following:

I used <label> for the name of each input element and <span> tag for the short description. All labels and input elements have float CSS property set to left;

Step 2: CSS Code
Copy and paste the following CSS code in the <head> tag of your page:

font-family:"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif;
p, h1, form, button{border:0; margin:0; padding:0;}
.spacer{clear:both; height:1px;}
/* ----------- My Form ----------- */
margin:0 auto;

/* ----------- stylized ----------- */
border:solid 2px #b7ddf2;
#stylized h1 {
#stylized p{
border-bottom:solid 1px #b7ddf2;
#stylized label{
#stylized .small{
#stylized input{
padding:4px 2px;
border:solid 1px #aacfe4;
margin:2px 0 20px 10px;
#stylized button{
background:#666666 url(img/button.png) no-repeat;

This is only a proposal for the form layout. You can reuse this code changing all properties how you prefer.

Download source code

Related Post
Table's anatomy: why tables are not so bad
Are you a CSS fanatic?
Improve form usability with auto messages

blog comments powered by Disqus
Ryan said...

Great write up, forms are always something I'm really not sure how to do. I've probably tried dozens of html and css layouts over the years and I think I settled on one similar to yours. I will have to try yours next, I like the text under the label better. :-)

Anonymous said...


Dude, what you use to do the images of the tutorials ?

Antonio said...

@anonymous: I use photoshop + Illustrator :)

Sure said...

all posts are great! nice work, you are social writer and genius :)

Nick said...

This is the best blogger template I never seen! :)))

Macca said...

Can you try to make demoes of your tutorials! I love them, but would like to a demo of the final product.

Mark van Eijk said...

I would clear the float's by using a linebreak (
). This is nicer because your (unstyled) form will look also good without any CSS. Now everything will be positioned horizontally.

Karim said...

You better add the "for" attribute to labels.
[label for="name"] where "name" is the id of your textfield

(P.S. Replace [ by < and ] by >)

Nikopolidis said...

Great tutorial ;) I often use tables to create form... I think is more simple for me (because I'm not a genius of CSS :P ), but I like this proceeding.

Mike said...

Your forms look great, but your class names and ids don't add any semantic value to the html.

class="small" and id="stylized" ??

Nice forms though. I also like the text under the label.

Perhaps instead of div stylized you might use a fieldset. Containing inputs is what a fieldset was designed for. Something to think about anyway.

Michiel van der Blonk said...

OK, that works. But it doesn't look nice when un-styled. Why do I care? Because by default it would be usable on any phone or any other device/software that doesn't support CSS.
So I changed all my forms to either have all fields wrapped in [div class="field"] or in [p]. And it gives some extra styling power as well to wrap the elements.
Read my own tableless-forms article here:

nice graphics though.

stfalx said...

Nice post. That's how i would have done it also.

Me said...

don' use the button tag use input,
choose semantic class-names(eg not "small", but "instruction", an instruction can be small, but you can't know for sure you will always make your instructions small (people with disabilities))

Webmonkey-in-Ireland said...

Nice approach, I've seen alot of forms using definition lists as well, floating the dd elements left, which has worked well for me in the past, as its not code heavy, and allows good control of spacing cross browser..

Anonymous said...

In my opinion H1 should be H2 :) H1 is semantically reserved for the header of the site (the main title od the site)

Xscratch said...

What's wrong with the <button> element?

Very neat and original way to post a tutorial, bravo!

Matthew Pollard said...

what about legends and fieldsets?

These are great for containing and labeling related elements in a form.

Ben said...

Nice tutorial!
Btw, it would be better if you use
for clearing or maybe a clearning without structural markup ":after method".

Ben said...

if you use < br / > [ line break ] *

Matthew 'Web Design' Adams said...

Cool article. Forms can be a pain.

ghs said...

could be better! I would use a "fieldset" and "legend" instance of "h1". "div"'s to separate the elements and much more... Should think about the accessibility too, not only the good look! here is an example how I use to organise my forms. it's a simple example with not so much elements, but will give some idea. And with a js could make a basic form validadion before send the form data

James said...

@Me is right, don't use "small". Even if you were just making the text small, it defeats the purpose of using CSS at all.

@webmonkey Using <dl>s to style a form is wrong. Why? Because it's marked up as a "definition" when it's really a form.

Anonymous said...

thank you

Kristy said...

Thanks for sharing your article. I like how you use labels. I have been using the definition list method for several years and have the same results.

Just a suggestion for better accessibility...rather than use just the label tag, do the label for="yourIDhere" tag to correspond with your input ID.

Also, I do like other people's suggestions about having a live demo. You should really consider doing that for anything you post.

Arnold said...

Nice form but 1 minor problem is that it doesn't work well with radio buttons.

< input type="radio" />

Medhat said...

Nice Style. But how to you handle form errors, syle-wise?


Anonymous said...

I don't really like the hard-coded width of the label and the descriptive text underneath. That's the problem I always run into with mimicking tables in CSS... it looks great as long as they 1) use the right font, 2) don't resize the text. Hard-coding the widths seems kludgey.

Thierry Koblentz said...

What about not using any class on the SPANs, and go with this:

#stylized label span{...}

instead of this:

#stylized .small{...}

Jennifer said...

I like to use a definition list (dl tag). The [label] tag goes inside the [dt] tag, and the [input] goes inside the [dd]. Because, semantically, that's what you're doing: label is a data term, defined by the input that the user is about to enter.

Plus, it gives you all sorts of lovely hooks to style.

Anonymous said...

The use of float:left for all input elements could also cause issues if you were planning on having multiple input elements on the same line.

For example, if you were separating parts of phone numbers or birthdates into 3 separate boxes with a divider between, the boxes would float left, but the dividers would all be right of those.

Tyssen said...

You should use 'for' attributes on your labels and IDs on the inputs so that the labels can be associated with the inputs.
And as someone mentioned, it'd probably be a good idea to use legends and fieldsets (although not always necessary for short forms).

kristarella said...

True, tables aren't evil... when tabulating data :P

I agree with Mark and Michiel a bit, perhaps a break or wrapping both floats in a p would work for styleless/semantic sake. Otherwise it's a great form.


Federico said...

Nice form and clear layout,
but I agree with mike:

" Perhaps instead of div stylized you might use a fieldset. Containing inputs is what a fieldset was designed for "

Rasheed said...

Really nice!!


Anonymous said...

Thanks, this is pretty useful.

fantata said...

Excellent form treatment, I've got a lot from playing with the styles you've got here. not rocket science, but i've never made a form look this good before! thanks.

Ji said...

Thanks ^^

Jeromche said...

Thank you for your article.

Nice work on the styling of the form. I like the little descriptions a lot.

Al said...

@Thierry Koblentz

I'd take it even a step further and remove the span tag altogether, replace it with something more standard and short, like em or strong. All the same styles would work just fine.

Overall, a good writeup!

John said...

Thanks, this was the best CSS form tutorial I have seen. I am a ColdFusion Guy, and usually use tables for forms.

One question how can I use a text area with this css?

I tried [textarea][/textarea] but I can't figure out the CSS:(

Any thoughts? I love to hear how you would go about this.

Thanks so much

John Barrett(

Gano said...


sabbour said...

[input type="textarea" class="mytextarea"]

.mytextarea {
/* stuff */

Jon said...

I agree, this looks awesome, but one size width is too narrow, which is fine to fix, easily. but problem is as someone else said, radio buttons don't work, and i need them majorly to work with this theme perhaps.

Tick boxes need to work too must.

Advisement please provide!



John said...

Awesome write up.
Inspired me to get rid of some html

balupton said...

Good post, although I am interested in how you handle your warnings and errors. Your other post here shows how you handle tips and things, which is a nice way of doing it. Thanks, and I really love your work and how you share your knowledge - well expertise.

Webtech Nepal said...

Thank you so much. I found the form which I am searching for.


The CSS Designer said...

Great tutorial just what i needed to create a CSS form

joomlapanel said...

Excellent Tutorial.. very usefull

BS Technology said...

it's good

N. Vitou said...


It is very helpful. I have been finding such CSS for weeks.


Anonymous said...

The form is not looking good in IE 8.. :(

Anonymous said...

Thanks for a great starting point!

Shielababes said...

you have a very nice blogger template, nice css form tutorial

promovare site said...

Really nice article!


nicole@younic said...

I added clear:left; on the labels css declaration. so the form won't mess up, when the small text goes over two lines.

Daniel Ulczyk said...

Excelente recurso Antonio.
Gracias por compartirlo, he escrito una entrada en mi blog comentándolo.


gradini said...

very useful article!


Rahim said...

Thats not a bad article, however why do you not put the advice into practise and producr a demo of the form?


Good work. Thanks.

Anonymous said...

how would u split the form into 2 or 3 pages if it gets too long ?

Rick Winkler said...

I always have trouble making my forms look nice. This helped quite a bit on my contact forms.

  • Twitter Follow woork on Twitter
  • RSS Feed Subscribe to stay up to date
  • Podcast Coming soon...
  • 0 delicious lovers save
Share your links. Do you want to suggest any interesting link about web design or tech news? Submit your link.
Submit a News