Oli.jp

Articles…

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.

You can test until you see the result then use FireBug to examine the DOM, then write custom selectors targeting the new structure to replicate your desired styles. You can wait until FireFox’s new HTML5 parser is default (getting close but not yet as of FireFox 3.6). Or you can give up and either not use block-level links, or change all elements inside the block-level link to <span> and style them to look like the original elements (ugh).

Recently I’ve been experimenting with wrapping block-level elements in <a> (so-called block-level links). This has several benefits:

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 generally seems to work in current browsers. However I recently came across a bug in Firefox; if the block-level link contains any of the new HTML5 semantic elements bizarre stuff happens (Bugzilla: #514122, test case):

<div>
  <a href="/">
  <hgroup>
    <h1>Title</h1>
    <h2>Subtitle</h2>
  </hgroup>
  </a>
</div>

The above code 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

Block-level link with wrapper <div> #

<div>
  <a href="/">
    <div>
      <hgroup>
        <h1>Title</h1>
        <h2>Subtitle</h2>
      </hgroup>
    </div>
  </a>
</div>

The above code 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>.

Feedback #

If you have any questions, feedback, or have found a mistake, please let me know via Twitter (@boblet). Tweet about it using this shortlink: http://01i.jp/html5bll

Changes #

  1. Finally migrated from boblet.tumblr.com, allowing me to walk the walk with HTML5 templates improvements, & CSS3 enrichment too.
  2. Made the update at the top more informative