HTML5 wrapping anchor behaviour

Takeaway nugget of information: If you're wrapping block level elements in an anchor, remember to set the anchor to display:block; to avoid unexpected styling issues.

If you want to leave a comment, please see the blog entry that accompanies this file.

Rationale

In HTML5 you can now wrap block level elements in an anchor tag. This is useful but can lead to unexpected behaviour if you've got an idea in your head that a wrapping anchor would behave like a wrapping <div> or other block-level element you're used to wrapping things with. It's important to remember that by default an anchor is not a block-level element. It's inline.

You don't usually wrap things with something that's set to display inline, so naturally I was expecting the anchor to behave like a div. Here's a table of what I was expecting to happen at first:

CSS HTML Expected behaviour Actual Result
a { border: 1px solid red; }
<a href="/">
  <h3>This is a heading</h3>
  <p>This is a paragraph</p>
  this is 'naked' text
</a>
A red box drawn around everything

This is a heading

This is a paragraph

this is 'naked' text
a { opacity : 0; }
<a href="/">
  <h3>This is a heading</h3>
  <p>This is a paragraph</p>
  this is 'naked' text
</a>
No visible text

This is a heading

This is a paragraph

this is 'naked' text

As you can see, the styling applied to a wrapping anchor effects only on the anchor itself, not the child block-level elements. That's just the same as if we'd wrapped those elements in a <span> (which we'd never do).

The solution to get the wrapping anchor to behave as expected is to set the wrapping anchor as display:block;.

CSS HTML Expected behaviour Result
a { display: block; border: 1px solid red; }
<a href="/">
  <h3>This is a heading</h3>
  <p>This is a paragraph</p>
  this is 'naked' text
</a>
A red box drawn around all of the text

This is a heading

This is a paragraph

this is 'naked' text
a { display: block; opacity : 0; }
<a href="/">
  <h3>This is a heading</h3>
  <p>This is a paragraph</p>
  this is 'naked' text
</a>
No visible text

This is a heading

This is a paragraph

this is 'naked' text