Semantic HTML tags allow you to add meaning to your markup so that search engines, screen readers, and web browsers can make sense of it. By default, when a user agent reads your content it doesn’t understand the context and meaning. Semantic HTML tags let you serve structured content to your users, which is especially important for on-page SEO and accessibility.
Although semantic tags existed in earlier HTML versions, the HTML5 specifications added several new semantic elements to the syntax—both on the block and inline levels. In this article, we’ll look into how HTML semantics work and also give you some tips about how to get the most out of the feature.
Semantic vs. Non-Semantic HTML Elements
The HTML markup consists of two kinds of elements: semantic and non-semantic ones. Both have their own purpose. You should use semantic tags when you want to mark up a content block that has an important role in the document structure. For instance, <ul> and <li> are semantic elements that indicate the presence of an unordered list.
On the other hand, non-semantic tags are for generic content. Developers typically use them when they need to mark up a content block for styling purposes. The most frequently used non-semantic tags are <div> and <span>. Both define a group of otherwise unrelated content: <div> on the block level, while <span> on the inline level. Although new CSS techniques such as flexbox and CSS Grid enable developers to rely less on non-semantic tags, they are still frequently used.
Most Frequently Used Semantic Tags
Perhaps it’s not surprising that the most frequently used semantic elements are the ones that had already existed before HTML5 came forth. Actually, there are three semantic tags without which you can’t even create an HTML document:
- <html> that encloses the whole page,
- <head> that contains all the necessary information that’s for rendering the page,
- <body> that encloses the content of the page.
These three semantic elements give the backbone of every HTML document. Besides them, here are the most popular semantic elements, all of which are defined by earlier HTML specifications:
- <ul>, <ol>, and <li> for defining ordered and unordered lists,
- <p> for paragraphs,
- <table> for tables,
- <form> for forms,
- <img> for images,
- <h1>, <h2>, <h3>, <h4>, <h5>, <h6> for different levels of headings.
Some of the elements above also have supplementary tags, which are also semantic ones. For example, <table> has <thead>, <tbody>, and <tfoot> that let you mark up the header, body, and footer of the table.
Block-Level Semantic Elements in HTML5
HTML5 has added several new semantic elements to the markup. Developers most love the ones that allow them to create content blocks with semantic meaning. Block-level semantic tags have two main types:
- Sectioning elements create a distinct section inside the HTML document. Their contents are treated as separate blocks in the document outline, so they can have their own heading and footer tags. There are four of them:
- Semantic flow elements carry semantic meaning but don’t create distinct blocks within the document, thus they can’t have their own heading and footer elements. There are many of them but here are the most widely used ones:
- <main> for the main content block of the document (can be used only once on a page),
- <header> for the header section of a page or sectioning element,
- <footer> for the footer section(s) of a page or sectioning element,
- <audio> for audio embeds,
- <video> for video embeds,
- <figure> for block-level image blocks.
As it’s important to understand how sectioning elements work, let’s see a code example. Below, you can see how a typical blog archive page would look like in HTML. Blog posts are marked up with the semantic <article> tag. At the bottom of the <main> section, there’s also a <section> tag for, say, a related content block.
<html>
<head></head>
<body>
<header>
<h1>Page Title</h1>
<h2>Page Subtitle</h2>
<header>
<main>
<article>
<header>
<h1>Article Title (1)</h1>
<h2>Article Subtitle (1)</h2>
</header>
...
<footer></footer>
</article>
<article>
<header>
<h1>Article Title (2)</h1>
<h2>Article Subtitle (2)</h2>
</header>
...
<footer></footer>
</article>
<section>
<header>
<h1>Section Title</h1>
<h2>Section Subtitle</h2>
</header>
...
<footer></footer>
</section>
</main>
<footer>...</footer>
</body>
</html>
As you can see above, the document includes a <header> section with a <h1> and <h2> tag for the title and subtitle of the entire page. It has a <footer> section, too, right above the closing </body> tag, for page-related footer elements such as copyright credits.
However, every <article> and <section> tag has its own <header> and <footer> elements as well. Each <header> tag includes its own <h1> and <h2> headings for the title and subtitle of the belonging article or section, too.
Sectioning elements form encapsulated blocks inside the document outline. You can have as many sectioning elements as you want; each will be treated as a mini-document with its own outline. If you insert the code example above into an HTML outliner this is how the document structure will look like:
Inline-Level Semantic Tags in HTML5
You can use inline tags within block-level elements, for instance an emphasized text string within a paragraph or list. Besides block-level semantic elements, HTML5 has also introduced a couple of semantic inline tags, even though previous specs also included semantic inline tags such as <a> for hyperlinks or <abbr> for abbreviations.
HTML5’s semantic inline elements have been created with the goal of replacing non-semantic inline tags that previously were used quite frequently, respectively the <b> tag for bold text and <i> for italics. But, as a rule of thumb, HTML should be used only to define meaning and structure. All styling should be done with CSS.
So, HTML5 has replaced <b> with the <strong> tag and <i> with <em>. To make the transition easier, web browsers have kept styling <strong> with bold fonts and <em> with italics. However, these semantic tags don’t imply such styling, as <strong> indicates important text, while <em> defines emphasized text—with any kind of styling.
HTML5 has other less frequently used inline-level semantic tags, too, such as <progress> for progress bars and <mark> for highlighted text.
The Document Outline
The ultimate goal of HTML semantics is to create a document outline that user agents such as web browsers, screen readers, and search engine bots can easily skim and understand. To do so, you need to use semantic and non-semantic tags wisely.
You should use semantic tags whenever you define a content block that has a meaning. Sectioning elements are also added to the document outline that defines the structure of your page. The example blog archive page above in the article is a typical document outline of a website making use of semantic HTML.
You can extend the document outline with other sectioning tags, too. For instance, this is how you can add a semantic sidebar and navigation block to your page:
<html>
<head></head>
<body>
<header>
<h1>Page Title</h1>
<h2>Page Subtitle</h2>
<nav>
<ul>
<li>Menu 1</li>
<li>Menu 2</li>
<li>Menu 3</li>
</ul>
</nav>
</header>
<main>...</main>
<aside>...</aside>
<footer>...</footer>
</body>
</html>
Next Steps
This was HTML semantics in a nutshell! Creating a semantic document outline takes some consideration, but it can mean a lot to your users and improve your SEO results, too.
Are you interested more in HTML5? If yes, also have a look at our collection of the best learning resources for front-end developers or check out how you can get the most out of HTML APIs.