Tutoriel

Statut éditorial : En attente de relecture

Construire une liste de tâches accessible en JavaScript

Créer une todo list utilisable au clavier et avec un lecteur d’écran grâce au HTML natif, aux labels et aux annonces ciblées.

Classification du contenu

Types

  • Développement web
  • Développement front-end

Technologies

Niveau
Débutant
Publié le
30 juillet 2026
Dernière relecture
Relecture en attente
Prochaine vérification
30 janvier 2027

Une interface accessible commence par du HTML natif. Les boutons restent des boutons, les champs ont un label et chaque tâche possède un nom compréhensible hors contexte.

Le HTML

~~~html <main> <h1>Mes tâches</h1> <form id="task-form"> <label for="task-title">Nouvelle tâche</label> <input id="task-title" required maxlength="120" /> <button type="submit">Ajouter</button> </form> <p id="status" aria-live="polite"></p> <ul id="task-list"></ul> </main> ~~~

Le formulaire fonctionne avec Entrée sans gestionnaire clavier personnalisé. aria-live annonce uniquement les changements importants.

Ajouter une tâche

~~~javascript const form = document.querySelector('#task-form'); const input = document.querySelector('#task-title'); const list = document.querySelector('#task-list'); const status = document.querySelector('#status'); let tasks = JSON.parse(localStorage.getItem('tasks') ?? '[]');

function save() { localStorage.setItem('tasks', JSON.stringify(tasks)); }

function render() { list.replaceChildren(...tasks.map(task => { const li = document.createElement('li'); const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.checked = task.done; checkbox.id = 'task-' + task.id; checkbox.addEventListener('change', () => { task.done = checkbox.checked; save(); render(); }); const label = document.createElement('label'); label.htmlFor = checkbox.id; label.textContent = task.title; const remove = document.createElement('button'); remove.type = 'button'; remove.textContent = 'Supprimer ' + task.title; remove.addEventListener('click', () => removeTask(task.id)); li.append(checkbox, label, remove); return li; })); }

form.addEventListener('submit', event => { event.preventDefault(); const title = input.value.trim(); if (!title) return; tasks.push({ id: crypto.randomUUID(), title, done: false }); save(); render(); input.value = ''; input.focus(); status.textContent = 'Tâche ' + title + ' ajoutée'; }); ~~~

Dans removeTask, mémorisez l’élément voisin avant suppression, puis placez le focus dessus ou sur le champ d’ajout. Annoncez la suppression sans déplacer brutalement le lecteur d’écran.

Vérifier

Parcourez toute l’application avec Tab, Maj+Tab, Entrée et Espace. Testez zoom 200 %, contraste, erreurs du formulaire et un lecteur d’écran. Aucun contrôle ne doit dépendre uniquement de la couleur ou du pointeur.

FAQ

Faut-il ajouter role=button ?

Non sur un élément button : sa sémantique est déjà correcte.

localStorage convient-il à des données sensibles ?

Non. Il est accessible au JavaScript de la page et ne remplace pas un stockage serveur sécurisé.

Sources utilisées