Between curating sites for the HTML5 gallery and answering readers' questions here at HTML5 Doctor, I see a host of HTML5 sites and their underlying markup. In this post, I'll show you some of the mistakes and poor markup practices I often see and explain how to avoid them.
Don't use section as a wrapper for styling
One of the most common problems I see in people's markup is the arbitrary replacement of <div>s with HTML5 sectioning elements — specifically, replacing wrapper <div>s (used for styling) with <section>s. In XHTML or HTML4, I would see something like this:
<!– HTML 4-style code –>
<div id="wrapper"> <div id="header"> <h1>My super duper page</h1> <!-- Header content --> </div> <div id="main"> <!-- Page content --> </div> <div id="secondary"> <!-- Secondary content --> </div> <div id="footer"> <!-- Footer content --> </div> </div>
Now, I'm instead seeing this:
<!-- Don't copy this code! It's wrong! --> <section id="wrapper"> <header> <h1>My super duper page</h1> <!-- Header content --> </header> <section id="main"> <!-- Page content --> </section> <section id="secondary"> <!-- Secondary content --> </section> <footer> <!-- Footer content --> </footer> </section>
Frankly, that's just wrong: <section> is not a wrapper.The <section> element denotes a semantic section of your content to help construct a document outline. It should contain a heading. If you're looking for a page wrapper element (for any flavour of HTML or XHTML), consider applying styles directly to the <body> element as described by Kroc Camen. If you still need an additional element for styling, use a <div>. As Dr Mike explains, div isn't dead, and if there's nothing else more appropriate, it's probably where you really want to apply your CSS.
With that in mind, here's the correct way to mark up the above example using HTML5 and a couple of ARIA roles. (Note: you may need one <div> depending on your design.)
<body> <header> <h1>My super duper page</h1> <!-- Header content --> </header> <div role="main"> <!-- Page content --> </div> <aside role="complementary"> <!-- Secondary content --> </aside> <footer> <!-- Footer content --> </footer> </body>
If you're not quite sure which element to use, then I suggest you refer to our HTML5 sectioning content element flowchart to guide you along your way.
Only use header and hgroup when they're required
There's no sense writing markup when you don't have to, right? Unfortunately, I often see <header> and <hgroup> being used when there's no need for them. You can get up to speed with our articles on the <header> element and the <hgroup> element, but I'll briefly summarise:
- The <header> element represents a group of introductory or navigational aids and usually contains the section's heading
- The <hgroup> element groups a set of <h1>—<h6> elements representing a section's heading when the heading has multiple levels, such as subheadings, alternative titles, or taglines
Overuse of header
As I'm sure you're aware, the <header> element can be used multiple times in a document, which has popularized the following pattern:
<!-- Don't copy this code! No need for header here --> <article>
<header> <h1>My best blog post</h1> </header> <!-- Article content --> </article>
If your <header> element only contains a single heading element, leave out the <header>. The <article> ensures that the heading will be shown in the document outline, and because the <header> doesn't contain multiple elements (as the definition describes), why write code when you don't need to? Simply use this:
<article> <h1>My best blog post</h1> <!-- Article content --> </article>
Incorrect use of <hgroup>
On the subject of headers, I also frequently see incorrect uses of <hgroup>. You should not use <hgroup> in conjunction with <header> when:
- there's only one child heading, or
- the <hgroup> would work fine on its own (i.e., without the <header>).
The first problem looks like this:
<!-- Don't copy this code! No need for hgroup here --> <header> <hgroup> <h1>My best blog post</h1> </hgroup> <p>by Rich Clark</p> </header>
In that case, simply remove the <hgroup> and let the heading run free.
<header> <h1>My best blog post</h1> <p>by Rich Clark</p> </header>
The second problem is another case of including elements when they're not necessarily required.
<!-- Don't copy this code! No need for header here --> <header> <hgroup> <h1>My company</h1> <h2>Established 1893</h2> </hgroup> </header>
When the only child of the <header> is the <hgroup>, why include the <header>? If you don't have additional elements within the <header> (i.e., siblings of the <hgroup>), simply remove the <header> altogether.
<hgroup> <h1>My company</h1> <h2>Established 1893</h2> </hgroup>
For more <hgroup> examples and explanations, read the detailed article about it in the archives.
Don't wrap all lists of links in <nav>
With 30 new elements (at the time of writing) introduced in HTML5, we're somewhat spoilt for choice when it comes to creating meaningful, structured markup. That said, we shouldn't abuse the super-semantic elements now made available to us. Unfortunately, that's what I see happening with <nav>. The spec describes <nav> as follows:
The nav element represents a section of a page that links to other pages or to parts within the page: a section with navigation links.
Note: Not all groups of links on a page need to be in a nav element — the element is primarily intended for sections that consist of major navigation blocks. In particular, it is common for footers to have a short list of links to various pages of a site, such as the terms of service, the home page, and a copyright page. The footer element alone is sufficient for such cases; while a nav element can be used in such cases, it is usually unnecessary.