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.
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
Incorrect use of
On the subject of headers, I also frequently see incorrect uses of
The spec describes
If it’s a purely presentational image and not referenced elsewhere in the document, then it’s definitely not a
A while back, I wrote about
In HTML5, there’s no need to include the
There are three valid ways for a boolean attribute to be applied. (The second and third options only apply if you’re writing XHTML syntax.)
Thanks to Ian Devlin, Derek Johnson, Tady Walsh, the HTML5
Gallery curators, and the HTML5 Doctors for their input to this article.
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>
).
<!-- 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.Common mistakes with the figure element
Ah,<figure>
. The appropriate use of this element, along with its partner-in-crime <figcaption>
, is quite difficult to master. Let’s look at a few common problems I see with <figure>
.Not every image is a figure
Earlier, I told you not to write extra code when it’s not necessary. This mistake is similar. I’ve seen sites where every image has been marked up as a<figure>
.
There’s no need to add extra markup around your images for the sake of
it. You’re just creating more work for yourself and not describing your
content any more clearly.The spec describes
<figure>
as being some flow content, optionally with a caption, that is self-contained and is typically referenced as a single unit from the main flow of the document.Therein lies the beauty of
<figure>
, that it can be moved away from the primary content — to a sidebar, say — without affecting the document’s flow.If it’s a purely presentational image and not referenced elsewhere in the document, then it’s definitely not a
<figure>
. Other use cases vary, but as a start, ask yourself, Is this image required to understand the current context?If not, it’s probably not a
<figure>
(an <aside>
, perhaps). If so, ask yourself, Could I move this to an appendix?If the answer to both questions is ‘yes’, it’s probably a
<figure>
.Your logo is not a figure
Segueing nicely on, the same applies to your logo. Here are a couple of snippets that I see regularly:<!-- Don’t copy this code! It’s wrong! -->
<header>
<h1>
<figure>
<img src="/img/mylogo.png" alt="My company" class="hide" />
</figure>
My company name
</h1>
</header>
<!-- Don’t copy this code! It’s wrong! -->
<header>
<figure>
<img src="/img/mylogo.png" alt="My company" />
</figure>
</header>
There’s nothing else to say here. It’s just plain wrong. We could
argue until the cows come home about whether your logo should be in an <h1>
, but that’s not what we’re here for. The real issue is the abuse of the <figure>
element. <figure>
should be used only when referenced in a document or surrounding
sectioning element. I think it’s fair to say that your logo is rarely
going to be referenced in such a way. Quite simply, don’t do it. All you
need is this:<header>
<h1>My company name</h1>
<!-- More stuff in here -->
</header>
Figure can be more than an image
Another common misconception regarding<figure>
is that it can only be used for images. This isn’t the case. A <figure>
could be video, audio, a chart (in SVG, for example), a quote, a table,
a block of code, a piece of prose, or any combination of these and much
more besides. Don’t limit your <figure>
s to images. Our job as web standards affectionadoes is to accurately describe the content with our markup.A while back, I wrote about
<figure>
in more depth. It’s worth a read if you want more detail or need a refresher.Don’t include unnecessary type attributes
This is probably the most common problem we see in HTML5 Gallery submissions. While it isn’t really a mistake, I believe it’s best practice to avoid this pattern.In HTML5, there’s no need to include the
type
attribute on <script>
and <style>
elements. While these can be a pain to remove if they’re automatically
added by your CMS, there’s really no reason to include them if you’re
coding by hand or if you have tight control over your templates. Since
all browsers expect scripts to be JavaScript and styles to be CSS, you
don’t need this:<!-- Don’t copy this code! It’s attribute overload! -->
<link type="text/css" rel="stylesheet" href="css/styles.css" />
<script type="text/javascript" src="js/scripts.js"></script>
Instead, you can simply write:<link rel="stylesheet" href="css/styles.css" />
<script src="js/scripts.js"></script>
You can also reduce the amount of code you write to specify your
character set, amongst other things. Mark Pilgrim’s chapter on semantics
in Dive into HTML5 explains all.Incorrect use of form attributes
You may be aware that HTML5 has introduced a range of new attributes for forms. We’ll cover them in more detail in the coming months, but in the meantime, I’ll quickly show you a few things not to do.Boolean attributes
Several of the new form attributes are boolean, meaning their mere presence in the markup ensures the behaviour is set. These attributes include:- autofocus
- autocomplete
- required
required
as an example, I’ve seen the following:<!-- Don’t copy this code! It’s wrong! -->
<input type="email" name="email" required="true" />
<!-- Another bad example -->
<input type="email" name="email" required="1" />
Ultimately, this causes no harm. The client’s HTML parser sees the required
attribute in the markup, so its function will still be applied. But what if you flip the code on its head and type required="false"
?<!-- Don’t copy this code! It’s wrong! -->
<input type="email" name="email" required="false" />
The parser will still see the required
attribute and implement the behaviour even though you tried to tell it not to. Certainly not what you wanted.There are three valid ways for a boolean attribute to be applied. (The second and third options only apply if you’re writing XHTML syntax.)
required
required=""
required="required"
<input type="email" name="email" required />
No comments:
Post a Comment