How To Make Good Looking Forms Using CSS


How To Make Good Looking Forms Using CSS

Last year, Jon wrote about the benefits of designing for the web using standards based CSS techniques (i.e. no tables). He did a great job at discussing the benefits so there’s no need for me to rehash them here. However, one line in particular caught my attention. He says

The main argument for still using tables today stems from bad habits, and complacency. What is often said is that using tables is easier, and that browsers don’t support it.

I couldn’t agree more. I know I was hesitant to make the switch because it seemed like tables were just so much easier. (I now know better.) And so, as penance for creating so many hideous table-based layouts, I offer up this technique for conquering the last hurdle in CSS development. Forms.

The Old Way

The problem with forms is that unless all of the fields are aligned correctly they look like crap. For example, this..

Password Again

is ugly. While this…

Password Again

looks better.

The first example doesn’t contain any formatting, while the second one uses a table with four rows and two columns to keep the fields aligned. This method works, but it isn’t ideal. Why?

  • Tables are a pain to create and edit.
  • They take use a lot of HTML which increases your page’s download time.
  • They aren’t semantically structured.
  • Tables are meant to display tabular data. NOT for layout.

Here’s the HTML used to render the table version.

 <table> <tr><td>Username</td><td><input type="text"/></td></tr> <tr><td>Password</td><td><input type="text"/></td></tr> <tr><td>Password Again</td><td><input type="text"/></td></tr> <tr><td>Email</td><td><input type="text"/></td></tr> <tr><td><input type="button" value="Create Account"/></td></tr> </table> 

That’s a lot of code to do just a little bit of work. And what if you want to change the spacing between cells? Align the submit button on the right? Add more rows or an extra column? It takes even more code.

There’s a better way.

The New Way

Instead of designing our HTML to do the layout, let’s use it to describe our form as it makes sense semantically and let the CSS worry about the formatting.

 <form> <p>Username <input type="text"/></p> <p>Password <input type="password"/></p> <p>Password Again<input type="password"/></p> <p>Email <input type="text"/></p> <p><input type="button" value="Create Account"></p> </form> 

That’s much cleaner and easier to read. Here’s what it looks like without any CSS applied to it.



Password again


Ugly, right? We can fix it.

First, we need add position:relative to the form tag so that we can absolutely position elements inside it. In our CSS file we write

form { position:relative; } 

Next, we align the textboxes by positioning them absolutely within the form and giving them a left value which pushes them out away from their labels.

form input { position:absolute; left:50px; } 

This doesn’t quite solve out problem. Since we specified the left value using a pixel width, that distance is constant no matter the font size. If the user is using a large text size in the browser, we could end up with something where the labels get bigger but the textboxes remain in the same position causing them to overlap.

Instead of using pixels, we can measure the left value using the em unit. One em is (usually) equivalent to the width of a capital letter M. What this means is that the em unit grows and shrinks proportionally to all font sizes. So how many ems should we set the left value to be? Well, that’s up to you. For this example I found that 11 worked quite nicely. (In practice, I’ve found that 80% of the number of letters in the biggest label is a good ballpark figure to start with. In my example “Password again” is the longest phrase and has 14 characters. 80% of 14 is about 11.)

Now, if the user picks a large text size, the entire form will scale nicely.


Here’s the final code for our example.

<form> <p>Username <input type="text"/></p> <p>Password <input type="password"/></p> <p>Password again <input type="password"/></p> <p>Email <input type="text"/></p> <p><input type="button" value="Create Account"></p> </form> form { position:relative; } form input { position:absolute; left:11em; } 

This technique is pretty rock-solid. It works in Safari, Firefox, and IE6. It’s also just a starting point. I encourage you to experiment with it, find what works best for you, and begin creating all of your forms with CSS. Your browser will thank you.

Comments are closed on this post