Nathan Knowler

Context Matters for Semantic HTML

Permalink

I see three stages to learning semantic HTML.

The first stage is expanding your vocabulary beyond using <div>, <span>, and other special elements (e.g. <a>, <button>, <input>, etc.). Often at this stage, HTML authors will tap into a wider vocabulary of elements, but use them as it makes sense to them. For example, I’ve seen card elements created like this:

<section class="card">
	<header></header>
	<main></main>
	<footer></footer>
</section>

While this might make a bit more sense to the person who wrote the code—this is a misuse of semantics, which leads me to the second stage…

The second stage is understanding the semantics of the elements beyond their tag name. This means understanding what ARIA role they map to. For example, while some are straightforward like the <main> element having the role of main, others are a bit different, like the <header> element mapping to the banner role or the <footer> element mapping to the contentinfo role.

The third is similar to the second and perhaps could be understood as the second learned correctly. The third stage is understanding that the context an element is used in affects its meaning. So for that last example: the <header> element maps to the banner role and the <footer> element maps to the contentinfo role—that is only true if they’re used in a specific context.

The following are two common examples where the <header> and <footer> elements would not have any corresponding ARIA role since they’re being used as a descendant of the <main> element or a sectioning content element (i.e. article, section, nav, aside).

<body>
	<main>
		<header></header>
		<footer></footer>
	</main>
</body>
<body>
	<article>
		<header></header>
		<footer></footer>
	</article>
</body>

In the next example, the <header> and <footer> elements are direct descendants of the <body> element and therefore have their respective banner and contentinfo roles.

<body>
	<header></header>
	<main></main>
	<footer></footer>
</body>

This doesn’t mean that your <header> or <footer> elements must be at the top-level as direct descedants of the <body> element. You can wrap them in a <div> element (or layers of <div> elements).

<body>
	<div>
		<header></header>
		<main></main>
		<footer></footer>
	</div>
</body>

Also, this doesn’t mean that you shouldn’t use <header> or <footer> within sectioning elements. Just make sure you’re not expecting them to do anymore than be a slight improvement of the developer experience over using <div>. Their more forgiving nature lends them to be helpful for that use unlike an element like <main> which you should only use in its appropriate context.

Personally, I tend to avoid using those element outside of contexts where they have more semantic meaning, because I think it makes the HTML source more clear and it means I can be less specific when writing CSS (i.e. if there’s only one <header> element on the page, there isn’t going to be any conflict if I use a simple selector like the header type selector). Instead of using <div>, I might use a custom element name like article-header. If you do this, just keep in mind that you’ll likely want to assign a different CSS display value to these elements since the default is inline.

There’s a lot more that can be said on this topic, like if there is more than one <nav> element on a page they should have different accessible names or that <section> doesn’t really do much on its own (see Todd Libby’s article, “<section> is the new <div> or Scott O’Hara’s article, “Accessibility of the section element”). I guess this is my invitation to you to look deeper into the meaning behind the elements we use and understand the real effects they have on people consuming the HTML documents we author.