Fieldset & Legend Behave!

10 February 2010 mortendk

The fieldset-legend tag is a legendary (rimshot) problem for webdesigners.
Its just that its a major pain in the ass to work with - the good thing about it is that it at least make sence for the usability nerds. But for a designer its a royale pain in the ass to look as you want it -unless you think that the outta the box fieldset-legend combination looks awesome.

<fieldset>
  <legend>foo</legend>
  <label>Label</label>
  <input type="text" name="foo" value="">
</fieldset>

Sure you can change the color of the border of the <fieldse>t. and to a degree set the position. of the placement of the <legend>. But its a pain, and offcourse safari/chrone (khtml), firefox & IE (7 or & 8) all behave differently

What the problem is with the fieldset-legent here is that they dont behave like normal display block/inline elements :( so all the normal tricks to whip it into shape is kinda useless. The <legend> tag has the ability to totally ignore whatever you want it to do.

Theres a dirty solution to the problem:

Give up on the legend tag and do a div-h3 combination instead,but be ready to hear the accessibility people go up in the red field and begin to screaming about the markup, and blind people n stuff ... oooh and all that about webstanrds n stuff...
But then you don't have to deal with the pesky <legend> and scream in anger whenever you want it to look any different than how it comes outta the box

So do this

<div>
  <h3>foo</h3>
  <label>Label</label>
  <input type="text" name="foo" value="">
</div>

instead of:

<fieldset>
  <legend>foo</legend>
  <label>Label</label>
  <input type="text" name="foo" value="">
</fieldset>

So basically its a fight between accessibility and design thats a majorepicfail(tm) We dont wanna end up with shitty markup now will we?

Span to the rescue

After digging around abit its pretty clear that legend isnt man (or woman sorry ladies) enough to hold his own pants. <legend> simply wont accept a width value. It needs to get a little helper, theres no way around it. Here comes the inner span tag: <legend><span>blablablabla</span></legend> and now we can begin to work with it.
If adding a <span> is the tradeoff to get <legend> to behave, well then thats a price im willing to pay.

<fieldset>
  <legend><span>Legend link</span></legend>
  <label>Label</label>
  <input type="text" name="foo" value="">
</fieldset>

Add this css and theres order in the chaos:

<style type="text/css" media="screen">
  legend{margin:0; display:block; padding:0;}
  fieldset{margin:30px 0 0 0; padding:30px 0 10px 0; border:none; width:100%; background:#Fdd;display:block; position: relative; top:0px; left:0;}
    /the margin top is set to push down the "real" content of the form
    position relative & block definition is nessesary to battle the evil ness of mulbible browsers...
    */
  legend span, legend a{
      height:20px;
      background:#FFD;
      color:#d0d;
      display:block;
      width:90%;
      position: absolute;
      left:0;
      top:0px\9;/
ie7 & ie8 8 ugly hack thanx to FF FF goes nuts of theres a top:0; so to correct that we have to add a selector for ie8*/
      padding:0 0 0 10px;
      border-bottom: 1px solid #f0f;
     }
     label{margin:0 0 0 20px;}
</style>

The trick here is to use margin top value to "push down" the <fieldset>, so it kinda behaves like a normal block element - instead of having the legend tag floating in the middle of everything.

Then were gonna to a bit of magick with the <span> to get the <legend> to behave.
set it to absolute position "position: absolute"
add a top value if its internet xplorer (7 or 8) use the "\9" trick "top:0px\9;"
Its kinda ugly i know, firefox is beeing an ass, safari didnt cared so this was the easy solution that made all browsers happy.

Now we have a <fieldset><legend> combination we can change as we usually does.

Drupal hell

As a drupal loving frontend geek the next step is to get the techneque into the way that drupal does fieldset.
You might now all fieldset in drupal has a tendency to have that folded effect (yay jQuery sweetness) But to be able to work with the <legend> here you need to be a tiny bit more persistent. Cause the mighty drupal adds all kinds off goody stuff, you might not wanna have...

Lets start with adding a span so we can control the legend tag. If you use the mighty mothership, this sexy feature is off course already included (yay mothership) else add this snippet to you template.php file, and offcourse change the THEMENAME to the name of the theme

<?php
/<em>adds a span tag inside the legend so we can control the legend width</em>/
function
THEMENAME_fieldset($element) {

  if (!empty(
$element['#collapsible'])) {
   
drupal_add_js('misc/collapse.js');

    if (!isset(
$element['#attributes']['class'])) {
     
$element['#attributes']['class'] = '';
    }

   
$element['#attributes']['class'] .= ' collapsible';
    if (!empty(
$element['#collapsed'])) {
     
$element['#attributes']['class'] .= ' collapsed';
    }
  }

  return
'<fieldset'. drupal_attributes($element['#attributes']) .'>'. ($element['#title'] ? '<legend><span>'. $element['#title'] .'</span></legend>' : '') . (isset($element['#description']) && $element['#description'] ? '<div class="description">'. $element['#description'] .'</div>' : '') . (!empty($element['#children']) ? $element['#children'] : '') . (isset($element['#value']) ? $element['#value'] : '') ."</fieldset>\n";
}
?>

The only thing thats changed from the normal Drupal 6 theme_fieldset is that it haves a span tag inside the legend.
Then add some css that takes care of some of all the magick that drupal gives ya (hide & show states), so it will work perfect with the drupalsite, and you dont have to code like a mofo to find all the wholes

<style type="text/css" media="screen">
/
fieldsets & legend hell
----------------------------
/
legend{margin:0;  display:block; padding:0;}
fieldset{border: none;}
fieldset div{margin-left:10px;}
fieldset fieldset{padding-left:1em; background:#eee;}
html.js fieldset.collapsible,
fieldset
{
  margin:0;
  padding:20px 0 10px 0px;
  /* width:100%; width:95%; ie7 screws with the with in/
  background:#eee;display:block; position: relative; top:0px; left:0;
}

html.js fieldset.collapsible legend span{width:98%;}
html.js fieldset.collapsible legend a span,
html.js fieldset.collapsible legend span
{
  height:20px;
  color:#fff;
  display:block;
  position: absolute;
  left:0;
  top:0px\9;/ie7 & ie8 8 ugly hack thanx to FF FF goes nuts of theres a top:0; so to correct that we have to add a selector for ie8/
  font-weight:normal; text-transform: uppercase;
  font-size:10px; line-height:20px;
  background-color:#999;
}

html.js fieldset.collapsible legend a span{background:#999 url(../icons/navigation-090-frame.png) no-repeat left 3px; padding:0 0 0 20px;}
html.js fieldset.collapsed legend a span{display:block; background:#aaa url(../icons/navigation-270.png) no-repeat left 3px; cursor: pointer; padding:0 0 0 20px;}
html.js fieldset.collapsed legend span{padding:0 0 0 10px;}
html.js fieldset.collapsed{padding:5px 0; height:0; margin:0 0 20px 0;}
html.js fieldset.collapsed legend a span:hover,
html.js fieldset.collapsible legend a span:hover
{
  color:#999;
  background-color:#666;
}

html.js fieldset.collapsible .fieldset-wrapper {overflow: hidden;}
html.js input.form-autocomplete{background-position: 100% 7px;}
html.js input.throbbing{background-position:100% -18px;}

.vertical-tabs,
.vertical-tabs-panes fieldset{background:#fff;}
</style>

The clever clever drupal themer will see that i added some hotnes (icons for the state of the legend) + as an added bonus theres a small element if you uses the vertical tabs module. Then this css wont screw it up to much ;)

resources

So there you have it - The eternal struggle against legend tags is finally over. and even drupal behaved - Hope it helps someone out there. oooh and please lemme know if there some prettier way to whip legend into submission.

more about this bug
* https://bugzilla.mozilla.org/show_bug.cgi?id=269908
* https://bugzilla.mozilla.org/show_bug.cgi?id=269908

AttachmentSize
legend.html2.02 KB

Pingback

[...] før tid og alt det der – Så jeg holdt mig i skindet og skrev i stedet for en post om at håndtere fieldset og legend tags (hvis du ikke er html geek fatter du det ikke, så bare [...]

You rock mate! I've been

You rock mate! I've been looking for a way to do this in Drupal for ages!

Thanks heaps for figuring this out and writing this post!

Matt 24 March, 2010 - 13:16

Great Post

google is the best.

google 19 April, 2010 - 13:03

Wonderful

Great post mortendk, very comprehensive. I'll certainly give it a shot. Actually I was looking for and I found it really workable. Thanks!

best web hosting 19 April, 2010 - 13:09

To be social is very positive

To be social is very positive aspect in this age of materialism. Life is moving very fast and embedded with full luxuries. In this fast life best web hosting is too facilitating for your comfort and minimizing all tensions.

Daniel 19 April, 2010 - 13:11

AWESOMENESS!!!

Just as I was about to delete Firefox...

Fran 20 April, 2010 - 22:01

Thanks for sharing nice and

Thanks for sharing nice and informative post scripts with cool comments.Really love your work.Keep up the good work coming.Wish you all the best with your site web hosting.

Anonymous 19 May, 2010 - 07:45

nice styles

your examples are very usefull for me, thanks a lot for sharing!

tech 22 February, 2011 - 12:46

Saved my day

Mange tak! Den här posten hjälpte mig att fixa dagens arbete... Vi ses på DrupalCamp CPH nu på fredag hoppas jag.

Leander 19 September, 2011 - 14:57

Hmmm...

Strange text replacement on your site!

Leander 19 September, 2011 - 14:59

Great post (and, you need Mollom anti-spam on your blog.. :)

Great Post, Morten.

Not sure if you've noticed, but some hyperlink spammers are taking advantage of your Comment system...

Anonymous 16 November, 2011 - 17:37

yeah anonymous i got it ...

yeah anonymous i got it ... geeez

mortendk 17 November, 2011 - 09:51
The content of this field is kept private and will not be shown publicly.
@danigrrl yup true and she is the source for it - but okay she don't touch my espresso machine so i guess its okay (almost) 1 hour 52 min ago
3,252

DrupalCon Denver 2012 - I am a Speaker!

good Stüff

Mothership - a clean up the crap "theme"

Miro - a open atrium theme:
more info & comments

freya rocks

the progress for my premature daughter can be folllowed here:
Freya Rocks
sorry its in danish

the blög

Give some Love to the development of the mothership

Flattr this

User login

Recent comments

give some luv

drupal member ...

geek royale