Styling fieldsets and legends with CSS

Back in 2002 I first learned about <fieldset> and <legend> tags while first discovering web standards and how to employ them. During the last 10 years while using the <legend> tag I’ve tried many different ways of using it while still keeping the <form> from being ugly.

Today I have a new trick that will give you further control over the <legend> tag.

Here’s a demo of the <legend> - before and after with styling. View Demo

Some people would just swap out the <legend>tag and instead use a heading tag, like an good old <h3>. Not me. I want the legend tag in there as it serves an important role - explaining what the deal with the fields in the <fieldset> are all about.

We should all be aware of the reasons <legend> elements turn out ugly. Explaining the issues isn’t within the scope of this post.

Let’s examine this simple form setup:

<form>
  <fieldset>
    <legend><span>Fill in the field</span></legend>
    <div>
      <label>The field</label>
      <input type="text">
    </div>
  </fieldset>
</form>

See how I added the <span> around the text in the <legend> tag? That’s the key to being able to manipulate the legend text better.

First thing you do is give your fieldset some CSS:

fieldset {
  position: relative;
  }

By making the position of our <fieldset> relative, we can safely position other elements inside the <fieldset> with absolute values. In this case we’re gonna position the span inside the legend element.

Could we just position the <legend>? No. Try it and see how differently each browser mangles your positioning. Why is this element so wacky? I don’t know. It was that very attempt that lead me to use the <span> element in the first place.

At any rate, once the fieldset CSS is in place it’s time to position the <span>:

legend span {
  position: absolute;
  top: 0;
  left: 0;
  }

A remaining issue is the legend itself, which will still interrupt the border of the <fieldset> element. So we need to get it out of the way.

legend {
  float: left;
  }

A quick float property gets the <legend> off the border. A simple way to take over the infamous <legend> element and force it to do your bidding. My example  places it inside the fieldset. You could just as easily place it outside the fieldset, to the left of the fieldset - anything you want!

Firefox users may have noticed that what we’re doing here looks like crap if you’re following along. That’s because Firefox has a legend positioning “bug” that requires a little CSS hack to get it in line with the others.

@-moz-document url-prefix() { 
  .a legend span {
    top: -30px !important;
    left: 0 !important;
    }
  }

Have fun making your own legends…


About Joseph R. B. Taylor

Joseph R. B. Taylor is a humble designer/developer who makes stuff for screens of all shapes and sizes. He is currently the lead UI/UX Architect at MScience, LLC, where he works to create simple experiences on top of large rich datasets for their customers and clients.