Semantic HTML5 provides us with an opportunity to improve our websites and optimize for search engines. We can take full advantage of these opportunities by using machine-readable semantic HTML5 elements to describe page outlines. Specially-named containers can help search engines and browsers more easily identify how our pages are arranged.
For example, <header>
is its own element now, as is <nav>
, and so on. You have the ability to describe your page outline using these terms. By the way, it’s important not confuse <header>
with heading containers (<h1>
). These also have semantic rules we should follow; specifically about their relative level, as you’ll see below.
Here’s a look at the SEO opportunities with HTML5 elements and how and why to use them.
Genuine Articles
Perhaps the most important semantic HTML5 element is <article>
. This can be used in such a way that your ideal content gets parsed into screen readers and reader views, and search engines will find a hard-coded signal for unique content on the page. You can test to see how this works with a page loaded in your browser by toggling the reader view.
If you don’t see your toggle switch or there is no <article>
container in page code, you don’t get the option at all or it won’t load anything separately. If you get content in the reader view, it will be that content which the webmaster wrapped in a single <article>
container. As developers we get to style these containers with direct specificity.
Multiple Articles
Although it’s not syntactically incorrect to have more than one <article>
element per page, it’s still not a good idea. You don’t get reader view options this way, and there are no search engine benefits either. For blog homepages that list posts, you may think of each blog post as an “article,” except that an excerpt of an article is not the real thing.
Instead, try using the semantically correct <section>
element for each post summary where related details are gathered. <section>
can correctly nest as a child of <article>
in this case. The parent-child relationship between <article>
and <section>
can be reversed, but we wouldn’t recommend it unless circumstances make that logical.
Let a single <article>
wrap a page’s unique content:
<body itemscope itemtype="https://schema.org/WebSite">
<a class="visually-hidden focusable" href="#main">Skip Navigation</a>
<header id="top" class="margin-bottom-small">
<nav class="container container-small">
<div class="row">
<div class="grid-full">
...
</div>
</div>
</nav>
</header>
<main id="main" tabindex="-1" class="content">
<article class="container container-small">
<header>
<h1>SEO for Developers by Detlef Johnson</h1>
</header>
<section class="row">
<div class="grid-half">
<h2>Semantic HTML5</h2>
<p>We're doing HTML5 semantic elements ...
Technical Debt
Technical debt is aging code in the codebase that looks to be no fun to replace or refactor away. The most common technical debt takes the form of un-insightful variable names and database column names.
SEO practitioners often dispense advice reactive to their own painful embedded technical debt. Implementing semantic HTML5 may be a bit like that.
If you’re using a modern framework with a templating language like JSX, and everything is a <div>
or a <span>, renaming for successfully implementing <main>
, <article>
, <header>
, <nav>
, <footer>
, <aside>
, <section>
, can seem daunting, depending how early in the process you are. The longer you wait the more that technical debt compounds.
Semantic Details
Many of us prefer skipping what we initially think are smaller details for a process of writing code that is going to work, especially when under deadlines. We use what operations we have in place to publish websites and apps with minimal effort in order to be productive. We use frameworks, task runners, and tooling to great effectiveness. We’re constantly eyeing shiny new things to learn.
We also know that unaddressed details can immensely compound technical debt down the road. In the long run, you don’t want all your elements named after the same <div>
and <span>
elements. Your code will become less and less recognizable over time. Organize your code into logical elements. Use the elements HTML5 provides out of the box.
Semantic SEO Outline
In SEO we’ve long known about headings, particularly the top-level <h1>
heading. What makes them special is the meaning they convey about document and section outlines. Start your document outline with elements <main>
, <header>
, and perhaps one or two <nav>
containers (one per link grouping). Then you’ll likely want to use <article>
to wrap unique content with <header>
, headings, and perhaps its own <footer>
.
<article class="container container-small"> <header> <h1>SEO for Developers by Detlef Johnson</h1> </header> <section class="row"> <div class="grid-half"> <h2>Semantic HTML5</h2> <p>We're doing HTML5 semantic elements ... <h3>Articles and Sections</h3> <p>Article and Section elements should have at least one heading ... <h3>Headings</h3> <p>Headings provide 6 levels for organizing content ...
Each <section>
ought to have at least one heading; probably more. Your headings will outline what makes the best sense in descending order of levels from <h1>
through to content with heading <h6>
. Think of them as you would bullets and outline levels. It’s rare that you’ll actually use all 6 levels, but they’ll be at your disposal when you want them.
SEO the Semantics
You’ll hear advice from the SEO community that there should always only be one <h1>
element per page, all on its own. That’s solid advice. Think of it as the whole page heading. However, it’s definitely not wrong to have more than one — it depends on your document outline. You may elect to bump up the top heading in a <section>
or <aside>
, or you may show different <h1>
content between desktop and mobile.
Use Headings
Each <section>
should definitely have a heading, perhaps beginning with level two (<h2>
), and descending from there, depending on the content for that section. Use your best judgement and get hints from the W3C validation service. This can warn you when you’re missing <section>
headings. Each section can have its own <header>
and <footer>
, which makes sense when you think about it.
Webmaster Tip: Encode an admin-only set of quick links in a site-wide header or footer, and insert the canonical page spelling for the name value pair so you can click and check page validation more quickly than with other tools like bookmarks.
Taking Aside
As for <aside>
, it’s been suggested that these containers are suitable for related content that is not part of the unique content identified by <article>
, like an advertising block. These can still be unique to the page, of course. The <aside>
will nest nicely in <article>
or <section>
and can stand on its own, as well. The <aside>
container can also have headings <header>
, and <footer>
— it’s totally up to you.
Footer Wrapper
That should be enough information to get you started. When you’re ready to wrap up your HTML5 semantic markup, you can use the <footer>
element for the page footer with its site-wide links in one or more <nav>
elements. Most of these Semantic HTML5 elements are treated as block elements by default unless otherwise noted.
Support even the oldest browsers with the following sample polyfill:
<!--[if lt IE 9]> <script> document.createElement("article"); document.createElement("aside"); document.createElement("footer"); document.createElement("header"); document.createElement("nav"); document.createElement("section"); </script> <![endif]-->
Takeaway: Be Descriptive
The most important thing to look for when you’re otherwise using a semantically sensible <div>
to wrap a chunk of content as a grouping for one of the above, is to ask yourself the question: Can I use a more descriptive element? Will it work with my application code? Can I, for example, style it using row class names or other grid logic? Your answer should be yes until you’ve taken full advantage of HTML5 semantic markup.