I am well aware that tables for layout are a BAD BAD idea and have stopped using them for such perverted things years ago with just one exception, forms. I started doing my forms in lists because IMO that makes sense but clients were always grumpy when web forms weren’t layed out in the traditional two column way and short of creating a mess of Divs I always ended up falling back to tables for forms. Not anymore! I’ve FINALLY found a nice way of doing forms so that the XHTML is simple, elegant and more importantly, semantically correct while still keeping to a nice two column layout.

OK, this CSS code comes from the VTIE Portal that I’m currently working on with the EVE Research group so that explains the names of some of the style classes. The basic thing is that each form on the site like the login form etc should be contained in a ‘box’, this box should have a title and then within it each bit of data needed from the user should be collected in a row consisting of a label and the form element and they should all be lined up in two columns. To make it easier for people to see what label matches what form element the “row” should also have an on-hover element to highlight each line as the mouse moves over it.

Below is the XHTML used:

<div id="page_container">
<h1>Sample CSS Form</h1>
<p>The form below is a sample CSS form for a blog entry on the subject. Please note that this form does not submit anywhere!</p>

<div class="vtie_form_container">
 <h1 class="vtie_form_container_title">Sample Form</h1>

 <form name="studentLoginForm" method="post" action="" class="vtie_form">
 <ul class="form_element_list">
  <li><label for="tb">A Text Box</label> <input type="text" name="tb" id="tb" /></li>
  <li>
   <label for="pwd">A Password Box</label>
   <input type="password" name="pwd" id="pwd" />
  </li>
  <li>
   <label for="rdo">Two radio Buttons</label>
   <span id="rdo">Yes <input type="radio" name="rdo" value="Yes" />
   or No <input type="radio" name="rdo" value="No" /></span>
  </li>
  <li>
   <label for="ck">A Check Box</label>
   I agree <input type="checkbox" name="ck" id="ck" value="agree" />
  </li>
  <li>
   <label for="ta">A Text Area</label>
   <textarea cols="20" rows="3" name="ta" id="ta"></textarea>
  </li>
  <li>
   <label for="sl">A Select List</label>
   <select name="sl" id="sl">
    <option value="-1"> -choose- </option>
    <option value="0">no</option>
    <option value="1">yes</option>
   </select>
  </li>
 </ul>
 <p class="button_bar">
  <input type="submit" value="Submit" class="submit" />
 </p>
 </form>
</div>

I think even Dave B would agree that that is nice simple XHTML that is makes semantic sense and is not over-loaded with divs (like my code used to be when I was new to this whole XHTML+CSS thing).

Now, this obviously doesn’t DO very much! Below is the CSS which both makes this look good and deals with the layout. You can see this form in action here BTW.

/* Generic style information from the start of the */
/* style sheet for the site as a whole, not strictly */
/* related to the example but here for completeness */
div{
  font-family: arial, sans-serif;
  font-size: 10pt;
  color: #000000;
}
p{
  text-align: justify;
}
h1, h2, h3, h4, h5, h6{
  margin: 0px;
  padding: 0px;
  padding-top: 20px;
  color: #000099;
  font-family: verdana, arial, sans-serif;
}
h1{
  font-size: 16pt;
}
ul{
  padding-left: 25px;
  list-style-image: url("li.png");
}

/* The style for the box containing the form, */
/* again not strictly related to the example */
/* but again included for completeness. */
div.vtie_form_container{
  margin-right: 20%;
  margin-left: 20%;
  margin-top: 40px;
  margin-bottom: 40px;
  padding: 0px;
  padding-bottom: 10px;
  border: 1px solid #000099;
  background-color: #f9f9ff;
}
h1.vtie_form_container_title{
  padding: 2px;
  background-color: white;
  background-image: url(headingBackground.png);
  text-align: center;
  margin-top: 0px;
  margin-bottom: 10px;
  text-transform: uppercase;
  font-size: 12pt;
  border-bottom: 1px solid #BFCAE2;
}

/* The code to make the form elements look nice and to */
/* ensure that buttons get the hand pointer (the code for */
/* the cursor is for Firefox only as IE does thing in a */
/* non-standards compliant way). */
/* You should also note that this CSS allowes buttons that */
/* submit the form to be marked to look different to */
/* regular buttons. */
form.vtie_form input{
  font-family: Verdana, Arial, sans-serif;
  font-size: 9pt;
  background-color: #D7E5F2;
  color: #000099;
  border: 1px solid #284279;
  margin: 2px;
}
form.vtie_form select{
  font-family: Verdana, Arial, sans-serif;
  font-size: 9pt;
  background-color: #D7E5F2;
  color: #000099;
  border: 1px solid #284279;
  margin: 2px;
}
form.vtie_form textarea{
  font-family: Verdana, Arial, sans-serif;
  font-size: 9pt;
  background-color: #D7E5F2;
  color: #000099;
  border: 1px solid #284279;
  margin: 2px;
}
div.vtie_form_container p.button_bar{
  margin-left: 25px;
}
form.vtie_form p.button_bar input{
  cursor: pointer;
}
form.vtie_form p.button_bar input:hover{
  color: black;
}
form.vtie_form p.button_bar input.submit{
  font-weight: bold;
}

/* FIANLLY, the code to do the whole two column */
/* thing and to highlight the row being hovered over. */
ul.form_element_list li{
  clear: both;
  padding: 2px;
}
ul.form_element_list li:hover{
  background-color: #FFF;
  border: 1px solid #BFCAE2;
  padding: 1px;
}
ul.form_element_list input, ul.form_element_list textarea, ul.form_element_list select{
  margin: 0px;
}
ul.form_element_list label{
  display: inline;
  float: left;
  width: 150px;
}

As you can see from the comments in the CSS I have included ALL the CSS that relates to the form including the code for the look and feel as well as just the code for the two column layout.