Tag semantici HTML5: guida completa con esempi

Come l’HTML semantico chiarisce la struttura della pagina a persone e macchine, dove migliora l’accessibilità e perché non è una scorciatoia per il ranking.

Prima di HTML5 il web era un mare di div e span con classi CSS come .header, .sidebar, .footer. I robot dei motori di ricerca e gli screen reader dovevano indovinare cosa fosse cosa. HTML5 ha introdotto i tag semantici — elementi che portano in sé un significato, indipendente dal CSS. Il tag <article> significa contenuto autonomo. Il tag <nav> significa navigazione. Il tag <aside> significa contenuto supplementare legato al contenuto principale ma non essenziale per capirlo.

Semantica ≠ stile. Un tag semantico descrive il ruolo di un elemento nel documento, non il suo aspetto. L’aspetto è compito del CSS. <section> e <div> sono visivamente indistinguibili senza stili — la differenza è che browser e motore di ricerca sanno di <section> cose che non possono sapere di <div>.

Tag strutturali della pagina

HTML5 ha introdotto un insieme di tag per marcare le grandi regioni della pagina. Formano lo scheletro del documento, che browser, motori di ricerca e tecnologie assistive possono percorrere senza leggere il CSS.

Diagramma visivo della struttura semantica della pagina HTML5.
<header>
Contenuto introduttivo del contesto di sezione più vicino — la pagina o una sezione. A livello di pagina: l’header del sito con logo, navigazione e ricerca. Dentro un <article>: il titolo, i metadati, l’autore. Più elementi <header> sono validi in una pagina se appartengono a sezioni diverse.
<nav>
Un blocco di link di navigazione. Non ogni insieme di link è <nav> — solo le principali vie di navigazione: menu principale, breadcrumb, paginazione. I link del footer verso la privacy policy non sono <nav>. Gli screen reader usano <nav> per una scorciatoia da tastiera verso la navigazione.
<main>
Il contenuto principale, unico nella pagina. Un solo <main> per documento. Il contenuto in <main> non deve ripetersi tra le pagine (header, footer e sidebar si ripetono, quindi stanno fuori da <main>). Gli screen reader saltano direttamente a <main> con una scorciatoia da tastiera.
<footer>
La sezione di chiusura del contesto di sezione più vicino. A livello di pagina: contatti, copyright, link. Dentro un <article>: informazioni sull’autore, tag, data di aggiornamento. Come <header>, può comparire in più sezioni.
<article>
Contenuto autonomo e distribuibile in modo indipendente: un articolo di blog, una notizia, un post su un forum, una scheda prodotto, un commento. Il test chiave: se togli l’<article> dal contesto e lo pubblichi da solo, ha senso? Se sì — è un <article>.
<section>
Una parte tematicamente coerente del documento senza un tag più specifico. Deve sempre avere un’intestazione (<h2>–<h6>). Se non c’è intestazione, probabilmente il tag giusto è <div>. Non usare <section> come sostituto stilizzato di <div>.
<aside>
Contenuto indirettamente legato al contenuto principale: box di approfondimento, sidebar, blocchi pubblicitari, biografie dell’autore, articoli correlati. Dentro un <article>: una nota o una citazione non essenziale per capire il testo principale. A livello di pagina: una colonna laterale.

Lo scheletro di base di qualunque pagina appare così — ed è già markup semanticamente corretto:

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Page title</title>
</head>
<body>

  <header>
    <a href="/"><img src="logo.svg" alt="Company name"></a>
    <nav aria-label="Main navigation">
      <ul>
        <li><a href="/blog">Blog</a></li>
        <li><a href="/services">Services</a></li>
        <li><a href="/contacts">Contacts</a></li>
      </ul>
    </nav>
  </header>

  <main>
    <!-- Unique page content -->
  </main>

  <footer>
    <p>&copy; 2026 Company name</p>
    <nav aria-label="Secondary navigation">
      <a href="/privacy">Privacy</a>
      <a href="/sitemap">Sitemap</a>
    </nav>
  </footer>

</body>
</html>

Tag di contenuto: article, section, h1–h6, p

I tag di livello strutturale definiscono le regioni della pagina. I tag di livello contenuto descrivono la natura del contenuto stesso. Vediamo la combinazione presente in ogni pagina di blog.

html
<!-- Blog post page -->
<main>

  <article>
    <header>
      <h1>How to choose the right HTML tag</h1>
      <p>Published: <time datetime="2026-05-22">22 May 2026</time></p>
      <address>
        By: <a rel="author" href="/authors/jane">Jane Doe</a>
      </address>
    </header>

    <section>
      <h2>Why semantics matters</h2>
      <p>Section text...</p>
    </section>

    <section>
      <h2>Main tags</h2>
      <p>Section text...</p>

      <aside>
        <p>Note: the HTML Living Standard is continuously updated.</p>
      </aside>
    </section>

    <footer>
      <p>Tags: <a href="/tags/html">#html</a>, <a href="/tags/seo">#seo</a></p>
    </footer>
  </article>

  <!-- Related articles -->
  <aside aria-label="Related articles">
    <h2>Also read</h2>
    <ul>
      <li><a href="/blog/heading-structure">Heading structure</a></li>
      <li><a href="/blog/schema-org-json-ld">Schema.org markup</a></li>
    </ul>
  </aside>

</main>
Nota: <header> e <footer> dentro un <article> non sono la stessa cosa dei <header> e <footer> a livello di pagina. Sono contesti di sezione separati. I robot dei motori di ricerca capiscono questa distinzione e attribuiscono correttamente titolo, data e autore all’articolo specifico, non al sito nel suo insieme.

Quando usare section e quando div

La regola è semplice: se un blocco ha un nome semantico, usa <section>. Se esiste solo per lo stile o come hook JavaScript, usa <div>.

html
<!-- CORRECT: section with a heading -->
<section>
  <h2>Product benefits</h2>
  <ul>
    <li>Fast delivery</li>
    <li>2-year warranty</li>
  </ul>
</section>

<!-- CORRECT: div for styling -->
<div class="cards-grid">
  <article>...</article>
  <article>...</article>
  <article>...</article>
</div>

<!-- WRONG: section with no heading -->
<section class="cards-grid">
  <article>...</article>
</section>

<!-- WRONG: div where content has meaning -->
<div id="about">
  <!-- The About section — this should be <section> -->
  <h2>About us</h2>
  <p>...</p>
</div>

Tag per media, dati e utilità

HTML5 ha aggiunto tag per tipi di dati specifici — danno ai motori di ricerca segnali aggiuntivi senza bisogno del markup Schema.org.

<figure> e <figcaption>

Contenuto media autonomo con didascalia. Immagini, diagrammi, tabelle, frammenti di codice — tutto ciò che è legato al testo principale e potrebbe essere spostato o messo in appendice senza perdere significato. <figcaption> è la didascalia ufficiale di un <figure>. Google usa <figcaption> come descrizione supplementare dell’immagine nell’analisi.

<time>

Una data o un'ora leggibili dalla macchina. L'attributo datetime in formato ISO 8601 permette al motore di ricerca di determinare con precisione la data di pubblicazione o dell'evento, indipendentemente da come la data è mostrata all'utente. Google raccomanda esplicitamente di usare <time> per le date degli articoli nei dati strutturati Article.

<address>

Informazioni di contatto per l’<article> più vicino o per l’intero documento. Dentro un <article>: i contatti dell’autore. A livello di pagina: i contatti dell’organizzazione. Non usare <address> per indirizzi postali fuori dal contesto di contatti di autore o organizzazione.

<details> e <summary>

Un widget richiudibile nativo, senza JavaScript. <summary> è l’intestazione visibile. <details> contiene il contenuto nascosto. Il browser gestisce apertura e chiusura automaticamente. I motori di ricerca indicizzano il contenuto dentro <details> anche quando è chiuso. Perfetto per FAQ e spoiler.

<mark>

Evidenzia un testo come pertinente nel contesto corrente — per esempio i risultati di ricerca o le keyword in una citazione. Non confondere con <strong> (importanza) ed <em> (enfasi). <mark> significa «segnalato come pertinente», non «importante» o «evidenziato per decorazione».

<data> e <output>

<data value="42">Quarantadue</data> collega un testo leggibile dalle persone a un valore leggibile dalla macchina. <output> rappresenta il risultato di un calcolo o di un’azione dell’utente. Entrambi i tag sono rari sui siti di contenuti ma essenziali nelle web app con form e calcolatori.

Esempio di markup per il tag <figure> con didascalia:
html
<!-- figure + figcaption for an image -->
<figure>
  <img
    src="/images/html5-structure.webp"
    alt="Diagram of the semantic structure of an HTML5 page"
    width="800" height="450"
  >
  <figcaption>Fig. 1 — Typical semantic structure of an HTML5 document</figcaption>
</figure>

<!-- figure + figcaption for code -->
<figure>
  <pre><code class="language-html">&lt;article&gt;...&lt;/article&gt;</code></pre>
  <figcaption>Example: minimal article markup</figcaption>
</figure>

<!-- time with datetime attribute -->
<p>
  Article updated:
  <time datetime="2026-05-22T10:30:00+03:00">22 May 2026</time>
</p>

<!-- details + summary (FAQ without JS) -->
<details>
  <summary>What is semantic HTML?</summary>
  <p>Markup where each tag conveys the meaning of the content,
     not just its visual appearance.</p>
</details>

<!-- mark for search highlighting -->
<p>Results for "<mark>semantic tags</mark>" — 42 articles</p>

Annidamento e combinazioni: esempi concreti

La forza semantica di HTML5 si rivela non nei singoli tag ma nella loro corretta combinazione. Vediamo architetture di pagina tipiche.

Pagina di elenco del blog

html
<main>
  <header>
    <h1>SEO blog</h1>
    <p>Practical articles on website promotion</p>
  </header>

  <!-- Article list — each card is an article -->
  <section aria-label="Article list">
    <article>
      <header>
        <h2><a href="/blog/semantic-html5">HTML5 semantic tags</a></h2>
        <p>
          <time datetime="2026-05-22">22 May 2026</time>
          · <span>18 min read</span>
        </p>
      </header>
      <p>HTML5 semantic tags are the foundation of correct page markup...</p>
      <footer>
        <a href="/blog/semantic-html5">Read more</a>
      </footer>
    </article>

    <article>
      <header>
        <h2><a href="/blog/heading-structure">Heading structure</a></h2>
        <p>
          <time datetime="2026-04-10">10 April 2026</time>
          · <span>12 min read</span>
        </p>
      </header>
      <p>One H1 per page. H2 divides content into sections...</p>
      <footer>
        <a href="/blog/heading-structure">Read more</a>
      </footer>
    </article>
  </section>

  <!-- Pagination -->
  <nav aria-label="Pagination">
    <a href="?page=1" aria-current="page">1</a>
    <a href="?page=2">2</a>
    <a href="?page=3">3</a>
  </nav>
</main>

Scheda prodotto con recensioni

html
<main>
  <article itemscope itemtype="https://schema.org/Product">

    <!-- Product main area -->
    <header>
      <h1 itemprop="name">SoundMax Pro Wireless Headphones</h1>
      <p itemprop="description">40 hours of battery life, active noise cancellation...</p>
    </header>

    <!-- Product image -->
    <figure>
      <img
        src="/products/soundmax-pro.webp"
        alt="SoundMax Pro wireless headphones — front view"
        itemprop="image"
        width="600" height="600"
      >
      <figcaption>SoundMax Pro in three colors: black, white, blue</figcaption>
    </figure>

    <!-- Price -->
    <section aria-label="Price and purchase">
      <p>
        <data value="129" itemprop="price">$129</data>
      </p>
      <button type="button">Add to cart</button>
    </section>

    <!-- Specs -->
    <section>
      <h2>Specifications</h2>
      <dl>
        <dt>Battery life</dt><dd>40 hours</dd>
        <dt>Connection</dt><dd>Bluetooth 5.3</dd>
        <dt>Weight</dt><dd>250 g</dd>
      </dl>
    </section>

    <!-- Reviews — each review is an article inside article -->
    <section aria-label="Customer reviews">
      <h2>Reviews</h2>

      <article>
        <header>
          <strong>Anna K.</strong>
          <time datetime="2026-04-15">15 April 2026</time>
        </header>
        <p>Excellent headphones, clean sound. The noise cancellation works brilliantly.</p>
      </article>

      <article>
        <header>
          <strong>Michael R.</strong>
          <time datetime="2026-03-28">28 March 2026</time>
        </header>
        <p>The 40-hour claim is real. Took them on a business trip and they lasted the week.</p>
      </article>
    </section>

  </article>
</main>

Landing page con sezioni e sidebar

html
<body>
  <header>
    <nav aria-label="Main navigation">
      <!-- logo + menu -->
    </nav>
  </header>

  <main>
    <!-- Hero section -->
    <section aria-labelledby="hero-title">
      <h1 id="hero-title">SEO promotion for your business</h1>
      <p>We grow organic traffic with guaranteed results</p>
      <a href="#contacts" role="button">Get a free audit</a>
    </section>

    <!-- Services -->
    <section>
      <h2>Our services</h2>
      <ul role="list">
        <li>
          <article>
            <h3>Technical audit</h3>
            <p>Full technical health check of your site...</p>
          </article>
        </li>
        <li>
          <article>
            <h3>Content strategy</h3>
            <p>Keyword universe and content calendar...</p>
          </article>
        </li>
      </ul>
    </section>

    <!-- Main content + sidebar -->
    <div class="layout-two-col">
      <section>
        <h2>Case studies</h2>
        <!-- ... -->
      </section>

      <aside aria-label="Contact us">
        <h2>Get in touch</h2>
        <address>
          <p>Email: <a href="mailto:hello@example.com">hello@example.com</a></p>
          <p>Telegram: <a href="https://t.me/yourchannel">@yourchannel</a></p>
        </address>
      </aside>
    </div>
  </main>

  <footer>
    <nav aria-label="Site map">
      <ul>
        <li><a href="/blog">Blog</a></li>
        <li><a href="/glossary">Glossary</a></li>
      </ul>
    </nav>
    <p><small>&copy; 2026 example.com</small></p>
  </footer>
</body>
Nell'esempio della landing page usiamo aria-labelledby per collegare una sezione alla sua intestazione tramite id. Lo screen reader può così annunciare correttamente il nome della sezione anche quando l'intestazione è stilizzata in modo non convenzionale. È una buona pratica per tutti gli elementi <section> e <nav> il cui nome non è ovvio dalla sola struttura.
html
<!-- Multiple <nav> elements are fine — distinguish them with aria-label -->

<!-- Breadcrumbs -->
<nav aria-label="Breadcrumbs">
  <ol>
    <li><a href="/">Home</a></li>
    <li><a href="/blog">Blog</a></li>
    <li aria-current="page">HTML5 semantic tags</li>
  </ol>
</nav>

<!-- Main navigation inside <header> -->
<nav aria-label="Main navigation">
  <ul>
    <li><a href="/blog" aria-current="page">Blog</a></li>
    <li><a href="/services">Services</a></li>
  </ul>
</nav>

<!-- Pagination at the end of a listing -->
<nav aria-label="Blog pages">
  <a href="?page=1" rel="prev" aria-label="Previous page">←</a>
  <a href="?page=1">1</a>
  <span aria-current="page">2</span>
  <a href="?page=3">3</a>
  <a href="?page=3" rel="next" aria-label="Next page">→</a>
</nav>

<!-- In-page table of contents -->
<nav aria-label="Article contents">
  <ol>
    <li><a href="#structural-tags">Structural tags</a></li>
    <li><a href="#content-tags">Content tags</a></li>
    <li><a href="#nesting-examples">Nesting examples</a></li>
  </ol>
</nav>

Impatto SEO: cosa riceve davvero il motore di ricerca

Il markup semantico incide direttamente su come Googlebot capisce, indicizza e presenta una pagina nei risultati di ricerca. Ecco i meccanismi specifici.

Identificare il contenuto principale

Google usa <main> per identificare il contenuto primario di una pagina. Il contenuto in header, footer e <aside> riceve meno peso nel posizionamento. Se tutto il testo sta dentro <div class="main">, Google spende risorse extra per capire la struttura.

Attribuzione di data e autore

<time datetime="2026-05-22"> dà a Google una data di pubblicazione precisa, che influenza la valutazione di freschezza. <address> con rel="author" collega l’articolo all’autore. Entrambi i segnali alimentano la generazione dei rich snippet nei risultati di ricerca.

Rich result

Il contenuto di <details> + <summary> è indicizzato da Google e può comparire come blocco espandibile nei risultati (People Also Ask). <figure> + <figcaption> influenzano l’indicizzazione delle immagini e il loro aspetto in Google Immagini.

Link interni

I link dentro <nav> portano un contesto navigazionale. I link dentro <article> portano un contesto di contenuto. Googlebot considera la posizione del link nella pagina nel valutarne il peso. Un link dal corpo principale di un <article> vale più di un link da un <aside>.

Schema.org (JSON-LD) e i tag semantici HTML5 sono strumenti complementari, non concorrenti. La semantica definisce la struttura del documento. Schema.org aggiunge dati leggibili dalla macchina su tipo di contenuto, entità e proprietà. Insieme danno a Google il quadro completo della pagina.

Errori comuni nel markup semantico

La maggior parte degli errori nasce dall'abitudine al div o dal fraintendimento dello scopo reale di un tag.

html
<!-- MISTAKE 1: <section> instead of <div> for styling -->
<section class="flex-wrapper">  <!-- no heading = not section -->
  <img src="photo.jpg" alt="">
</section>
<!-- CORRECT -->
<div class="flex-wrapper">
  <img src="photo.jpg" alt="Photo description">
</div>

<!-- MISTAKE 2: <article> for a card without standalone meaning -->
<article class="feature-card">
  <span class="icon">⚡</span>
  <h3>Fast delivery</h3>
</article>
<!-- CORRECT: a benefits card is li or div, not article -->
<li class="feature-card">
  <span class="icon" aria-hidden="true">⚡</span>
  <h3>Fast delivery</h3>
</li>

<!-- MISTAKE 3: <header> as a synonym for <div class="header"> -->
<header class="section-header">
  <h2>Our advantages</h2>
</header>
<!-- CORRECT: use <header> only when a section has an introductory group -->
<section>
  <h2>Our advantages</h2>  <!-- h2 directly, no header wrapper -->
  ...
</section>

<!-- MISTAKE 4: two <main> elements -->
<main>Primary content</main>
<main>Also important content</main>  <!-- invalid! -->
<!-- CORRECT: one <main>, supplementary content in <aside> -->
<main>Primary content</main>
<aside>Supplementary content</aside>

<!-- MISTAKE 5: <address> for an office address in body text -->
<address>1 High Street, London</address>  <!-- not in an author/org context -->
<!-- CORRECT -->
<p>Office address: 1 High Street, London</p>
<!-- or in footer as site contact information: -->
<footer>
  <address>
    <a href="mailto:hello@company.com">hello@company.com</a>
  </address>
</footer>
L’errore più comune è usare <section> come nome elegante per un blocco wrapper senza valore semantico. Test rapido: se puoi sostituire <section> con <div> senza che cambi nulla in termini di significato — il tag corretto è <div>.

Un altro problema frequente è l’attributo alt mancante o vuoto. Le immagini dentro <figure> devono avere un alt significativo oppure alt="" (se l’immagine è decorativa e descritta dal <figcaption>). Non omettere mai del tutto l’attributo alt — viola gli standard di accessibilità e la validazione HTML.

html
<!-- Decorative image: empty alt, figcaption describes it -->
<figure>
  <img src="chart.png" alt="" role="presentation">
  <figcaption>Organic traffic growth over 6 months: +340%</figcaption>
</figure>

<!-- Informative image: full alt text -->
<figure>
  <img
    src="html5-tags-map.png"
    alt="Map of HTML5 semantic tags: header, nav, main, article, section, aside, footer"
  >
  <figcaption>Fig. 2 — Complete map of HTML5 semantic elements</figcaption>
</figure>

<!-- Mistake: no alt at all -->
<img src="diagram.png">  <!-- invalid! -->

FAQ

Il markup semantico influenza direttamente il posizionamento su Google?
Non esiste un «bonus semantica» diretto. Ma la semantica incide indirettamente sul posizionamento: Google estrae il contenuto principale con più precisione (migliorando l’accuratezza della corrispondenza con la query), attribuisce correttamente data e autore (segnali E-E-A-T) e il contenuto in <main> riceve più peso di quelle stesse parole in header o footer. La semantica corretta è anche un prerequisito per la maggior parte dei tipi di dati strutturati.
Si può annidare <article> dentro <article>?
Sì, ed è corretto. L’esempio classico: una scheda prodotto (<article>) contiene una sezione recensioni in cui ogni recensione è a sua volta un <article>. Oppure un articolo di blog (<article>) include un post dei social (<article>). L’<article> annidato significa che l’elemento interno è un contenuto autonomo legato a quello esterno.
Come differisce <strong> da <b>, ed <em> da <i>?
<strong> marca un contenuto come importante (gli screen reader aggiungono enfasi). <b> è il grassetto stilistico, senza semantica di importanza. <em> aggiunge un’enfasi verbale che cambia il significato (come l’enfasi parlata: «non ho detto che lui l’ha rubata»). <i> è il corsivo senza enfasi: termini tecnici, forestierismi, titoli. La differenza SEO è minima; quella di accessibilità è significativa.
Serve role="main" insieme al tag <main>?
No. Il tag <main> ha già il ruolo ARIA implicito «main». Aggiungere role="main" è ridondante. Lo stesso vale per <nav> (role navigation), <header> a livello di pagina (role banner) e <footer> (role contentinfo). Duplicare tag e ruolo crea confusione nell’albero di accessibilità.
E le single-page application (SPA) in React o Vue?
La semantica conta il doppio. Dato che le SPA generano l’HTML dinamicamente, crawler e screen reader ricevono la struttura solo dal rendering JavaScript. Assicurati che al cambio di rotta si aggiorni il <title>, che il focus si sposti su <main> e che la struttura semantica di ogni «pagina» sia riprodotta correttamente. React e Vue non impediscono il markup semantico — è una questione di disciplina del team.

Check it with SpiderHead

Free and local: run the audit on your own machine.

Try it