{"id":2258,"date":"2011-01-23T19:51:23","date_gmt":"2011-01-23T19:51:23","guid":{"rendered":"http:\/\/sunpig.com\/mt-entry-2258.html"},"modified":"2011-01-23T20:31:09","modified_gmt":"2011-01-23T20:31:09","slug":"fieldset-and-legend-formatting","status":"publish","type":"post","link":"https:\/\/sunpig.com\/martin\/2011\/01\/23\/fieldset-and-legend-formatting\/","title":{"rendered":"Fieldset and Legend formatting"},"content":{"rendered":"\n<p style=\"font-style:italic\"><a href=\"http:\/\/sunpig.com\/martin\/code\/2011\/fieldset\/demo.html\">demo page<\/a><\/p>\n<p><code>&lt;fieldset&gt;<\/code> and <code>&lt;section&gt;<\/code> elements can both<br \/>\n            be used to break up a large whole (a form or a document) into smaller,<br \/>\n            logically grouped chunks.  Semantically, a <code>&lt;section&gt;<\/code> element is very flexible,<br \/>\n            but a <code>&lt;fieldset&gt;<\/code> is much more restrictive. Although you can put a <code>&lt;h<i>n<\/i>&gt;<\/code><br \/>\n            element somewhere inside its body to give it a title, the proper way to indicate the caption of a fieldset is to use<br \/>\n            a <code>&lt;legend&gt;<\/code>. This is where the problems come in, because <code>&lt;legend&gt;<\/code><br \/>\n            is a pain in the arse to style.<\/p>\n<p>For a start, browsers refuse to style a <code>&lt;legend&gt;<\/code> as a block, which means that you can&#8217;t<br \/>\n            easily apply a background and border that stretches across the whole width of the <code>&lt;fieldset&gt;<\/code><br \/>\n            it is captioning. Secondly, browsers have a set of special non-overrideable positioning rules for <code>&lt;legend&gt;<\/code><br \/>\n            that are designed to make it float in the middle of the border around the <code>&lt;fieldset&gt;<\/code> &mdash; see below.<\/p>\n<p class=\"center\"><img decoding=\"async\" src=\"http:\/\/sunpig.com\/martin\/code\/2011\/fieldset\/img\/naked-fieldset.gif\" class=\"center\" \/><\/p>\n<p>Furthermore, you can&#8217;t just wrap the <code>&lt;legend&gt;<\/code> in a <code>&lt;header&gt;<\/code>, because<br \/>\n            <a href=\"http:\/\/www.whatwg.org\/specs\/web-apps\/current-work\/multipage\/forms.html#the-legend-element\">the spec says that the<br \/>\n            <code>&lt;legend&gt;<\/code> has to be the first child element of the <code>&lt;fieldset&gt;<\/code><\/a>.<br \/>\n            Oh, and you can&#8217;t just put a block-level <code>&lt;header&gt;<\/code> <em>inside<\/em> the <code>&lt;legend&gt;<\/code><br \/>\n            either, because a <code>&lt;legend&gt;<\/code> may only contain <a href=\"http:\/\/www.whatwg.org\/specs\/web-apps\/current-work\/multipage\/content-models.html#phrasing-content\">phrasing content<\/a>.<br \/>\n            (You <em>can<\/em> put a <code>&lt;span&gt;<\/code> in there and then apply <code>display:block<\/code> to the span; this is a significant part of the workaround. But you have to be careful with positioning the element when its content wraps over multiple lines.)<\/p>\n<p>The reason I&#8217;m looking for a workaround in the first place is this:  I&#8217;ve got an application<br \/>\n            where edit screens are divided up into chunks, some of which contain groups of fields,<br \/>\n            and some of which contain lists.  Their HTML content is different, but visually I want their blocks<br \/>\n            to be styled essentially the same way &mdash; see image below.<\/p>\n<p class=\"center\"><img decoding=\"async\" src=\"http:\/\/sunpig.com\/martin\/code\/2011\/fieldset\/img\/fieldset-and-section.gif\" class=\"center\" \/><\/p>\n<p>Additional requirements:<\/p>\n<ul>\n<li>Insofar as possible, I want the <code>&lt;fieldset&gt;<\/code> and <code>&lt;section&gt;<\/code><br \/>\n                to share a common set of modular classes, so that I don&#8217;t have to maintain two completely<br \/>\n                different sets of styles.<\/li>\n<li>Mobile devices have narrow screens, but some sections have long captions; captions longer than can fit<br \/>\n                on a single line should break nicely across multiple lines. (Some <code>&lt;legend&gt;<\/code> formatting examples on<br \/>\n                the interwebs rely on re-positioning the caption, but don&#8217;t take multi-line captions into account.)<\/li>\n<li>When CSS is disabled, the naked HTML should be comprehensible because of the appropriate use of<br \/>\n                standard semantics: a fieldset is a fieldset, a section is a section. No silly tricks.<\/li>\n<li>No JavaScript, with the exception of the <a href=\"http:\/\/code.google.com\/p\/html5shim\/\">HTML5 shim<\/a> to make IE&lt;9 behave.<\/li>\n<\/ul>\n<p>Here&#8217;s the HTML structure I&#8217;m happy with:<\/p>\n<p>HTML for a <code>&lt;section&gt;<\/code>:<\/p>\n<pre class=\"code html\">\n&lt;section class=\"chunk\"&gt;\n    &lt;header class=\"hd\"&gt;\n        &lt;h1 class=\"text\"&gt;Caption text&lt;\/h1&gt;\n    &lt;\/header&gt;\n    &lt;div class=\"bd\"&gt;\n        &lt;ol class=\"list\"&gt;\n            ...\n        &lt;\/ol&gt;\n    &lt;\/div&gt;\n&lt;\/section&gt;\n        <\/pre>\n<p>HTML for a <code>&lt;fieldset&gt;<\/code>:<\/p>\n<pre class=\"code html\">\n&lt;section class=\"chunk\"&gt;\n    &lt;fieldset&gt;\n        &lt;legend class=\"hd\"&gt;\n            &lt;span class=\"text\"&gt;Caption&lt;\/span&gt;\n        &lt;\/legend&gt;\n        &lt;div class=\"bd\"&gt;\n            &lt;ol class=\"fields\"&gt;\n                ...\n            &lt;\/ol&gt;\n        &lt;\/div&gt;\n    &lt;\/fieldset&gt;\n&lt;\/section&gt;\n        <\/pre>\n<p>Key points to note:<\/p>\n<ul>\n<li>A <code>&lt;fieldset&gt;<\/code> is actually wrapped inside a <code>&lt;section&gt;<\/code>.<br \/>\n                Semantically, this is unnecessary, but it makes consistent styling easier. The outermost<br \/>\n                <code>&lt;section&gt;<\/code> provides a consistent container block context, side-stepping any<br \/>\n                un-overrideable browser default styles for the <code>&lt;fieldset&gt;<\/code> element.<br \/>\n                The semantic duplication is something I can live with.  <a href=\"http:\/\/twitter.com\/vasilis\">Vasilis<\/a> points out that a <code>&lt;div&gt;<\/code> element wrapper might be better than a <code>&lt;section&gt;<\/code>, because it is semantically neutral.  The CSS styling would be exactly the same; I chose <code>&lt;section&gt;<\/code> because it makes the HTML structures as similar as possible.<\/li>\n<li>The inner content is split into header and body content, identified by elements with the class<br \/>\n                names &#8220;hd&#8221; and &#8220;bd&#8221;.<\/li>\n<li>For the fieldset case, the .hd element is the <code>&lt;legend&gt;<\/code> element,<br \/>\n                whereas for the section case, .hd is a <code>&lt;header&gt;<\/code>.  In both cases, the .hd class<br \/>\n                is attached to an element that semantically represents a caption for its logical block.<\/li>\n<li>The actual text of the caption is wrapped in an element with a &#8220;.text&#8221; classname<br \/>\n                rather than just being simple inner content of the caption.  This is because we need to hang<br \/>\n                some extra styling on an inner element of the .hd element.  (For a <code>&lt;section&gt;<\/code>,<br \/>\n                the .text element is an <code>&lt;h1&gt;<\/code> element, because a <code>&lt;header&gt;<\/code><br \/>\n                deserves an actual heading element inside it.)<\/li>\n<\/ul>\n<p>Here&#8217;s the key CSS:<\/p>\n<pre class=\"code css\">\n.chunk {\n    background:#ccf;\n    border:0.2em solid #99c;\n    border-top-left-radius:0.8em;\n    border-top-right-radius:0.8em;\n    display:block;\n    margin-bottom:2em;\n    overflow:hidden;\n    position:relative;\n}\n.chunk fieldset,\n.chunk legend {\n    border:none;\n    margin:0;\n    padding:0;\n}\n    .chunk .hd {\n        display:block;\n        padding:0.5em 0 0.3em;\n        width:100%; \/* For IE8 *\/\n    }\n        .chunk .hd .text {\n            color:#003;\n            font-family:helvetica,arial;\n            font-size:138.5%;\n            font-weight:normal;\n            margin:0 0.5em;\n            white-space:normal;\n            display:block;zoom:1; \/* For IE7 *\/\n        }\n    .chunk .bd {\n        background: #eef;\n        border-top:0.2em solid #99c;\n        padding:1em 0.5em;\n    }\n        <\/pre>\n<p>Key points:<\/p>\n<ul>\n<li>There is a single border around the whole section; the line separating the header from the body<br \/>\n                is a top border on the div.bd element.<\/li>\n<li>For fieldsets and legends, we zap any default margins and padding<\/li>\n<li>The header&#8217;s background colour is actually the background of the <em>entire section<\/em>.  This is<br \/>\n                to ensure that the visual header always occupies the full width of the section.  If you want a fancier<br \/>\n                background for the header (a gradient or an image), you obviously have to apply it to the whole section.<\/li>\n<li>The body&#8217;s background is applied on the div.bd element.<\/li>\n<li>The font styling for the header is applied on the .text element.  Pay particular attention to the<br \/>\n                white-space:normal rule, because this is what allows the text to wrap when it&#8217;s inside a <code>&lt;header&gt;<\/code><\/li>\n<li>There are a couple of IE7\/8 hacks &mdash; these ensure that long text wraps onto multiple lines in those browsers. (I&#8217;m<br \/>\n                not even going to fire up a VM to experiment with IE6.)  The caption is pushed a little too far to the right in IE7,<br \/>\n                but I&#8217;m not too worried about that; some more IE7-specific CSS could probably fix it easily, but I wanted to keep the<br \/>\n                example CSS to the point.<\/li>\n<\/ul>\n<p>Have a look at the <a href=\"http:\/\/sunpig.com\/martin\/code\/2011\/fieldset\/demo.html\">demo page<\/a> to see what it looks like for real.<\/p>\n<p>I&#8217;m not going to go into much detail about the inner structure of the body of these blocks &mdash;<br \/>\n            <a href=\"http:\/\/www.alistapart.com\/articles\/prettyaccessibleforms\">keeping form content semantic and pretty<\/a><br \/>\n            is way beyond the scope of this article, and there is much more good information available on this topic<br \/>\n            available on the interwebs than there is for <code>&lt;fieldset&gt;<\/code> and <code>&lt;legend&gt;<\/code>.<br \/>\n            Have a look at the source code of the demo page if you want to see how I&#8217;m doing things there.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>demo page &lt;fieldset&gt; and &lt;section&gt; elements can both be used to break up a large whole (a form or a document) into smaller, logically grouped chunks. Semantically, a &lt;section&gt; element is very flexible, but a &lt;fieldset&gt; is much more restrictive. Although you can put a &lt;hn&gt; element somewhere inside its body to give it a &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/sunpig.com\/martin\/2011\/01\/23\/fieldset-and-legend-formatting\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Fieldset and Legend formatting&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-2258","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/posts\/2258","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/comments?post=2258"}],"version-history":[{"count":0,"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/posts\/2258\/revisions"}],"wp:attachment":[{"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/media?parent=2258"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/categories?post=2258"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/tags?post=2258"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}