Skip to main content
Semantic HTML elements clearly describe their meaning to both the browser and the developer. They give structure and meaning to your content, improving SEO, accessibility, and code maintainability.

Why Semantic HTML?

Before HTML5, developers used generic <div> elements for everything:
<!-- Old way: Non-semantic -->
<div id="header">
  <div id="nav">...</div>
</div>
<div id="content">
  <div class="post">...</div>
</div>
<div id="sidebar">...</div>
<div id="footer">...</div>
HTML5 introduced semantic elements that give meaning:
<!-- Modern way: Semantic -->
<header>
  <nav>...</nav>
</header>
<main>
  <article>...</article>
</main>
<aside>...</aside>
<footer>...</footer>

Benefits of Semantic HTML

Better SEO

Search engines understand your content structure better, potentially improving rankings.

Accessibility

Screen readers navigate semantic landmarks more effectively, helping visually impaired users.

Maintainability

Code is more readable and easier to understand for developers.

Consistency

Standard elements create a common language among developers.

Main Semantic Elements

<header> - Page or Section Header

<header class="header" id="main-header">
  <div class="header__container">
    <!-- Logo -->
    <div class="header__logo">
      <a href="/" class="header__logo-link">
        <span class="header__logo-text">ML</span>
        <span class="header__logo-subtitle">Store</span>
      </a>
    </div>
    
    <!-- Navigation -->
    <nav class="header__nav">
      <ul class="header__nav-list">
        <li><a href="#">Home</a></li>
        <li><a href="#">Products</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
    </nav>
  </div>
</header>
Use <header> for:
  • Page header with logo and main navigation
  • Section headers within articles
  • Header area of any content block
Characteristics:
  • Can have multiple headers in a document (one per section/article)
  • Typically contains branding, navigation, search bars
  • Usually appears at the top but position isn’t required
A <header> doesn’t have to be at the page top. Articles and sections can have their own headers.
<nav class="header__nav">
  <ul class="header__nav-list">
    <li class="header__nav-item">
      <a href="#" class="header__nav-link">Crear cuenta</a>
    </li>
    <li class="header__nav-item">
      <a href="#" class="header__nav-link">Ingresar</a>
    </li>
    <li class="header__nav-item">
      <a href="#" class="header__nav-link">Mis compras</a>
    </li>
  </ul>
</nav>
Use <nav> for:
  • Primary navigation menu
  • Secondary navigation (categories, filters)
  • Breadcrumb navigation
  • Table of contents
Don’t use for:
  • Footer links (unless it’s a major navigation)
  • Social media links
  • Tags or keyword lists
A page can have multiple <nav> elements for different navigation contexts:
<!-- Main navigation -->
<header>
  <nav aria-label="Main navigation">
    <ul>
      <li><a href="/">Home</a></li>
      <li><a href="/products">Products</a></li>
      <li><a href="/about">About</a></li>
    </ul>
  </nav>
</header>

<!-- Secondary navigation -->
<nav aria-label="Categories" class="categories-nav">
  <ul>
    <li><a href="/electronics">Electronics</a></li>
    <li><a href="/clothing">Clothing</a></li>
    <li><a href="/books">Books</a></li>
  </ul>
</nav>

<!-- Breadcrumb navigation -->
<nav aria-label="Breadcrumb">
  <ol>
    <li><a href="/">Home</a></li>
    <li><a href="/products">Products</a></li>
    <li><a href="/products/laptops">Laptops</a></li>
  </ol>
</nav>
Use aria-label to distinguish between multiple navigation sections.

<main> - Primary Content

<main class="main" id="main-content">
  <section class="hero">
    <h1>Welcome to ML Store</h1>
    <p>Find the best products at the best prices</p>
  </section>
  
  <section class="products">
    <!-- Product catalog -->
  </section>
</main>
Use <main> for:
  • The dominant/primary content of the page
  • Content unique to this page (not repeated across pages)
Important rules:
  • Only ONE <main> per page
  • Excludes content repeated across pages (header, footer, navigation)
  • Helps screen readers jump directly to main content
  • Can be a direct child of <body> or nested in other elements
Never use more than one <main> element in a document. This is a hard rule for valid HTML.

<section> - Thematic Grouping

<section class="benefits" id="benefits-section">
  <div class="benefits__container">
    <h2 class="benefits__title">¿Por qué elegirnos?</h2>
    
    <div class="benefits__grid">
      <article class="benefits__item">
        <div class="benefits__icon">🚚</div>
        <h3 class="benefits__item-title">Envío gratis</h3>
        <p class="benefits__item-text">En compras mayores a $299</p>
      </article>
      
      <article class="benefits__item">
        <div class="benefits__icon">🔒</div>
        <h3 class="benefits__item-title">Pago seguro</h3>
        <p class="benefits__item-text">Todas las transacciones protegidas</p>
      </article>
    </div>
  </div>
</section>
Use <section> for:
  • Thematically related content
  • Chapters or tabbed content
  • Distinct parts of a page with their own heading
Characteristics:
  • Should generally have a heading (<h1>-<h6>)
  • Groups related content together
  • Has semantic meaning (unlike generic <div>)

<article> - Self-Contained Content

<article class="product-card">
  <figure class="product-card__figure">
    <img src="laptop.jpg" alt="Gaming Laptop" class="product-card__image" />
  </figure>
  <div class="product-card__content">
    <span class="product-card__category">Electronics</span>
    <h3 class="product-card__title">Gaming Laptop Pro</h3>
    <p class="product-card__price">$1,299.99</p>
    <button type="button" class="product-card__btn">
      Add to Cart
    </button>
  </div>
</article>
Use <article> for:
  • Blog posts
  • News articles
  • Product cards
  • Comments
  • Forum posts
  • Independent, self-contained content
Key question: Could this content be distributed independently (RSS feed, syndication)?
<section>: Thematic grouping of content
  • Part of a larger whole
  • Wouldn’t make sense on its own
  • Example: “Features” section on a landing page
<article>: Independent, self-contained content
  • Makes sense on its own
  • Could be syndicated or shared
  • Example: Blog post, product card, comment

<aside> - Complementary Content

<aside class="sidebar">
  <section class="sidebar__section">
    <h3>Related Products</h3>
    <ul>
      <li><a href="#">Wireless Mouse</a></li>
      <li><a href="#">USB-C Hub</a></li>
      <li><a href="#">Laptop Bag</a></li>
    </ul>
  </section>
  
  <section class="sidebar__section">
    <h3>Popular Categories</h3>
    <ul>
      <li><a href="#">Electronics</a></li>
      <li><a href="#">Fashion</a></li>
      <li><a href="#">Home & Garden</a></li>
    </ul>
  </section>
</aside>
Use <aside> for:
  • Sidebars
  • Pull quotes
  • Advertisements
  • Related links
  • Additional information
Characteristics:
  • Content related to surrounding content but not essential
  • Could be removed without affecting the main content’s meaning
  • Often positioned to the side visually (but not required)
<footer class="footer" id="main-footer">
  <div class="footer__container">
    <div class="footer__grid">
      <!-- About column -->
      <div class="footer__column">
        <h4 class="footer__column-title">Sobre ML Store</h4>
        <address class="footer__address">
          <p>Tu tienda de confianza desde 2024</p>
          <p>Contacto: [email protected]</p>
        </address>
      </div>
      
      <!-- Links column -->
      <div class="footer__column">
        <h4 class="footer__column-title">Enlaces útiles</h4>
        <ul class="footer__links">
          <li><a href="#" class="footer__link">Cómo comprar</a></li>
          <li><a href="#" class="footer__link">Métodos de pago</a></li>
          <li><a href="#" class="footer__link">Envíos</a></li>
        </ul>
      </div>
    </div>
    
    <hr class="footer__divider" />
    
    <div class="footer__bottom">
      <small class="footer__copyright">
        &copy; 2024 ML Store. Todos los derechos reservados.
      </small>
    </div>
  </div>
</footer>
Use <footer> for:
  • Page footer with copyright, legal links
  • Section or article footer
  • Author information
  • Related documents
Can contain:
  • Copyright information
  • Contact information (<address>)
  • Legal links (privacy policy, terms)
  • Social media links
  • Site map

Additional Semantic Elements

<figure> and <figcaption>

<figure class="product-card__figure">
  <img 
    src="laptop.jpg" 
    alt="Gaming Laptop with RGB keyboard" 
    class="product-card__image"
    loading="lazy"
  />
  <figcaption>Dell XPS 15 - High-performance laptop</figcaption>
</figure>
Use <figure> for:
  • Images with captions
  • Code snippets
  • Diagrams
  • Illustrations
  • Embedded content

<address>

<address class="footer__address">
  <p>ML Store Inc.</p>
  <p>123 Commerce Street</p>
  <p>San Francisco, CA 94103</p>
  <p>Email: <a href="mailto:[email protected]">[email protected]</a></p>
  <p>Phone: <a href="tel:+15551234567">+1 (555) 123-4567</a></p>
</address>
Use <address> for:
  • Contact information
  • Physical addresses
  • Email addresses
  • Phone numbers

<time>

<article class="blog-post">
  <h2>New Product Launch</h2>
  <p>
    Published on 
    <time datetime="2024-03-04T10:30:00Z">
      March 4, 2024 at 10:30 AM
    </time>
  </p>
</article>
Use <time> for:
  • Dates
  • Times
  • Durations

<mark>

<p>Search results for "laptop":</p>
<p>Gaming <mark>Laptop</mark> Pro - High-performance <mark>laptop</mark> for gamers</p>
Use <mark> for:
  • Highlighting text
  • Search result highlighting
  • Emphasizing relevant text

Complete Semantic Page Structure

Here’s how all semantic elements work together:
<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>ML Store | Tu Tienda Online</title>
</head>
<body>
  <header>
    <nav>
      <!-- Main navigation -->
    </nav>
  </header>
  
  <main>
    <section class="hero">
      <h1>Welcome</h1>
    </section>
    
    <section class="products">
      <h2>Products</h2>
      <article class="product-card">
        <figure>
          <img src="..." alt="..." />
          <figcaption>Product name</figcaption>
        </figure>
      </article>
    </section>
    
    <aside class="sidebar">
      <!-- Related content -->
    </aside>
  </main>
  
  <footer>
    <address>
      <!-- Contact info -->
    </address>
  </footer>
</body>
</html>

Best Practices

Do

  • Use semantic elements for their intended purpose
  • Include only one <main> per page
  • Give sections meaningful headings
  • Use <article> for independent content
  • Nest elements logically

Don't

  • Don’t use <section> when <div> is more appropriate
  • Don’t skip heading levels
  • Don’t use semantic elements just for styling
  • Don’t nest <main> inside <article> or <section>
  • Don’t use multiple <main> elements

Build docs developers (and LLMs) love