Considerazioni sull'accessibilità nello sviluppo web
Garantire l'accessibilità web è essenziale per creare esperienze digitali inclusive. L'accessibilità non solo aiuta gli utenti con disabilità, ma migliora anche l'esperienza complessiva.
Garantire l'accessibilità web è essenziale per creare esperienze digitali inclusive. L'accessibilità non solo avvantaggia gli utenti con disabilità, ma migliora anche l'esperienza utente complessiva e amplia il pubblico raggiunto. Questa guida tratta l'importanza dell'accessibilità, le tecniche per rendere accessibile la manipolazione del DOM, il ruolo di ARIA (Accessible Rich Internet Applications) e come mantenere i widget JavaScript dinamici utilizzabili da tutti.
Quando si costruisce interattività con JavaScript — alternando contenuti, selezionando e aggiornando elementi o modificando il documento — ci si assume la responsabilità dell'accessibilità che il browser altrimenti fornirebbe gratuitamente con il semplice HTML. Questo capitolo mostra dove si trova tale responsabilità e come adempierla.
Creare contenuti accessibili
Importanza dell'accessibilità nello sviluppo web
L'accessibilità nello sviluppo web garantisce che tutti gli utenti, inclusi quelli con disabilità, possano accedere ai contenuti web e interagire con essi in modo efficace. L'Organizzazione Mondiale della Sanità stima che oltre 1 miliardo di persone viva con una qualche forma di disabilità. Rendendo i propri contenuti web accessibili, si raggiunge un pubblico più ampio, si migliora l'usabilità e si rispettano gli standard legali come l'Americans with Disabilities Act (ADA) e le Web Content Accessibility Guidelines (WCAG).
Vantaggi dell'accessibilità
- Inclusività: Permette agli utenti con varie disabilità di accedere a informazioni e servizi.
- Miglioramento SEO: I motori di ricerca spesso premiano i siti accessibili con posizionamenti migliori.
- Conformità legale: Aiuta a evitare potenziali problemi legali relativi agli standard di accessibilità.
- Usabilità migliorata: Migliora l'esperienza utente complessiva per tutti i visitatori, inclusi quelli senza disabilità.
Tecniche per rendere accessibile la manipolazione del DOM
Navigazione da tastiera
Molte persone non possono usare il mouse — navigano con la tastiera, un dispositivo a interruttore o un lettore di schermo che gestisce la tastiera. Se un controllo risponde solo ai clic, quegli utenti sono esclusi. La regola generale: tutto ciò che un utente con mouse può fare, deve poterlo fare anche un utente con tastiera.
Assicurarsi che tutti gli elementi interattivi siano accessibili tramite tastiera. Fare affidamento sull'ordine naturale del DOM per la navigazione con Tab mantiene un flusso logico. L'attributo tabindex controlla questo comportamento:
tabindex="0"inserisce un elemento nell'ordine naturale di tabulazione (utile quando si rende interattivo un elemento non nativo).tabindex="-1"lo rimuove dall'ordine di tabulazione ma consente di focalizzarlo programmaticamente conelement.focus().- I valori positivi come
tabindex="3"sovrascrivono l'ordine naturale e causano quasi sempre confusione — da evitare.
Gli elementi nativi come <button>, <a href> e i controlli di form sono focalizzabili da tastiera per impostazione predefinita, il che è uno dei motivi più validi per preferirli rispetto ai <div> cliccabili. Assicurarsi sempre che un indicatore di focus visibile (il contorno) sia stilizzato in modo che gli utenti da tastiera possano vedere chiaramente quale elemento è focalizzato — non impostare mai outline: none senza fornire un'alternativa.
<!DOCTYPE html>
<html>
<head>
<title>Keyboard Navigation Example</title>
</head>
<body>
<h4>Press the 'Tab' key to navigate through the buttons!</h4>
<button>Button 1</button>
<button>Button 2</button>
<button>Button 3</button>
</body>
</html>Questo esempio si basa sull'ordine naturale del DOM per i pulsanti, rendendo più facile per gli utenti da tastiera navigare.
Componenti interattivi accessibili
Questo esempio dimostra come creare un accordion accessibile utilizzando ruoli e proprietà ARIA e gestendo il focus in modo efficace.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Accessible Accordion Example</title>
<style>
.accordion {
border: 1px solid #ccc;
border-radius: 5px;
margin: 20px 0;
}
.accordion-header {
padding: 10px;
cursor: pointer;
background-color: #f0f0f0;
border-bottom: 1px solid #ccc;
width: 100%;
text-align: left;
}
.accordion-content {
display: none;
padding: 10px;
}
</style>
</head>
<body>
<h1>Accessible Accordion Example</h1>
<h4>Use your keyboard (Enter or Space key) to toggle the accordion!</h4>
<div class="accordion">
<button class="accordion-header" id="accordion-header-1" aria-controls="accordion-content-1" aria-expanded="false">
Section 1
</button>
<div class="accordion-content" id="accordion-content-1" role="region" aria-labelledby="accordion-header-1" tabindex="-1">
<p>This is the content of section 1.</p>
</div>
</div>
<div class="accordion">
<button class="accordion-header" id="accordion-header-2" aria-controls="accordion-content-2" aria-expanded="false">
Section 2
</button>
<div class="accordion-content" id="accordion-content-2" role="region" aria-labelledby="accordion-header-2" tabindex="-1">
<p>This is the content of section 2.</p>
</div>
</div>
<div class="accordion">
<button class="accordion-header" id="accordion-header-3" aria-controls="accordion-content-3" aria-expanded="false">
Section 3
</button>
<div class="accordion-content" id="accordion-content-3" role="region" aria-labelledby="accordion-header-3" tabindex="-1">
<p>This is the content of section 3.</p>
</div>
</div>
<script>
document.querySelectorAll('.accordion-header').forEach(header => {
header.addEventListener('click', function () {
const expanded = this.getAttribute('aria-expanded') === 'true';
this.setAttribute('aria-expanded', !expanded);
const content = document.getElementById(this.getAttribute('aria-controls'));
content.style.display = !expanded ? 'block' : 'none';
});
header.addEventListener('keydown', function (event) {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
this.click();
}
});
});
</script>
</body>
</html>- Struttura accordion: L'accordion è composto da intestazioni che, quando cliccate, espandono o comprimono il contenuto associato.
- HTML semantico e ARIA:
- Gli elementi
<button>nativi sono utilizzati per le intestazioni per garantire supporto nativo da tastiera e per i lettori di schermo. aria-controlsassocia le intestazioni al loro contenuto.aria-expandedindica lo stato della sezione accordion.role="region"sulle sezioni di contenuto le identifica come aree significative.
- Gli elementi
- Accessibilità da tastiera:
- I gestori di eventi gestiscono gli eventi
clickekeydownper consentire l'attivazione dell'accordion tramite tastiera (Invio o Spazio).
- I gestori di eventi gestiscono gli eventi
Perché questo è importante:
- Usabilità migliorata: L'accordion è utilizzabile tramite mouse e tastiera.
- Accessibilità migliorata: Gli attributi ARIA comunicano lo stato e la struttura alle tecnologie assistive, rendendolo accessibile agli utenti di lettori di schermo.
- Gestione del focus: Il focus rimane sul pulsante di attivazione, seguendo i pattern standard degli accordion e prevenendo salti di navigazione imprevisti per gli utenti da tastiera.
Per una trattazione più approfondita della gestione degli eventi di tastiera e clic, vedere Gestione degli eventi nel DOM.
HTML semantico
Usare elementi HTML semantici per trasmettere il significato e la struttura del contenuto. Questo aiuta le tecnologie assistive a interpretare e navigare i contenuti web in modo efficace.
<!DOCTYPE html>
<html>
<head>
<title>Semantic HTML Example</title>
</head>
<body>
<header>
<h1>Main Heading</h1>
</header>
<nav>
<ul>
<li><a href="#section1">Section 1</a></li>
<li><a href="#section2">Section 2</a></li>
</ul>
</nav>
<main>
<section id="section1">
<h2>Section 1</h2>
<p>Content for section 1.</p>
</section>
<section id="section2">
<h2>Section 2</h2>
<p>Content for section 2.</p>
</section>
</main>
<footer>
<p>Footer content</p>
</footer>
</body>
</html>Questo esempio utilizza elementi HTML semantici come <header>, <nav>, <main>, <section> e <footer> per definire la struttura della pagina.
Alternative testuali
I lettori di schermo non possono interpretare immagini, icone o disegni canvas — leggono l'alternativa testuale fornita. Ogni immagine significativa necessita di un attributo alt che ne descriva il contenuto o la funzione. Le immagini decorative che non aggiungono informazioni dovrebbero avere un alt="" vuoto affinché il lettore di schermo le salti invece di annunciare un nome di file.
<!-- Meaningful image: describe it -->
<img src="chart.png" alt="Sales rose 40% from January to March" />
<!-- Decorative image: hide it from screen readers -->
<img src="divider.png" alt="" />
<!-- Icon-only button: label it -->
<button aria-label="Close dialog">×</button>Quando si generano immagini o pulsanti con icone dinamicamente con JavaScript, impostare alt o aria-label nel momento stesso in cui si crea l'elemento — non inviare mai un controllo senza etichetta.
Gestione del focus nei contenuti dinamici
Quando JavaScript apre una finestra di dialogo, rivela nuovo contenuto o guida l'utente attraverso un flusso in più passaggi, è necessario spostare il focus deliberatamente. Altrimenti un utente da tastiera o lettore di schermo rimane nella posizione precedente senza sapere che qualcosa è cambiato. L'esempio seguente apre un modale, sposta il focus al suo interno, intrappola il focus in modo che Tab non possa uscire, e ripristina il focus sul pulsante di apertura alla chiusura.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Accessible Modal Example</title>
<style>
.overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.5); }
.overlay.open { display: flex; align-items: center; justify-content: center; }
.dialog { background: #fff; padding: 20px; border-radius: 6px; min-width: 260px; }
</style>
</head>
<body>
<button id="open-btn">Open dialog</button>
<div class="overlay" id="overlay">
<div class="dialog" role="dialog" aria-modal="true" aria-labelledby="dialog-title">
<h2 id="dialog-title">Confirm action</h2>
<p>Are you sure you want to continue?</p>
<button id="confirm-btn">Confirm</button>
<button id="close-btn">Cancel</button>
</div>
</div>
<script>
const overlay = document.getElementById('overlay');
const openBtn = document.getElementById('open-btn');
const closeBtn = document.getElementById('close-btn');
let lastFocused = null;
function openDialog() {
lastFocused = document.activeElement; // remember the trigger
overlay.classList.add('open');
document.getElementById('confirm-btn').focus(); // move focus in
}
function closeDialog() {
overlay.classList.remove('open');
if (lastFocused) lastFocused.focus(); // restore focus
}
openBtn.addEventListener('click', openDialog);
closeBtn.addEventListener('click', closeDialog);
// Trap focus inside the dialog and close on Escape
overlay.addEventListener('keydown', function (event) {
if (event.key === 'Escape') { closeDialog(); return; }
if (event.key !== 'Tab') return;
const focusable = overlay.querySelectorAll('button');
const first = focusable[0];
const last = focusable[focusable.length - 1];
if (event.shiftKey && document.activeElement === first) {
event.preventDefault();
last.focus();
} else if (!event.shiftKey && document.activeElement === last) {
event.preventDefault();
first.focus();
}
});
</script>
</body>
</html>Punti chiave: role="dialog" e aria-modal="true" comunicano alle tecnologie assistive che si tratta di un modale, aria-labelledby gli assegna un nome accessibile, il focus si sposta all'apertura e ritorna al pulsante di attivazione alla chiusura, e Tab/Shift+Tab cicla all'interno della finestra di dialogo invece di uscirne. Per maggiori informazioni sul focus programmatico, vedere Focus: focus / blur.
ARIA (Accessible Rich Internet Applications)
Ulteriori informazioni su ARIA
Come appreso finora, ARIA (Accessible Rich Internet Applications) è un insieme di attributi che possono essere aggiunti agli elementi HTML per migliorare l'accessibilità per gli utenti di tecnologie assistive come i lettori di schermo. Gli attributi ARIA aiutano a definire ruoli, proprietà e stati degli elementi, rendendo le applicazioni web più accessibili.
La regola più importante di ARIA è: se esiste già un elemento HTML nativo con il comportamento necessario, usarlo invece di ricrearlo con ARIA. Un <button> è sempre preferibile a <div role="button">, perché il pulsante nativo offre attivazione da tastiera, focus e semantica per i lettori di schermo senza alcun JavaScript. ARIA non aggiunge alcun comportamento — cambia solo come un lettore di schermo descrive un elemento. Ricorrere ad ARIA quando nessun elemento nativo si adatta (tab personalizzati, slider, visualizzazioni ad albero, regioni live).
Utilizzo degli attributi ARIA per migliorare l'accessibilità
Ruoli ARIA
I ruoli ARIA definiscono il tipo di elemento, aiutando le tecnologie assistive a comprenderne lo scopo.
<div role="button" aria-pressed="false">Toggle</div>Questo elemento non interattivo usa lo stato aria-pressed per indicare il suo stato di attivazione.
Proprietà e stati ARIA
Le proprietà e gli stati ARIA forniscono informazioni aggiuntive sugli elementi.
<!DOCTYPE html>
<html>
<head>
<title>ARIA Example</title>
</head>
<body>
<div role="alert" id="live-region">
<!-- Dynamic content goes here -->
</div>
<script>
document.getElementById('live-region').textContent = "This is an important message.";
</script>
</body>
</html>Questo esempio utilizza le proprietà ARIA per creare una regione live che annuncia messaggi importanti in modo dinamico. Una regione live è un elemento le cui modifiche il lettore di schermo legge ad alta voce automaticamente, senza che l'utente debba spostare il focus — ideale per aggiornamenti di stato, errori nei form o messaggi di chat.
Si controlla l'urgenza con cui viene annunciata la modifica:
role="alert"(oaria-live="assertive") interrompe l'utente immediatamente — riservarlo per errori e messaggi urgenti.aria-live="polite"attende che l'utente sia inattivo prima di annunciare — usarlo per stati non urgenti come "Articolo aggiunto al carrello".
<div aria-live="polite" id="status"></div>
<script>
// Updating the text content triggers the announcement
document.getElementById('status').textContent = 'Settings saved.';
</script>L'elemento della regione live deve già esistere nel DOM prima di aggiornarlo; se si inietta l'elemento e il suo testo contemporaneamente, molti lettori di schermo perderanno la modifica.
Best practice
- Usare HTML semantico: Preferire sempre gli elementi HTML semantici per fornire significato e struttura chiari al contenuto.
- Implementare l'accessibilità da tastiera: Assicurarsi che tutti gli elementi interattivi siano accessibili e utilizzabili tramite tastiera.
- Gestire il focus in modo efficace: Controllare il focus programmaticamente per guidare gli utenti attraverso i cambiamenti di contenuto dinamici.
- Usare ARIA con saggezza: Applicare ruoli, proprietà e stati ARIA per migliorare, non sostituire, la semantica degli elementi HTML nativi.
- Testare con le tecnologie assistive: Testare regolarmente le applicazioni web con lettori di schermo e altre tecnologie assistive per garantire l'accessibilità.
- Usare strumenti di test automatizzati: Eseguire controlli con strumenti come axe o Lighthouse per individuare tempestivamente i problemi di accessibilità più comuni.
Assicurarsi sempre che i modali e gli altri elementi dinamici siano accessibili gestendo il focus in modo efficace. Usare JavaScript per intrappolare il focus nei modali, ciclando tra gli elementi focalizzabili con il tasto Tab per evitare che gli utenti da tastiera navighino fuori dalla finestra di dialogo involontariamente. Questo migliora l'accessibilità e offre una migliore esperienza utente.
Argomenti correlati
- Selezione degli elementi DOM — trovare gli elementi da etichettare e focalizzare.
- Modifica del documento — impostare attributi ARIA e testo
altdurante la creazione degli elementi. - Gestione degli eventi nel DOM — aggiungere sia gestori
clickchekeydownper il supporto da tastiera. - Focus: focus / blur — gestire il focus programmaticamente per modali e contenuti dinamici.
Conclusione
L'accessibilità è un aspetto fondamentale dello sviluppo web che garantisce che i contenuti siano utilizzabili da tutte le persone, indipendentemente dalle loro capacità. Creando contenuti accessibili, usando tecniche per rendere accessibile la manipolazione del DOM e sfruttando gli attributi ARIA, è possibile migliorare significativamente l'inclusività e l'usabilità delle proprie applicazioni web. L'implementazione di queste pratiche non solo aiuta a rispettare gli standard legali, ma migliora anche l'esperienza utente complessiva.