The Wayback Machine - https://web.archive.org/web/20101127030836/http://staff.washington.edu:80/fmf/2009/02/06/grouping-with-fieldset/
  • CSS February 6, 2009

    If you have a form that has items which should be grouped together, using <fieldset> is a good way to go. It’s essentially a <div> with a predefined border, but what makes it work well is the ability to label the box with a legend. If you want to change its look, however, you must be very careful to test it against multiple browsers.

    Here’s a simple example, using all the browser defaults:

    Fieldset Example

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque quam. Aenean id lacus at dui aliquet malesuada. Vivamus pretium, justo eget blandit tempus, sem nunc luctus ipsum, at venenatis enim.

    The HTML for this is:

    <fieldset>
        <legend>Fieldset Example</legend>
        Lorem ipsum (etc.)
    </fieldset>

    Safari, Firefox, and Opera render this in a very similar way:

    Safari fieldset, defaults

    Safari 3.x

    Firefox fieldset, defaults

    Firefox 3.x

    Opera fieldset, defaults

    Opera 9.x

    The fieldset acts as a block (div) using border-style: groove and border-width: 2px, but the browsers use different colors for the border itself (Safari #c0c0c0, Firefox #f0f0f0, Opera #000000). If you look closely you can see that they each have a slightly different implementation of the groove border style.

    IE 7 fieldset, defaults

    IE 7

    Internet Explorer renders the fieldset differently (shown to the right). The rounded rectangle is visually quite appealing, and IE also uses a different legend color. As far as I can tell, you can’t define borders with rounded corners in IE (even in IE 8), so fieldset is a special case. The border is equivalent to border: 1px solid #d0d0bf and a border-radius of about 5px. If you use Javascript to look at the fieldset’s border style, you’ll see it’s set to border: 2px groove black, and if you change any of the components, the rounded border goes away and you will be overriding what’s set on the object (e.g. if you change the width to 3px you’ll end up with a 3 pixel-wide black groove border).

    IE 8 fieldset, defaults

    IE 8

    IE 8 is still in beta at this time so I won’t cover it other than to show how it currently renders the same fieldset (at the right). The legend is a bit lower and to the left; if you get rid of the rounded borders you’ll find the legend is completely on the left side of the top border. As with IE 7, it seems that there is no support for rounded borders.

    It’s possible to make Firefox have the same look as IE by using rounded borders:

    border: 1px solid #d0d0bf;
    -moz-border-radius: 5px;

    If you’re using either the developer preview of Safari 4.x or have downloaded the Webkit nightly build, you can use -webkit-border-radius to set rounded border corners. Update 9-Mar-2010: I fixed the errors so border-radius is referenced now instead of the incorrect border-width. Also, Opera 10.50 and up now support border radius with border-radius.

    All the browsers let you set the color of the legend text. They will also make the legend follow the content of the fieldset if you set left padding.

    IE w/narrow window

    IE w/narrow window

    If the text of the legend is longer than one line, Safari and Opera will let that text wrap to multiple lines. Firefox will set the minimum width of the fieldset so the legend won’t wrap to multiple lines. IE will let the fieldset itself get smaller and let the border shrink, but it will keep the legend on one line so you will get a horizontal scroll bar (example at right).

    Changing the right padding will cause similar behavior; Safari and Opera will let the legend wrap to multiple lines, Firefox will make sure the content is at least as wide as the legend, and IE will let the content get narrow but will not let the legend wrap to multiple lines.

    Setting padding on the legend itself gives predictable results, so setting padding-top: 1em would move the text down by about 0.5em (centering the whole legend, including padding, on the border). Left padding will create a gap between the border’s end and the left of the legend’s text, and similarly right padding will create a gap on the legend’s right.

    While the non-IE browsers seem to implement fieldset as a special case of a div that has a border and knows how to display the legend, IE acts as if the top part of the fieldset were a nested div, with the border around a sub-div. If you set top padding, IE will push the whole fieldset down and add space above the whole thing, while other browsers will add space between the top border and the fieldset’s text. Padding on the left, right, and bottom adds space between the border and the text for all browsers, including IE.

    Since setting the background of a block will also change the color of the padding, setting the fieldset’s background in IE will cause the color bleed outside the border. IE’s borders will revert to 2px groove black. Examples are below, with the same code for IE and Safari (Firefox and Opera are similar to Safari):

    IE 7 w/background

    IE 7 w/background

    Safari w/background

    Safari w/background

    While the non-IE browsers have implementations which seem to make more sense, neither result looks particularly desirable to me. IE also has no default padding for the inner box which looks fine with the rounded borders, but puts the text too close when the borders are overridden (but it’s easy to explicitly add padding). You can also change the background color of the legend, which looks as expected except for IE, which has a hard-to-see gap between the color and the border, as shown below. If you override IE’s rounded corner border, the gap is larger and on both sides of the legend. The gap cannot be closed with negative margins.

    IE w/legend bg

    IE w/legend bg

    IE w/border, legend bg

    IE w/border, legend bg

    Safari will let you change the position of the legend using text-align, such as:

    legend {
        text-align: center;
    }
    Safari w/legend float

    Safari w/legend float

    This doesn’t work in other browsers, but the fact that it does work in Safari seems a little odd. Safari acts as if the legend were a block element with the maximum width set to the text’s width, but for that to be the case the browser would need to dynamically set that width when the text changes size or content (something you wouldn’t be able to do using just CSS). Another explanation for the legend’s behavior would be to use a left float, but, it doesn’t seem to actually be implemented that way; if you explicitly set the legend to float: left, it will end up being in the flow of the fieldset content (as shown on the right). Either way, you wouldn’t expect that setting text-align on a block element would affect its position in its container.

    You can actually set the legend to have float: right to get IE to put the legend on the right side of the box (which actually kind of makes sense, if you assume the inner, bordered block clears floats), but that has bad side-effects for Safari and Opera, which both will put the legend into the fieldset text. Firefox seems to internally treat the legend as an inline element, thus setting a float has no effect. Setting the legend to use relative positioning and trying to move it has no effect in Firefox (even if you explicitly set the legend to display: block). Safari acts as you would expect in this case and lets you reposition the legend (even though the gap in the fieldset border will not move), but just the act of setting the legend to position: relative will make Opera move the legend into the fieldset (which will then have a continuous border), but it will be on its own line, unlike when you float the legend.

    IE w/legend relative

    IE w/legend relative

    You’d probably (hopefully?) never make use of it, but IE has very odd behavior when you try to position its legend. Even though the legend seems to be treated as an inline element, setting just position: relative on the legend will make the fieldset’s border reposition itself to be at the bottom of the legend, and the border gap will have shifted a bit to the right.

    IE w/legend left: -1.5em

    IE w/legend left: -1.5em

    If you use relative positioning to move IE’s legend (with top, left, etc.) the top border will stay in the same position relative to the legend. Moving it down down will make the border move down, but when the border seems to get to about the same height as one line of text it will completely disappear. If you move the legend far enough to the left, the gap will wrap around to the left border!

    Posted by fmf @ 5:45pm

  • 7 Responses

    WP_Modern_Notepad
    • derek curtice Says:

      I’m having a heck of a time making sense of the fieldset variations for css definitions neccessary for safari, mozilla, opera, etc. the right column of my index page contains the challenge. Can you help?

    • fmf Says:

      What in particular is causing you grief? In general, fieldsets act a lot like divs with a border, so if you can get those working correctly, then the fieldsets should be mostly right. At this time you generally need to be satisfied with the defaults for the legend.

      Is there a particular browser that looks correct?

    • derek curtice Says:

      Yes, IE. In fact, IE6 is giving me a particularly difficult time. The site renders well in Safari, FF/Mozz, but in IE8 and Opera I’ve lost the radius completely. When left to the default in IE–the rendering is perfect. However, I opted for Safari/FF rendering (personal choice) even though 65% of my traffic, or better, comes from IE. Recap–IE6 is rendering poorly, and cross compatible radius on fieldset remains a challenge. Thoughts?

    • fmf Says:

      Do you happen to be setting any attributes of the border, such as color or width? If so, then IE will no longer use the default rounded-corner border.

      One option is to use conditional comments (<!–[if IE]> <![endif]–>) to hide the border color/width attributes from IE. If future versions of IE start to support border-radius, then you can change the comment to test the version. That would leave IE with the default appearance.

      Opera doesn’t support border-radius at all (IE only supports it as a special case for the default fieldset appearance)

    • derek curtice Says:

      I see. I have little experience with css–in fact, with any of this. I appreciate your help. So, where would I insert ( )?

    • fmf Says:

      You would put whatever CSS attributes you don’t want to be used for IE into the conditionals. Note the parentheses aren’t part of the actual comment.

      If you do a web search for “IE conditional comments” you should find several examples.

    • derek curtice Says:

      I see. Thank you kindly.

    Leave a Comment