Using Definition Lists (dl tag) for forms

03 Aug 2006

I’ve been mostly table-free for a while now in my layouts but I’ve had a particular bit of trouble with forms. Getting the labels and inputs aligned has been a huge pain because it seems like every form has a tons of exceptions to it and doing anything to the input tag means you need to go through and exclude all your radio buttons from it. I don’t know about you but most of my clients look quizzically at radio buttons that are 150px wide.

Enter Definition Lists

 Garbage Burrito has an awesome post about the html tags we’ve all forgotten about - definition lists among them. Thabenksta reintroduced me to this wonderful tag and it’s saved my ass just today.

The thing about definition lists is that they contain sets of pairs. The problem with uls and divs has been the the only way to put an input into it and making that input behave differently than a label is to give s special class to the input or to the label.

Here’s some code that I’ve had to use to make a ul-based form with aligned inputs and labels (labels on the left):

    <style>
    input.radio {
      width: auto;
    }
    label {
      cursor: pointer;
    }
    form.aligned label, form.aligned .label {
      margin: 2px 0px;
      border-top: 1px solid #EEE;
      display: block;
      clear: left;
      float: left;
      width: 90px;
      font-size: 1em;
      font-weight: bold;
    }
    form.aligned input, form.aligned .input, form.aligned textarea {
      margin: 2px 0px;
      display: block;
      clear: none;
      float: left;
    }
    </style>

That’s a mouthful. And, even worse, its just not pretty.

Here’s an example of an aligned form using a dl tag. I put labels in the dt and inputs (or whatever, it’s encapsulated!) in the dd.

    <style>
    dt {
      min-height: 1em; /* to make sure it stays aligned if it's empty */
      float: left;
      clear: left;
    }
    dd {
      min-height: 1em;
      margin-left: 100px;
    }
    </style>

That’s it. Then it’s not only pretty but also much more semantic to code up my forms:

    <dl>
      <dt><label for="name"></dt>
      <dd><input id="name" name="name" /></dd>
      <dt><label for="email"></dt>
      <dd><input id="email" name="email" /></dd>
    </dl>

Onward and upward.

  • Anonymous said: I tried this too, but got alignements issues when the dt tag ends up being higher than the dl tag. I fixed this by setting max-height on dt rather than min-height (and overflow:hidden); and set it to the same (or lower) value than max-height on dd. If there's another way, I'd glad to hear it (using a clear:left on br inside dl did work, but using br inside dl isn't valid...)

Please if you found this post helpful or have questions.