tags:

views:

515

answers:

4

Hello guys,

I personally like the <fieldset> tag because of how it draws a box and puts the <legend> at the top of it, over the border. Like this.

alt text

However, it was made to organize forms, and using it for general design is no better than using tables for general design. So, my question is... how can I achieve the same result using another tag? The border has to be erased under the <legend> (or whatever other tag will be used), and since there could be a "complex" body background image, I can't afford to just set the background-color of the legend to match the one of the element under.

I'd like it to work without Javascript, but CSS3 and XML-based formats (such as SVG or XHTML) are fine.

A: 

I believe you already know the answer.

You have 2 options, provide your own border (that's a lot of unnecessary work) or position an element with occludes the border (the problem with that is that you can only have a solid background color, but maybe that's fine).

To my knowledge there's not anything you can do to make this workout nicely in every browser out there. I like your style though, it's the right approach but probably not a problem you'll be able to solve in a satisfying manner.

My general opinion on these topics is that you should not try and do things with the web that requires A) excessive effort or B) a markup solution which is not entirely obvious to begin with. The web has limitations and you would do well to ad-her to them rather than trying to work around those limitations.

So I'm forced to ask, what's the problem with <legend/>?

John Leidegren
I guess the point is, that it is not semantically correct to use `fieldset` for **only** display purposes, especially if no form fields are involved.
Felix Kling
The problem is that it's semantically wrong. However, looking _only_ at the render, it's perfect. Kind of like a `<table>` design: it works flawlessly on every browser, but tables aren't layout tools. I was just wondering if there was some magical tag or CSS property I wasn't aware of.
zneak
I think that worrying about semantic purity is a practice that should have sane limits. It's not like God Himself decreed the use (or even the name!) of the "fieldset" tag. The fact that browsers implement a particular (and somewhat odd) layout effect that's otherwise unobtainable is a historical accident.
Pointy
+2  A: 

HTML:

<div class="fieldset">
 <h1><span>Title</span></h1>
 <p>Content</p>
</div>

CSS:

.fieldset { border: 1px solid #ddd; margin-top: 1em; width: 500px; }
 .fieldset h1 { font-size: 12px; text-align: center; }
  .fieldset h1 span { display: inline; border: 1px solid #ddd; background: #fff; padding: 5px 10px; position: relative; top: -1.3em; }

Demo: http://jsbin.com/ulema

Mathias Bynens
+1 I like it :)
Felix Kling
And what if I want it to look more like the example I've posted?
zneak
Oh, I’ve only just noticed OP posted this: “since there could be a ‘complex’ body background image, I can't afford to just set the background-color of the legend to match the one of the element under.” That’s what I’m doing in this example. I don’t see how it could work otherwise…
Mathias Bynens
@zneak: You mean like this? http://jsbin.com/ulema/2
Mathias Bynens
As you noted, I'm looking for a permanent replacement to the `<fieldset>` + `<legend>` combo, not for code that would fit one precise situation. I'm very well aware there may be no real solution to this, but I thought I was better off to ask anyways. Still, what you've done is cool, and could come in handy at some point in the future. It's just not exactly what I'm looking for.
zneak
So the only problem is the background of the fake `legend`? I’m sorry, but I’m afraid there’s nothing I can do about that. :(
Mathias Bynens
+2  A: 

However, it was made to organize forms, and using it for general design is no better than using tables for general design

This is mistaken. The main problem with using tables for layout is that almost no layouts map to tabular data. The second problem is that none of those that don't map to tabular data are tabular data, and some of those that do aren't. That is, the semantics of the markup wouldn't match those of the page. In addition, pragmatically, tables' layout mechanism usually makes custom styling and text-only browsing painful or impossible.

Now, fieldset clearly has the intent of grouping form fields. And choosing an element for its appearance is almost always a sign it's a bad choice. However, for this specific example I would argue that a fieldset+legend containing a list has almost no disadvantages (in fact, the only one I can think of is a scaper which naively interprets fieldset as signalling a form and then wasting the user's time enumerating its contents differently; but I know of nothing which actually does this). The main reason for this is that the form element serves the functional and semantic purpose of containing inputs, while fieldset has possessed since the early days had special, non-reproducable visual effects. In addition, if the visual elements in the fieldset are in any way functional, semantically the fieldset does again contain a set of interactive widgets, which was the original point.

My advice is to use it if you want to. I wouldn't, but not because of semantic considerations: I prefer not to rely on special effects, and eschew form over function in general.

Anyway, here's something to chew on:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
<html><head><title>test</title><style type="text/css">

.fake_fieldset {
    border: 2px groove ButtonFace;
    border-top-width: 0;
    margin-left: 2px;
    margin-right: 2px;
    padding: .35em .625em .75em;
    margin-top: 1em;
    position: relative;
}

.fake_legend {
    margin-top: -1em;
}

.fake_legend.test1::before {
    position: absolute;
    top: 0;
    left: -1px;
    border-top: 2px groove ButtonFace;
    content: " ";
    width: 0.5em;
}

.fake_legend.test1::after {
    position: absolute;
    top: 0;
    right: -1px;
    border-top: 2px groove ButtonFace;
    content: " ";
    width: 80%;
}


.fake_fieldset.test2 {
    padding: 0;
    padding-top: 1px; /* no collapsed margin */
}

.fake_fieldset.test2 .fake_fieldset.container {
    margin: 0;
    border: 0;
}

.fake_legend.test2 {
    display: table;
    width: 100%;
}

.fake_legend.test2 span {
    display: table-cell;
}

.fake_legend.test2 span:first-child {
    width: 0.5em;
}
.fake_legend.test2 span:first-child + span {
    width: 0; /* cells stretch */
}
.fake_legend.test2 span:first-child,
.fake_legend.test2 span:last-child {
    /* the rest of this code is left as an exercise for the reader */
}


</style></head><body>

<fieldset><legend>foo</legend>bar</fieldset>

<div class="fake_fieldset test1"><div class="fake_legend test1">foo</div>bar</div>

<div class="fake_fieldset test2"><div class="fake_legend test2"><span></span><span>foo</span><span></span></div><div class="fake_fieldset container">bar</div></div>

</body></html>
Anonymous
Your `test1` is very close to what I was looking for; however the legend cell somehow has a fixed width under Firefox and yesterday's nightly Webkit build. So I can't really use that, but your comments about the usage of `<fieldset>` gave me hope again, so I might just continue using them since they do contain interactive widgets in my case.
zneak
+2  A: 

No, it isn't really possible. Even browser makers themselves are struggling with that.

Of course, I couldn't resist having a go at it anyway. And I spent so much time on that, that Anonymous came up with a "solution" rather similar to mine in the mean time (his test1). But mine doesn't need the fixed width "legend".

This code is evidently a bit of a hack, though, and I don't know how well it'll fare in complex sites. I also agree with Anonymous that using a fieldset for grouping isn't nearly as bad as using tables for layout. Fieldsets were designed for grouping elements, though in HTML they're really only supposed to be used for grouping form controls.

<!doctype html>
<style>
.fieldset {
    border: 2px groove threedface;
    border-top: none;
    padding: 0.5em;
    margin: 1em 2px;
}
.fieldset > h1 {
    font: 1em normal;
    margin: -1em -0.5em 0;
}   
.fieldset > h1 > span {
    float: left;
}
    .fieldset > h1:before {
        border-top: 2px groove threedface;
        content: ' ';
        float: left;
        margin: 0.5em 2px 0 -1px;
        width: 0.75em;
    }
    .fieldset > h1:after {
        border-top: 2px groove threedface;
        content: ' ';
        display: block;
        height: 1.5em;
        left: 2px;
        margin: 0 1px 0 0;
        overflow: hidden;
        position: relative;
        top: 0.5em;
    }
</style>

<fieldset><legend>Legend</legend> Fieldset</fieldset>

<div class="fieldset"><h1><span>Legend</span></h1> Fieldset</div>

As a side note, you might also want to have a look at the HTML5 figure and figcaption elements. Those seem to be the best elements to use in your example.

That's only for the semantic part of the issue, though, since I don't think those elements are rendered the same as a fieldset/legend. Not to mention that current browsers probably don't support these elements yet to begin with.

mercator
No, `<figure>` wouldn't do it in my case, and now that I think of it, `<fieldset>` is actually all right. However, your solution apparently works very well (although I'd change the `<h1>` tag to something else since that wouldn't quite match my heading model), so thank you very much.
zneak