Frontend

Creare un layout semanticamente corretto con HTML

Autore

Manuel Ricci

Quando guardiamo un sito web comprendiamo subito le sue sezioni grazie al modo in cui sono organizzati gli elementi. Vero che con gli stili dati da CSS tutto è molto più chiaro, ma per poter creare layout accattivanti stilisticamente bisogna innanzitutto creare un HTML coi contro fiocchi.

In questo approfondimento vedremo quindi i principali tag che servono a creare il layout di un documento HTML e per ognuno andrò ad approfondire anche l’aspetto semantico.

Intestazione di un documento HTML: il tag header

<header> rappresenta del contenuto introduttivo, potrebbe contenere intestazioni, immagini (es. logo), navigazione, form di ricerca, nome dell’autore o altri elementi.

Questo perché <header> è un elemento che può essere usato in diversi punti del layout.

Il suo impiego principale è come header globale del sito, ma nulla ci vieta di usarlo anche come header del contenuto di una pagina (es. articolo di un blog).

Dal punto di vista dell’accessibilità, in base a dove si trova, <header> cambia il suo ruolo. Se discende da body allora esso sarà banner, mentre invece se dovesse discendere da tag come <article>, <aside>, <nav> o <section> allora non avrà alcun tipo di ruolo.

banner è il ruolo che indica l’header globale di un sito web. Inoltre, banner è una sottoclasse di un ruolo più ampio e astratto che è landmark. Questo definisce un’area molto importante del sito e che l’utente può avere interesse nel navigare.

1<header>
2      <img src="images/bolt.svg" width="64" alt="logo del sito" />
3</header>

<nav> rappresenta una sezione della pagina il cui scopo è quello di fornire dei link di navigazione, sia interni che esterni. Menu e indici sono un classico esempio di <nav>.

<nav> ha ruolo navigation, un’altra sottoclasse di landmark, definizione di un’area del sito dove sono presenti link di navigazione.

Inoltre, qualora in pagina ci fossero <nav> multipli è possibile aiutare gli screen reader a distinguerli grazie all’uso dell’attributo aria-label, in questo modo sarà possibile distinguerlo grazie al nome che gli verrà assegnato.

1<header>
2   <img src="images/bolt.svg" width="64" alt="logo del sito" />
3   <nav aria-label="principale">
4      <ul>
5         <li><a href="/index.html">Home</a></li>
6         <li><a href="/contatti.html">Contatti</a></li>
7         <li><a href="/layout.html">Layout</a></li>
8      </ul>
9   </nav>
10</header>

Alcune cose da tenere a mente quando si usa aria-label:

  • usare label diverse per <nav> diversi
  • usare la stessa label se il contenuto dei <nav> è identico (es. navigazione in header e footer identica, allora si usa lo stesso nome)
  • evitare label ridondanti (es. navigazione principale) gli screen reader leggerebbero due volte la stessa cosa, bisogna rimanere concisi.

Il contenuto principale: il tag main

<main> rappresenta il contenuto dominante del corpo del documento.

Il contenuto di main è pensato per essere unico, contenuti che si ripetono tra più documenti è meglio inserirli all’interno di altri elementi come aside, header o footer.

Come gli altri tag che stiamo osservando e che osserveremo, anche main è un tag strettamente informativo, ciò significa che non influenza il modo in cui gli elementi vengono rappresentati nel documento. In altre parole, non li vediamo come vediamo un heading (h1-h6) o un listato.

<main> ha ruolo main ed è una sottoclasse di landmark. Questo ruolo indica il contenuto principale di un documento.

Alcune cose da tenere a mente:

  • Usa un solo <main> per documento
  • Dare un ID a <main> per creare un link per permettere agli utenti con disabilità motorie di raggiungere con facilità il contenuto principale.

Su quest’ultimo punto bisogna considerare che ci sono persone che navigano il web senza l’ausilio del mouse, usano dei bastoncini con una gomma che tengono in bocca e fanno un intenso uso del pulsante TAB.

Ipotizzando la struttura vista negli esempi precedenti prima di raggiungere il contenuto principale devono pigiare il TAB tre volte per superare i link di navigazione, ma come consigliato possiamo prevedere un ancoraggio subito dopo l’apertura di <body> per aiutarli a raggiungere con più facilità la zona d’interesse. L’implementazione è questa:

1<body>
2   <a href="#main-content">Salta al contenuto principale</a>
3   <header>
4      <img src="images/bolt.svg" width="64" alt="logo del sito" />
5      <nav aria-label="principale">
6         <ul>
7            <li><a href="/index.html">Home</a></li>
8            <li><a href="/contatti.html">Contatti</a></li>
9            <li><a href="/layout.html">Layout</a></li>
10         </ul>
11      </nav>
12   </header>
13   <main id=”main-content”></main>
14</body>

Il link possiamo nasconderlo poi con CSS e renderlo visibile solo all’occorrenza.

Qual è la differenza tra article e section?

<article> e <section> li prendo in coppia perché vengono molto spesso confusi, in realtà non c’è niente di male perché come vedremo tra poco si possono usare tranquillamente uno al posto dell’altro, ma attenzione: non sono uguali, hanno scopi differenti.

Partiamo quindi da <article> il quale rappresenta una composizione autonoma che può essere riutilizzata o distribuita in maniera indipendente. Per dirla in maniera più semplice: viene usato per post di un blog, notizia, scheda prodotto, un commento, un widget interattivo (es. il meteo della tua città) o in ogni caso un elemento indipendente del contenuto, dove per indipendente s’intende che se viene estratto dal suo contesto è ancora comprensibile il suo scopo.

Di conseguenza va da sé che in un documento HTML ci possono più <article>.

Dal punto di vista dell’accessibilità <article> ha ruolo article il quale indica una sezione indipendente del documento. In questo caso non abbiamo a che fare con una sottoclasse di landmark.

<article> può essere tranquillamente annidato in altri <article>. Il figlio verrà relazionato al genitore, come ad esempio può succedere per un post di un blog e l’elenco dei commenti.

Anche qui ci sono cose da tenere a mente:

  • Ogni articolo dovrebbe essere identificabile, ad esempio attraverso un heading (h1-h6)
  • L’autore di un articolo può essere correlato ad esso grazie all’uso del tag <address>
  • La data e l’ora di pubblicazione possono essere descritte con l’uso di <time> e il suo attributo datetime.

Mentre per quanto riguarda <section>, esso rappresenta una sezione generica del documento che non ha un elemento semantico più specifico per rappresentarla. <section> dovrebbe avere sempre un heading, a parte qualche eccezione.

Di alternative semantiche al giorno d’oggi ne abbiamo a bizzeffe, ad esempio:

  • Se il contenuto può essere considerato indipendente usiamo <article>
  • Se il contenuto rappresenta delle informazioni correlate al contenuto principale usiamo <aside>
  • Se il contenuto rappresenta il contenuto principale usiamo <main>
  • Se usi l’elemento solo per scopi stilistici usiamo <div>
  • Se il contenuto è un menu che permette di navigare il sito usiamo <nav>

Se nessuna casistica si applica, allora possiamo usare <section>.

Dal punto di vista dell’accessibilità <section> ha ruolo region se etichettata con aria-label o aria-labelledby, altrimenti non ha alcun ruolo.

region permette di indicare aree del documento che l’autore ritiene importanti. Si tratta di una sottoclasse di landmark generica.

L’etichettatura di <section> deve essere usata con parsimonia. region è un landmark, per cui deve essere usato con parsimonia, troppi landmark rendono difficoltoso comprendere il documento con gli screen reader.

Se non ci fossero landmark più specifici, allora possiamo etichettare <section> come meglio crediamo.

Ma quindi quale devo usare tra article e section?

A vederli sembrano identici, a leggerne la spiegazione sono diversi, ma quindi come si usano? Ricorda questo:

  • <section>: può essere usato per raccogliere articoli in categorie differenti, ma può anche definire sezioni interne dell’articolo.
  • <article>: può essere usato per contenere pezzi di contenuto indipendente (es. blog post, video, immagini o news)

Ciò significa che possiamo usare <section> per raggruppare <article> e possiamo dividere <article> in sezioni differenti con l’ausilio di <section>.

1<section class="posts caterogia-1">
2      <article class="post">
3        <h2>Titolo dell'articolo 1</h2>
4        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Iure a, voluptatibus nihil error eveniet, reiciendis
5          aut officiis suscipit, expedita dolores dicta voluptatum maxime? Porro saepe consequatur voluptas delectus ex
6          eveniet?</p>
7        <a href="/article.html">Continua a leggere</a>
8      </article>
9      <article class="post">
10        <h2>Titolo dell'articolo 2</h2>
11        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Iure a, voluptatibus nihil error eveniet, reiciendis
12          aut officiis suscipit, expedita dolores dicta voluptatum maxime? Porro saepe consequatur voluptas delectus ex
13          eveniet?</p>
14        <a href="#">Continua a leggere</a>
15      </article>
16</section>

Oppure

1<article>
2      <header>
3        <h1>Titolo del mio articolo 1</h1>
4        <p>Manuel Ricci</p>
5        Pubblicato il: <time datetime="2023-09-14T21:43:00">14/09/2023 alle 21:43</time>
6      </header>
7      <section aria-labelledby="intro">
8        <h2 id="intro">Introduzione</h2>
9      </section>
10      <section aria-labelledby="demo">
11        <h2 id="demo">Demo</h2>
12        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facilis facere velit illum sunt et, aspernatur ipsum earum quibusdam ratione, adipisci nihil ut explicabo accusantium cupiditate neque aut architecto maiores quod.
13        Quasi ea et, neque corporis iusto, labore porro reiciendis est tempore fuga aliquid perferendis consectetur. A fugiat rem nam, vero dolor corporis qui, vitae, tempore doloremque sit praesentium expedita autem!
14        Nostrum harum explicabo voluptatibus ut consequuntur rerum animi dolor id. Deserunt, dicta sequi maxime expedita, numquam laboriosam est ipsum mollitia sit excepturi eveniet, totam corporis enim. Assumenda laboriosam necessitatibus quidem.
15        Itaque iure unde libero labore odio cumque modi quis repudiandae quasi magnam qui eum nam suscipit consectetur beatae dolore a reiciendis, porro velit. Qui atque aspernatur repudiandae, commodi ut aut?</p>
16      </section>
17</article>

Notare che in questo esempio ho usato due aria-labeledby per creare due landmark interni ad <article>.

Contenuto indirettamente correlato al principale con aside

<aside> rappresenta una porzione del documento il cui contenuto è indirettamente correlato con il contenuto principale. <aside> è utile quindi per creare sidebar o parti del contenuto indirettamente correlate a quello presente nel flusso principale.

Per quanto riguarda la sidebar può contenere, ad esempio, elementi come articoli correlati, link ad altre categorie o gli ultimi commenti pubblicati. Mentre per quanto riguarda il contenuto indirettamente correlato possiamo pensare alla scheda di un film, ad esempio Jumanji, quello del 1995 con Robin Williams. Il contenuto di un aside potrebbe essere una cosa simile a questa

1<aside>
2   <p>Nel 2017 c’è stato un reboot con protagonista The Rock, il quale ha poi girato anche un sequel, Jumanji: The Next Level nel 2019.</p>
3</aside>

Dal punto di vista dell’accessibilità <aside> ha ruolo complementary, un’altra sottoclasse di landmark. complementary indica una sezione a supporto del contenuto principale.

Cose da tenere a mente:

  • usare aria-label o aria-labelledby per contrassegnare landmark (aside) multipli
  • evitare label ridondanti
1<main id=”main-content”>...</main>
2<aside>
3    <section>
4      <h2>Articoli correlati</h2>
5      <nav aria-label="articoli correlati">
6        <ul>
7          <li><a href="#">Articolo 1</a></li>
8          <li><a href="#">Articolo 2</a></li>
9          <li><a href="#">Articolo 3</a></li>
10          <li><a href="#">Articolo 4</a></li>
11        </ul>
12      </nav>
13    </section>
14  </aside>

Notare che ho usato aria–label su <nav> per distinguere questa navigazione rispetto a quella dell’header.

Il pié di pagina

Siamo giunti in fondo al nostro documento e l’elemento che ci si aspetta qui è <footer> il quale rappresenta proprio il pié di pagina di una sezione o del documento, ciò dipende dalla discendenza.

Il footer, tipicamente, può contenere informazioni circa l’autore, copyright o vari link.

<footer> ha ruolo contentinfo se discende da body, altrimenti non ha ruolo specifico. contentinfo definisce il footer, quindi quella parte del documento che contiene informazioni come copyright, link di navigazione, privacy e che si trova in ogni documento.

Cose da tenere a mente:

  • non annidare più footer per creare un mega footer, contentinfo è un landmark quindi occhio
  • dovrebbe esserci solo un contentinfo per pagina (stesso discorso del punto precedente)
  • nel caso di footer multipli etichettarli con aria-label
  • evitare label ridondanti
1<header>...</header>
2<main>
3   <section>
4      <footer aria-label="autore articolo">
5         <address>L'autore di questo contenuto è Ricci Manuel, contattalo se vuoi ulteriori informazioni all'indirizzo info@manuelricci.com</address>
6      </footer>
7   </section>
8</main>
9<aside>...</aside>
10<footer aria-label="footer">
11    &copy; 2023 - Manuel Ricci
12    <nav aria-label="principale">
13      <ul>
14        <li><a href="/index.html">Home</a></li>
15        <li><a href="/contatti.html">Contatti</a></li>
16        <li><a href="/layout.html">Layout</a></li>
17      </ul>
18    </nav>
19  </footer>

Dei due solo il secondo footer ha ruolo contentinfo perché discende da body.

L’elemento più versatile di tutti

<div> elemento più versatile di HTML, non è semantico, ciò significa che non rappresenta nulla.

La specifica di HTML 3 lo descrive così:

L’elemento DIV…rappresenta contenitori di diverso tipo, es. capitoli, sezioni, abstract o appendici.

Mentre quella di HTML 5:

L'elemento div non ha alcun significato speciale. Rappresenta i suoi figli. Può essere utilizzato con gli attributi class, lang e title per contrassegnare la semantica comune a un gruppo di elementi consecutivi. Può anche essere utilizzato in un elemento dl, avvolgendo gruppi di elementi dt e dd.

Non solo, sempre la specifica dice:

Gli autori sono caldamente incoraggiati a vedere l'elemento div come elemento di ultima di ultima istanza, per quando nessun altro elemento è adatto. L'uso di elementi più appropriati invece dell'elemento div porta a una migliore accessibilità per I lettori e una più facile manutenibilità per gli autori.

Abbastanza chiaro quindi il ruolo di div nel web di oggi e proprio in tema di ruoli, ARIA gli assegna un role generic.

Il ruolo generico ARIA lo definisce come: un contenitore senza nome che non ha nessun valore semantico di per sé.

Ma quindi si usa <div>?

Certo! Essendo un elemento generico lo possiamo usare per scopi anche solo prettamente stilistici, assegnandogli una classe o un ID e con un po’ di CSS si possono fare miracoli.

<div> comunque non è da solo, ci sono altri elementi come lui che possono darci una mano, come ad esempio <span>.

La differenza tra questi due è che <div> si comporta come fa un <h1> occupa tutto lo spazio orizzontale a disposizione mandando a capo tutto il resto, mentre <span> si comporta come un <i></i> non manda a capo niente e si integra nel flusso.

Si dice quindi che <div> è un elemento di blocco, mentre <span> è un elemento in linea.

Infine, il ruolo di <div>, generic, ce l’ha anche un altro elemento HTML molto importante, <body>.

Considera che noi potremmo scrivere anche un layout in questo modo:

1<div role="banner" class="header"></div>
2<div role="main" class="main"></div>
3<div role="complementary" class="sidebar"></div>
4<div role="contentinfo" class="footer"></div>

Non c’è niente di sbagliato, ma è sempre meglio usare le alternative semantiche viste finora. Sono più chiare e ci permettono di scrivere di meno.

Caricamento...

Diventiamo amici di penna? ✒️

Iscriviti alla newsletter per ricevere una mail ogni paio di settimane con le ultime novità, gli ultimi approfondimenti e gli ultimi corsi gratuiti puubblicati. Ogni tanto potrei scrivere qualcosa di commerciale, ma solo se mi autorizzi, altrimenti non ti disturberò oltre.

Se non ti piace la newsletter ti ricordo la community su Discord, dove puoi chiedere aiuto, fare domande e condividere le tue esperienze (ma soprattutto scambiare due meme con me). Ti aspetto!

Ho in previsione di mandarti una newsletter ogni due settimane e una commerciale quando capita.