Block-level links, HTML5 and Firefox
Update: Unfortunately this doesn’t seem to be a magic bullet, and there are still problems with the dreaded packet boundary bug. See the Mozilla bug report for more info.
Recently I’ve been experimenting with wrapping block-level elements in <a> (so-called block-level links), as you can see in this page’s header. This has several benefits:
- several elements can of course be linked at once, such as an image and it’s caption—historically we’d need to link both the image and caption text individually
- Internet Explorer 6 doesn’t allow CSS
:hoveretc effects on anything other than<a> - making block-level elements into links increases the clickable area
Changing <a> from an inline element to something like <del> that can appear pretty much anywhere is fine in the spec, but what about browser support? Luckily, this behaviour is already unofficially supported in current browsers. However I recently discovered a bug in Firefox; if the block-level link contains any of the new HTML5 semantic elements bizarre stuff happens (Bugzilla: #514122, test case):
Code sample
<div>
<a href="/">
<hgroup>
<h1>Title</h1>
<h2>Subtitle</h2>
</hgroup>
</a>
</div>
In Firefox (DOM asplode)
<div>
<a href="/">
<hgroup>
</hgroup></a><h1><a _moz-rs-heading="" href="/">Title</a></h1>
<a href="/"> <h2>Subtitle</h2>
</a>
</div>
While the contained content is still linked, the HTML5 element is prematurely closed, the link becomes inline for the first element following the HTML5 element, and everything after that is wrapped in a new link. Kind of defeats the purpose huh. This is especially important for <hgroup>, a new HTML5 element that’s going to be block-linked a lot.
Luckily, there is an easy solution; add a <div> wrapper
Code sample with wrapper <div>
<div>
<a href="/">
<div>
<hgroup>
<h1>Title</h1>
<h2>Subtitle</h2>
</hgroup>
</div>
</a>
</div>
In Firefox (all is right in the DOM)
<div>
<a href="/">
<div>
<hgroup>
<h1>Title</h1>
<h2>Subtitle</h2>
</hgroup>
</div>
</a>
</div>
Wow that was easy! Lucky it wasn’t an IE bug huh ;-) There are some other things to watch out for too. Link styles don’t inherit to block-level elements, so you need to explicitly declare them on the contained elements, or use eg {background: inherit;}. This also includes the browser default {text-decoration: underline;} (in Safari browser link styles are applied, but user link styles also need to be declared). Finally, Firefox handles tag mismatch errors in block-level links … poorly. When in doubt, validate.
So in conclusion, if your block-level links contain HTML5 structural elements, add a wrapper <div>. If you have any questions, feedback, or have found a mistake, please let me know via Twitter (@boblet)…