Chuck Conway

In The craft

Semantic CSS Form Layout

December 12, 2004 · 3 minute read

Form layout is tricky. Even using tables, it’s tricky. In my current project, I refused to use tables for laying out my form components (input, textarea & select). There had to be a way to do it. CSS has been around for a couple years. New things are always being devised.

After a quick search of Google, I came across a couple I thought might work. In particular one written by Mark Newhouse called Practical CSS Layout Tips, Tricks, & Techniques. The problem is, it’s not semantic and it’s complex. There has to be away to simplify it and make it more meaningful.

The example files can be found here.

Here is the code for Mark’s CSS Form layout:

HTML:

<div style="width: 350px; background-color: #cc9;
border: 1px dotted #333; padding: 5px;
margin: 0px auto" ;="">
<form>
<div class="row">
      <span class="label">Name:</span><span class="formw"><input type="text" size="25"></span>
    </div>
<div class="row">
      <span class="label">Age:</span><span class="formw"><input type="text" size="25"></span>
    </div>
<div class="row">
      <span class="label">Shoe size:</span><span class="formw"><input type="text" size="25"></span>
    </div>
<div class="row">
      <span class="label">Comments:</span><span class="formw">
        <textarea cols="25" rows="8">        Go ahead - write something…
        </textarea>
      </span>
    </div>
<div class="spacer">
  &nbsp;
  </div>
</form>
</div>

CSS:

div.row {
          clear: both;
          padding-top: 5px;
          }

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

        input, textarea {
          float: right;
          width: 235px;
          text-align: left;
          } 

          div.spacer {
  clear: both;
  }

Div and span tags mean nothing to me. There is no significance in their use. So why use them? Looking at the span tags I decided to try label tags. I didn’t see any functional difference between the two except for one thing: label tags have meaning – span tags don’t.

I decided to apply the CSS directly to the input and the newly inserted label tag. Viola! It worked.

So instead of having this:

<div class="row">
    <label>Shoe size:</label><input class="formw" type="text" size="25">
</div>

We have this:

<li><label>Name:</label><input id="txtName" type="text"></li>

It much cleaner, less code, yet it accomplishes the same thing.

Still I was bothered with having to encapsulate my input and label tags into a div tag.

There must be a more semantic approach. What if I put it in an unordered list?

It worked!

I went from this:

<div class="row">
    <label>Shoe size:</label><input class="formw" type="text" size="25">
</div>

To this:

<li><label>Name:</label><input id="txtName" type="text"></li>

Much cleaner, and it’s simple and semantic.

Here is all the code:

CSS:

div#form
{
    position:relative;
    z-index:1;
    width:325px;
}

div#form ul li,  div#form ul li ul li
{
    clear: both;
    padding-top: 5px;
    display:block;
    list-style:none;
}

div#form ul li ul li
{
    padding:0;
}

input, textarea
{
    margin:0;
    padding:0;
}

div#form ul li ul li label
{
    float:left;
    border:0;
    width: 50px;
    text-align:left;
}

div#form ul li ul li input
{
    float:left;
    border:0;
    width: 20px;
    margin-left:90px;

}

div#form input, div#form textarea
{
    float:right;
    width: 150px;
    text-align: left;
} 

div.spacer
{
    clear: both;
}

label
{
    float: left;
    width: 120px;
    font-size:small;
    text-align:right;
}

select
{
    float:left;
    margin:0;
    padding:0;
    margin-left:11px;
}

HTML:

<div id="form">
    <ul>
        <li><label><strong>Name:</strong></label><input id="txtName" type="text"></li>
        <li><label>Age:</label><input id="txtAge" type="text"></li>
        <li><label>Address:</label><textarea id="txtAddress"></textarea></li>
        <li>
            <label>County:</label>
            <select><option value="1">Shasta</option><option value="2">Butte</option><option value="3">Tehema</option><option value="4">Glenn</option></select>
        </li>
        <li><label>E-mail:</label><input id="txtEmail" type="text"></li>
        <li>
            <label>Type of Coverage:</label>
            <ul>
                <li><input id="chkHealth" type="checkbox"><label for="chkHealth">Health</label></li>
                <li><input id="chkHealth" type="checkbox"><label for="chkHealth">Dentistry</label></li>
                <li><input id="chkHealth" type="checkbox"><label for="chkHealth">Life</label></li>
                <li><input id="chkHealth" type="checkbox"><label for="chkHealth">Other</label></li>
            </ul>
        </li>
        <li><label><strong>Contact Name:</strong></label><input id="Textbox27" type="text"></li>
        <li><label><strong>Phone number:</strong></label><input id="Textbox28" type="text"></li>
        <li><label>Fax Number:</label><input id="Textbox25" type="text"></li>
        <li><label><strong>E-mail:</strong></label><input id="Textbox30" type="text"></li>
        <li><label></label> <input style="width:auto;text-align:center;" type="submit" value="Submit"></li>
    </ul>
    <div class="spacer"> </div>
</div>

Note: Drop down lists don’t line up in Opera. They are about 5 pixels to the left of the other textboxes. I am currently searching for a solution.