Eric Niquette UI, UX, Accessibility

What is semantic HTML?

Semantic HTML, also known as semantic markup, is the practice of using HTML tags that clearly describe the meaning or role of the content on a web page. It's like using the right tool for the job, not like using a screwdriver to hammer in a nail. This makes your code easier to understand for both people (like developers) and machines (like screen readers).

A tag is considered semantic if it adds meaning to the content it contains. Modern HTML includes around 30 to 40 of these semantic elements. Common examples are headings like <h1>, content tags like <p>, <ul>, <table>, and <figure>, as well as layout elements like <header>, <main>, <aside>, <nav>, and <footer>.

Tags that don't convey meaning on their own are considered non-semantic. These are typically used for layout or styling with CSS. Common examples include <div>, <span>, and <br>. Some tags, like <i>, can be semantic in specific contexts—such as marking idiomatic text—but are often used purely for visual styling.

Benefits of semantic HTML

Accessibility

Using a website without semantic elements is like driving without road signs. You might get where you're going, but it will be slow and confusing.

Semantic HTML helps screen readers and other assistive technologies understand the type and structure of your content. For example, a screen reader might announce a level 2 heading or describe a table with six rows and three columns.

Elements like <header>, <main>, <aside>, <nav>, and <footer> act as landmarks. They give users a high-level map of the page, making it easier to navigate quickly and efficiently.

Usability

Semantic HTML helps elements behave in ways users expect. For example, using a <button> to link to another page can be confusing. People usually expect buttons to perform an action, not redirect them. In that case, an <a> tag is the better choice.

Semantic elements also help users visually scan a page. Headings, for example, act as clear breakpoints that organize content. Without them, even well-structured pages can look like one long block of text, making them harder to read.

Maintainability

Websites built with semantic HTML are easier to maintain. When you use meaningful elements like <article> or <nav>, the structure and purpose of the code are clearer at a glance.

In team environments, semantic tags create a shared language that helps everyone understand the layout and function of the content. This can even reduce the need for extra comments or documentation.

Search engine optimization (SEO)

Search engines rely on semantic elements like headings and landmark areas to understand and index a page's content. Pages with a solid semantic structure are easier to interpret and are often ranked higher in search results. Google Search Central, for example, highlights the importance of headings:

Use meaningful headings to indicate important topics, and help create a hierarchical structure for your content, making it easier for users to navigate through your document.

When to use ARIA roles

The role attribute in ARIA (Accessible Rich Internet Applications) is used to describe the purpose of elements when native HTML does not provide enough context.

For example, a <nav> element already has an implicit role="navigation". There is no need to declare the role manually. The same is true for elements like <main>, <header>, <footer>, <article>, and others. These elements already tell assistive technologies what their purpose is without any additional attributes.

Adding redundant ARIA roles can clutter your code and may interfere with how screen readers interpret the structure. The general rule is simple:

  • Use semantic HTML elements first.
  • Add ARIA roles only when there is no appropriate semantic HTML element available.

For example, if you are building a custom component using <div> or <span> and no native element fits the use case, then an ARIA role may help. But it should be used with care and only when necessary.

When in doubt, refer to the ARIA in HTML specification for a list of elements that already include built-in roles. Many common patterns are already covered by HTML itself.

Using a role with a custom component

In some cases, there is no semantic HTML element that fits a specific need. For example, if you are building a custom tab interface using <div> elements, ARIA roles can help communicate the structure to assistive technologies:


								<div role="tablist">
									<div role="tab" aria-selected="true">Overview</div>
									<div role="tab" aria-selected="false">Details</div>
								</div>
							

This example uses role="tablist" to define a group of tabs, and role="tab" to mark each item within the group. The aria-selected attribute communicates which tab is currently active. There are no native HTML elements for tabs, so ARIA is useful in this situation.

Semantic vs. non-semantic examples

To better understand how semantic HTML works in practice, let's look at some simple examples. These show how the same content can be written using either non-semantic or semantic elements.

Here's a basic navigation menu built with non-semantic markup:


								<div id="nav">
									<a href="/">Home</a> |
									<a href="/about">About</a> |
									<a href="/contact">Contact</a>
								</div>
							

And here's the same menu using semantic elements like <nav> and <ul>:


								<nav>
									<ul>
										<li><a href="/">Home</a></li>
										<li><a href="/about">About</a></li>
										<li><a href="/contact">Contact</a></li>
									</ul>
								</nav>
							

In the second example, the <nav> element clearly tells assistive technologies that this is a navigation region. The list structure also makes it easier for users and machines to scan and process the links.

Page sections

This block of content uses only <div> elements to divide the layout:


								<div id="header">Welcome to our site</div>
								<div id="content">Here is some content.</div>
								<div id="footer">© 2025 Example Inc.</div>
							

Here's the semantic version:


								<header>Welcome to our site</header>
								<main>Here is some content.</main>
								<footer>© 2025 Example Inc.</footer>
							

The second example uses HTML elements that describe the actual role of each section. Screen readers and search engines can interpret this more easily, and developers working with the code will understand the layout at a glance.

Content grouping

This example shows how to group related content using semantic elements. Here's the non-semantic version:


								<div class="faq">
									<div class="question">What is semantic HTML?</div>
									<div class="answer">It is HTML that carries meaning about the content.</div>
								</div>
							

And here is the semantic version using <section> and <h2> to organize the content:


								<section class="faq">
									<h2>What is semantic HTML?</h2>
									<p>It is HTML that carries meaning about the content.</p>
								</section>
							

Using <section> signals that this content forms a meaningful group, and <h2> creates a clear heading for both visual users and assistive technologies.

Common anti-patterns

Even with semantic tags available, it's easy to fall into habits that reduce clarity, accessibility, or maintainability. Here are a few common anti-patterns to avoid when working with HTML:

  • Using non-semantic containers for everything: Elements like <div> or <span> offer no meaning on their own. Relying on them for all structure and layout makes your code harder to read and less accessible to screen readers.
  • Wrapping content in extra tags, just in case: Avoid unnecessary nesting, like placing a <section> inside another <section> without clear purpose. Only group content semantically when it truly forms a unit of meaning.
  • Overusing semantic tags where they don't apply: Using <article> or <aside> for purely decorative or layout elements can confuse both developers and assistive technologies. Use each element according to its definition.
  • Applying ARIA roles redundantly: If an element already has an implicit role like <nav> or <main>, then it does not need its role defined. Overriding or duplicating roles can interfere with accessibility support.

Wrapping up

Semantic HTML is one of the simplest and most powerful tools in your web development toolkit. It improves accessibility, supports assistive technologies, boosts search engine visibility, and makes your code easier to read and maintain. All of this is possible using just standard HTML tags.

If you're building new pages or revisiting old ones, start by replacing generic tags with semantic elements where they make sense. Your future self (and your users) will thank you.