Generatore di schede CSS

Avanti

Le schede sono ovunque: pannelli delle impostazioni, siti di documentazione, gallerie di prodotti. L’HTML nativo non ha un elemento scheda dedicato, quindi gli sviluppatori creano i propri. Questo generatore costruisce una semplice barra di schede in HTML + CSS: un colore accent per la scheda attiva, un raggio degli angoli per i pulsanti e uno stato al passaggio del mouse. Incolla il markup nel tuo progetto e collega il cambio di scheda al tuo JavaScript.

Come costruire le schede

  1. 1

    Scegli un colore accent

    Il colore di sfondo e di testo della scheda attiva. Scegli un colore che si abbini al tuo brand.

  2. 2

    Imposta il raggio degli angoli

    Arrotonda gli angoli superiori dei pulsanti. Valori più alti danno un aspetto più morbido.

  3. 3

    Modifica le etichette

    Il risultato contiene tre pulsanti, "Overview", "Details" e "Settings": rinominali in base al tuo contenuto.

  4. 4

    Copia il codice

    Il markup delle schede include un blocco <style> integrato. Incolla entrambi nella tua pagina.

  5. 5

    Aggiungi il cambio di scheda

    Il generatore produce solo la parte visiva. Collega i pulsanti al tuo JavaScript o alla tua libreria UI per mostrare e nascondere i pannelli.

Markup accessibile corretto

<div class="tabs">
  <div role="tablist" aria-label="Informazioni sul prodotto">
    <button role="tab" id="tab-1" aria-selected="true"  aria-controls="panel-1" tabindex="0">Panoramica</button>
    <button role="tab" id="tab-2" aria-selected="false" aria-controls="panel-2" tabindex="-1">Specifiche</button>
    <button role="tab" id="tab-3" aria-selected="false" aria-controls="panel-3" tabindex="-1">Recensioni</button>
  </div>
  <section role="tabpanel" id="panel-1" aria-labelledby="tab-1">...</section>
  <section role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>...</section>
  <section role="tabpanel" id="panel-3" aria-labelledby="tab-3" hidden>...</section>
</div>

Attributi critici:

  • role="tablist" avvolge i pulsanti.
  • role="tab" su ogni pulsante, con aria-selected e aria-controls.
  • tabindex utilizza il pattern di tabindex mobile: solo la scheda attiva è 0, le altre sono -1. I tasti freccia spostano il focus tra di esse.
  • role="tabpanel" su ogni pannello, con aria-labelledby che punta alla sua scheda.
  • hidden sui pannelli inattivi (non display: none da solo, l’attributo è ciò che utilizza AT).

Contratto da tastiera

Tasto Azione
Tab Sposta dentro / fuori dalla lista delle schede
ArrowLeft Scheda precedente (torna all’ultima)
ArrowRight Scheda successiva (torna alla prima)
Home Prima scheda
End Ultima scheda
Enter / Space Attiva la scheda con focus (se attivazione manuale)

Attivazione automatica (la scheda cambia mentre il focus si sposta) vs. manuale (il focus si sposta, la scheda si attiva su Enter), WAI-ARIA consente entrambi. L’automatico è più facile per gli utenti vedenti; il manuale è migliore quando il contenuto della scheda è pesante da renderizzare.

Stile sottolineato

[role="tablist"] {
  display: flex;
  border-bottom: 1px solid #e5e7eb;
}
[role="tab"] {
  padding: 0.75rem 1rem;
  background: transparent;
  border: 0;
  color: #6b7280;
  position: relative;
  cursor: pointer;
}
[role="tab"][aria-selected="true"] {
  color: #111827;
}
[role="tab"][aria-selected="true"]::after {
  content: "";
  position: absolute;
  left: 1rem; right: 1rem; bottom: -1px;
  height: 2px;
  background: #2563eb;
}

Stile arrotondato

[role="tab"] {
  padding: 0.5rem 0.9rem;
  border-radius: 9999px;
  border: 0;
  background: transparent;
}
[role="tab"][aria-selected="true"] {
  background: #2563eb;
  color: #fff;
}

Focus visibile

Disegna sempre un anello di focus quando il focus arriva tramite tastiera:

[role="tab"]:focus-visible {
  outline: 2px solid #60a5fa;
  outline-offset: 2px;
}

Il JavaScript

Circa:

const tabs = document.querySelectorAll('[role="tab"]');
tabs.forEach(tab => {
  tab.addEventListener('click', () => activate(tab));
  tab.addEventListener('keydown', e => {
    const i = [...tabs].indexOf(tab);
    if (e.key === 'ArrowRight') tabs[(i + 1) % tabs.length].focus();
    if (e.key === 'ArrowLeft')  tabs[(i - 1 + tabs.length) % tabs.length].focus();
    if (e.key === 'Home') tabs[0].focus();
    if (e.key === 'End')  tabs[tabs.length - 1].focus();
  });
});

function activate(tab) {
  tabs.forEach(t => {
    const panel = document.getElementById(t.getAttribute('aria-controls'));
    const active = t === tab;
    t.setAttribute('aria-selected', active);
    t.setAttribute('tabindex', active ? '0' : '-1');
    panel.hidden = !active;
  });
  tab.focus();
}

Trenta righe in totale, zero dipendenze.

Schede vs. accordion

Sugli schermi stretti, le righe delle schede diventano affollate. Schema comune: schede su desktop, accordion su mobile. Usa una query di contenitore o una media query per cambiare il trattamento visivo senza cambiare i ruoli ARIA.

Domande frequenti

Per schede accessibili, sì. Senza role="tablist" e role="tab", i lettori di schermo trattano i pulsanti come pulsanti normali e gli utenti perdono la convenzione di navigazione. L’alternativa è un semplice accordion <details> / <summary>, che ha una semantica integrata.

L’attivazione automatica (la scheda si attiva mentre il focus si sposta) va bene quando il contenuto di ciascuna scheda è economico da renderizzare. L’attivazione manuale (il focus si sposta, Enter attiva) è migliore quando il passaggio tra le schede attiva lavori pesanti come il recupero o il rendering di un grande modulo.

Per schede che contengono contenuti (documentazione, schede prodotto), sì, usa un hash (#specs) o un parametro di query in modo che i link possano collegarsi a una scheda specifica e la scheda attiva persista tra i ricaricamenti. Per schede UI (pannelli delle impostazioni) l’URL è facoltativo.

Solo con l’hack della checkbox/radio, che manca della navigazione con tasti freccia e degli stati ARIA. Per un’implementazione veramente accessibile, il piccolo snippet JS vale la pena. Se hai bisogno di fallback renderizzati dal server, collega ogni scheda a un URL unico e renderizza il pannello corrispondente lato server.

Strumenti correlati

Strumento disponibile in altre lingue