A Syntax Riddle Wrapped in a Parsing Enigma

I’m certain souls more intrepid than I have come across this quirk of HTML5 and Firefox already. But having smacked headlong into it the other night—and finding fewer accounts online of it than I would have hoped—I’m chucking my two cents at the hive mind.

So then, the bug. In HTML5 it’s now officially peachy keen to wrap block level elements in an anchor tag, something we’ve seen the rabble do for years but that proper gentlefolk such as we would never deign do, no sir thank you very much. This proves incredibly handy when it comes to things like headlines, subheadings and photo pairings, allowing us to wrap an img and an h1 tag in a single anchor, creating one link. Very tidy, methinks.

Trouble is, under the right set of not-that-uncommon circumstances, Firefox goes all pear-shaped on us. Take the following code:

<article>
  <a href="#">
    <p><img src="thumbnail.jpg" alt="" /></p>
    <header>
      <h1>A Snappy Title</h1>
    </header>
    <p>A pithy introduction.</p>
  </a>
</article>

Give this markup some very simple styles to apply a border to the anchor and set it to display: block so we can see what’s going on, feed it to our unsuspecting browsers, and let’s see what we get:

We've secretly replaced the fine markup this server usually transmits with HTML5. Let's see if our browsers notice the difference. WebKit on the left, Firefox on the right.

Oh my. Note that I’m putting the anchor inside the article element because I want this to be a self-contained widget, just as the HTML5 Gods intended. The WebKit-powered browser does just fine, but Firefox… well, speaking in strictly technical terms, things break with verve. Firefox appears to be attempting to close the anchor prematurely, multiple times (I’m no rendering agent maven, so I can’t say for sure—Firefox code contributors, help me out here).

Some have had minor success explicitly declaring the anchor a block level element in their CSS. Others have suggested a JavaScript fix, a route I flatly refuse to go since we’re talking about basic access and an acceptable minimum of layout parity across browsers (Read: It should never ever appear this obviously, crazy-making broken to an end user.)

The solution? After some tinkering, I’ve found that if you don’t include any of the new HTML5 elements inside the anchor, the wrapping works as intended. So if we remove the HTML5 header tag

<article>
  <a href="#">
    <p><img src="thumbnail.jpg" alt="" /></p>
    <h1>A Snappy Title</h1>
    <p>A pithy introdution.</p>
  </a>
</article>

…we get this:

Look Ma, no header tag. WebKit on the left, Firefox on the right.

And peace is restored to the realm, albeit via the compromise of dropping any new HTML5 goodies inside your link. Word is all this should be resolved with the imminent release of Firefox 4 and it’s new HTML5 parser. But in the meantime, if you’re looking to make block-level links in HTML5 and want to pass muster in Firefox, make sure you’re wrapping old school html elements and none of the new HTML5 elements, and you should be fine for now.

Update

Officially submitted as bug #637044.