Semantic HTML is the practice of using HTML tags that describe the meaning and purpose of the content they enclose rather than their visual appearance. While generic tags like <div> and <span> provide no information about the data within them, semantic elements like <article>, <header>, and <nav> provide context for browsers, developers, and search engines.
Using these elements ensures that [a semantic Web allows data to be shared and reused across applications, enterprises, and communities] (W3Schools).
What is Semantic HTML?
A semantic element clearly describes its meaning to both the machine (browser or search crawler) and the human developer. In standard web development, many sites use non-semantic code such as <div id="nav"> or <div class="header">. Semantic HTML replaces these generic containers with specific tags like <nav> and <header> that describe their own role.
The corpus distinguishes between two types of elements:
* Non-semantic: Elements like <div> and <span> tell nothing about their content.
* Semantic: Elements like <img>, <table>, and <main> clearly define what they contain.
Why Semantic HTML matters
Implementing semantic markup directly impacts how a website performs in search results and how it functions for users with disabilities.
- Improved Search Rankings: [Search engines consider semantic contents as important keywords to influence a page’s search rankings] (MDN).
- Accessibility (AOM): [Assistive devices, such as screen readers, use the Accessibility Object Model (AOM) to parse and interpret content] (web.dev).
- Efficient Navigation: [Landmarks provide an easy way for users of assistive technology to understand programmatic structure and skip over content] (W3C WAI).
- Rich Results: Semantic elements can enhance schema markup, increasing the likelihood of appearing in search results with ratings, prices, or dates.
- Maintenance: Developers can understand the architecture of a page even without understanding the content, such as code in a foreign language.
Common Semantic Elements
Structural Elements
These tags define the primary layout and regions of a webpage.
* <header>: Contains introductory content, logos, or navigational sets. It cannot be nested within a <footer> or another <header>.
* <nav>: Reserved for major blocks of navigation links. Not all links on a page should be inside a <nav> element.
* <main>: Represents the primary content of the document. Use this tag only once per page.
* <section>: A thematic grouping of content, typically including a heading.
* <article>: Content that is independent and self-contained, such as blog posts, forum posts, or product cards.
* <aside>: Content tangentially related to the main content, often used as a sidebar.
* <footer>: Contains information like copyright, contact details, or sitemaps.
Textual and Media Elements
These tags convey the role of specific text or media data.
* <h1> to <h6>: Define a hierarchy of importance for headings.
* <figure> and <figcaption>: Group media like photos or diagrams with a descriptive caption.
* <time>: Specifically defines a date or time for machine processing.
* <mark>: Highlights text that is relevant to the current context.
Best practices
Choose elements based on meaning. Before coding, ask which element best represents the function of the markup. Use <button> for actions and <a> for navigation.
Nest tags logically. Maintain a hierarchical structure. For example, headings should generally reside inside <section> or <article> tags. While <article> can be inside <section> or vice versa, the choice should depend on which content is "independent."
Use the role attribute sparingly. The role attribute can turn a non-semantic element into a semantic one (e.g., <div role="navigation">). However, it is better to use the tag with the implicit role already built-in, such as <nav>.
Prioritize keyboard focus. Semantic interactive elements like <button> are automatically added to the document's tab sequence. If you use a non-semantic element for a button, you must manually program keyboard accessibility.
Common mistakes
Mistake: Using semantic tags for visual styling.
Fix: Use CSS to change font size or weight. Do not use <h1> just to make text large if it is not a top-level heading.
Mistake: Using <nav> for every link on the page.
Fix: Reserve <nav> only for the primary navigation blocks.
Mistake: Nesting <main> inside other structural landmarks.
Fix: Ensure <main> is not placed within <header>, <footer>, <article>, or <aside>.
Mistake: Forgetting accessible names for landmarks.
Fix: A <section> or <form> is not exposed as a landmark to assistive technology unless it has an accessible name, such as an aria-label.
Semantic HTML vs. Non-Semantic HTML
| Feature | Semantic HTML (<nav>, <article>) |
Non-Semantic HTML (<div>, <span>) |
|---|---|---|
| Meaning | Clearly describes content to browsers/search engines | Conveys no meaning about the content |
| Primary Use | Structure, SEO, Accessibility | Layout and general styling |
| SEO Impact | Helps crawlers identify relevant keywords | No direct impact on content identification |
| Accessibility | Automatically creates landmarks for screen readers | Requires manual ARIA roles for accessibility |
FAQ
Can I have more than one header or footer?
Yes. You can have multiple <header> and <footer> elements in one document. For example, an <article> can have its own header and footer distinct from the page-wide site header and footer.
What is the difference between <section> and <article>?
An <article> is intended to be independent and distributable on its own, like a news item or blog post. A <section> is a thematic grouping of content within a document, such as chapters or an introduction.
Why shouldn't I use <div> for everything?
While <div> and CSS can make a site look correct, it creates "div soup." This makes the code harder for developers to read and prevents search engines and screen readers from understanding which parts of the page are navigation, headers, or the main story.
Does semantic HTML replace CSS? No. HTML is for structure and meaning; CSS is for the realm of appearance. You should never choose a tag based on how it looks by default in a browser.
Do browsers automatically style semantic tags?
Most browsers use a "user agent stylesheet" that provides default styles, such as making an <h1> large. However, you should override these with your own CSS to match your design.