Aller au contenu

Accessibilité de base et mentions légales

Temps 1 · séance 5 · ~25 min

Les slides du chapitre (PDF)PDF

  • Passer cinq vérifications d'accessibilité dans le navigateur.
  • Corriger dans vos pages ce que ces vérifications révèlent.
  • Publier une page de mentions légales exacte.
  • Relier les mentions légales depuis chaque page publique.

1. Cinq vérifications

Un site accessible se lit et s'utilise par tout le monde : au clavier sans souris, avec une vue faible, ou avec un lecteur d'écran, le logiciel qui lit la page à voix haute. Cinq vérifications couvrent les erreurs les plus fréquentes d'un portfolio. Elles se font dans le navigateur, page par page, en quelques minutes.

Vérification Ce qu'elle protège Comment la faire
Texte alternatif des images le lecteur d'écran sait ce que montre l'image une ligne dans la console, puis relire chaque alt
Titres dans l'ordre la navigation de titre en titre une ligne dans la console qui liste les titres
Contraste de la palette la lecture avec une vue faible ou en plein soleil le sélecteur de couleur des outils de développement
Focus visible au clavier l'utilisation sans souris la touche Tab, de haut en bas de la page
Libellés des champs le remplissage du formulaire de contact un clic sur chaque libellé

Le texte alternatif des images

L'attribut alt d'une image donne le texte que le lecteur d'écran lit à sa place. Une image qui apporte une information reçoit une phrase qui la décrit. Une image décorative, ou qui répète le texte voisin, reçoit alt="" : le lecteur d'écran la saute. Sans attribut alt, il lit le nom du fichier.

Ce que le lecteur d’écran fait de trois images : avec alt et une phrase, une image qui informe, il lit la phrase ; avec alt vide, une image décorative, il saute l’image ; sans attribut alt, il lit le nom du fichier

Dans la console des outils de développement, cette ligne compte les images sans attribut alt :

document.querySelectorAll('img:not([alt])').length

La réponse doit être 0 sur chaque page. Relisez ensuite chaque alt avec la même question : que perd un lecteur qui n'a pas l'image ? Dans ProjectCard.vue, le titre du projet suit l'image et dit ce qu'elle montre, d'où alt="". Si la capture d'une fiche montre ce que le texte ne dit pas, décrivez-la.

Les titres dans l'ordre

Un lecteur d'écran permet de sauter de titre en titre, comme on parcourt une table des matières. Une page a un seul h1, puis des h2, puis des h3 sous un h2, sans sauter de niveau. Cette ligne liste les titres de la page dans l'ordre :

[...document.querySelectorAll('h1, h2, h3, h4')].map((h) => h.tagName + ' ' + h.textContent.trim())

Relisez le code du chapitre 1.18. Sur l'accueil, le h1 de votre nom est suivi du h2 « Projets récents », puis des h3 des cartes : l'ordre est respecté. Sur la liste des projets, le h1 « Mes projets » est suivi directement des h3 des cartes, et le niveau 2 manque. Donnez à la carte un h2 : sur l'accueil, les titres des cartes sont alors au même niveau que « Projets récents », et aucun niveau ne saute sur les deux pages.

Les titres de la page, dans l’ordre. Avant, sur la liste : le h1 Mes projets, puis directement les h3 des cartes, le niveau h2 manque. Après, avec un h2 sur la carte : la liste donne h1 Mes projets puis h2 pour chaque carte, et l’accueil donne h1 votre nom, h2 Projets récents, puis h2 pour chaque carte ; aucun niveau ne saute

Le niveau d'un titre dit sa place dans la structure, pas sa taille. La taille vient des classes, comme text-lg, qui ne changent pas.

Le contraste

Vous avez mesuré les paires de votre planche au chapitre 1.09. Le site en ajoute d'autres : le blanc sur bg-brand de l'appel à l'action, le gris text-muted-foreground des résumés sur le fond, les liens text-brand. Mesurez chaque paire réellement affichée, en mode clair et en mode sombre.

Dans Chrome, inspectez un élément de texte, puis cliquez sur le petit carré de couleur à côté de color dans le panneau Styles. Le sélecteur de couleur affiche le contraste de ce texte sur son fond, avec les seuils atteints ou non. Les seuils restent ceux du chapitre 1.09 : 4,5:1 pour tout texte, boutons compris, et 3:1 pour une icône, le contour d'un champ ou la forme d'un bouton face à la page.

Le focus visible au clavier

Le focus marque l'élément qui recevra la prochaine frappe du clavier. La touche Tab le fait passer au lien ou au bouton suivant, et Entrée l'active. Sans cadre visible autour de l'élément qui a le focus, une personne qui navigue au clavier ne sait plus où elle est.

Cliquez dans la barre d'adresse, puis appuyez sur Tab jusqu'au bas de la page. Chaque lien et chaque bouton doit montrer un cadre ou un changement net. Les boutons du kit ont un anneau de focus, écrit avec focus-visible:ring-[3px] dans resources/js/components/ui/button/index.ts. Vos liens gardent le contour que le navigateur dessine par défaut. Ne le retirez jamais avec outline-none sans le remplacer.

Sur la page de contact, le focus passe du nom à l'adresse, au message, puis au bouton.

L'en-tête de l'accueil après deux appuis sur Tab : le lien À propos du menu porte le contour de focus dessiné par le navigateur, les autres liens non.

Les libellés des champs

Chaque champ a besoin d'un libellé relié à lui : une balise <label> dont l'attribut for vaut l'id du champ. Le lecteur d'écran annonce ce libellé quand le champ reçoit le focus. Un texte d'exemple dans le champ, l'attribut placeholder, ne le remplace pas, car il disparaît dès qu'on tape.

Dans Contact.vue, <Label for="name"> est relié à <Input id="name">. Pour vérifier, cliquez sur chaque libellé : le curseur doit se placer dans le champ correspondant.

Dans Contact.vue, Label for="name" et Input id="name" portent la même valeur : quand le champ reçoit le focus, le lecteur d’écran annonce Nom. Un placeholder disparaît dès qu’on tape. La touche Tab fait passer le focus de Nom à Adresse e-mail, à Message, puis au bouton Envoyer

Astuce

L'onglet Lighthouse des outils de développement de Chrome fait un audit automatique de l'accessibilité d'une page. Il trouve une partie de ces erreurs, mais pas toutes : il ne sait pas si un alt décrit bien l'image. Gardez les cinq vérifications faites à la main.

2. Les mentions légales

Un visiteur doit pouvoir savoir qui publie le site, qui l'héberge et ce que deviennent les données qu'il y laisse. La page de mentions légales le dit. Elle n'affiche aucune donnée de la base, donc elle n'a pas besoin de contrôleur.

La route d'abord

Ajoutez la route dans routes/web.php, à côté de about :

Route::inertia('mentions-legales', 'Legal')->name('legal');

Enregistrez le fichier avant d'écrire la page et le lien. Wayfinder génère alors la fonction legal() dans resources/js/routes/index.ts. Dans l'ordre inverse, un import de legal écrit avant la route fait échouer Vite, avec ce message dans la console :

SyntaxError: The requested module '/resources/js/routes/index.ts' does not provide an export named 'legal'

L'erreur disparaît dès que la route existe et que le terminal affiche Types generated for actions, routes, form variants.

La page

Créez resources/js/pages/Legal.vue :

<script setup>
import { Head } from '@inertiajs/vue3';
</script>

<template>
    <Head title="Mentions légales">
        <meta
            head-key="description"
            name="description"
            content="Éditeur, hébergeur et données personnelles du portfolio de Nora Benali."
        />
    </Head>

    <article class="prose max-w-none py-8 dark:prose-invert">
        <h1 class="font-display">Mentions légales</h1>

        <h2>Éditeur du site</h2>
        <p>
            Nora Benali, étudiante à l'IFOSUP Wavre. Contact : par le formulaire
            de la page Contact.
        </p>

        <h2>Hébergeur</h2>
        <p>OVH SAS, 2 rue Kellermann, 59100 Roubaix, France.</p>

        <h2>Données personnelles</h2>
        <p>
            Le formulaire de contact enregistre votre nom, votre adresse e-mail
            et votre message, pour vous répondre et pour rien d'autre. Ils ne
            sont ni vendus ni transmis. Écrivez-moi pour les faire effacer.
        </p>

        <h2>Cookies</h2>
        <p>
            Ce site ne dépose aucun cookie de mesure d'audience ni de publicité.
            Il utilise seulement les cookies techniques nécessaires à son
            fonctionnement (session et protection des formulaires).
        </p>
    </article>
</template>

Les textes sont ceux de l'exemple. Écrivez les vôtres, et ne déclarez que ce que votre site fait vraiment.

La page Mentions légales du portfolio de Nora Benali, dans le layout public : les quatre titres Éditeur du site, Hébergeur, Données personnelles et Cookies, chacun suivi de son paragraphe, puis le pied de page.

  • L'éditeur, c'est vous : votre nom, et un moyen de vous joindre. Le formulaire de contact suffit, sans publier votre adresse e-mail.
  • L'hébergeur est la société qui loue le serveur. Recopiez son nom et son adresse depuis les conditions de votre hébergement chez OVH, et vérifiez-les.
  • Les données personnelles sont celles du formulaire du chapitre 1.20 : le nom, l'adresse e-mail et le message, enregistrés dans la table contact_messages et envoyés à votre boîte. Dites pourquoi vous les gardez, et comment en demander l'effacement.
  • Les cookies : le kit dépose un cookie de session, un cookie XSRF-TOKEN qui protège les formulaires, et un cookie appearance pour le thème choisi dans le back-office. Ce sont des cookies techniques. Aucun ne sert à mesurer l'audience ou à faire de la publicité, et le site n'affiche donc pas de bandeau de cookies.

Les polices ne demandent aucune ligne. Depuis le chapitre 1.18, le site sert lui-même leurs fichiers, et aucune donnée du visiteur ne part vers un service tiers.

prose met en forme les titres et les paragraphes, comme pour l'à-propos.

Le lien dans le pied de page

Chaque page publique mène aux mentions légales. Dans PublicLayout.vue, ajoutez legal à l'import de @/routes, puis le lien dans le pied de page :

<footer
    class="flex flex-col gap-2 border-t py-6 text-sm text-muted-foreground sm:flex-row sm:justify-between"
>
    <p>© Nora Benali</p>
    <Link :href="legal()" class="underline">Mentions légales</Link>
</footer>
import { about, contact, home, legal } from '@/routes';

Le pied de page de chaque page publique porte, sous © Nora Benali, le lien Mentions légales ; legal() le mène à /mentions-legales, une page de quatre titres h2 : Éditeur du site, vous ; Hébergeur, OVH SAS ; Données personnelles, nom, adresse e-mail et message ; Cookies, techniques seulement

Le test

Ajoutez ce test dans tests/Feature/PublicPagesTest.php, le fichier du chapitre 1.19 :

test('the legal notice page exists', function () {
    $this->get('/mentions-legales')
        ->assertOk()
        ->assertInertia(fn (Assert $page) => $page->component('Legal'));
});

Assert est la classe du chapitre 1.17, importée en tête du fichier avec use Inertia\Testing\AssertableInertia as Assert;. La sortie de php artisan test tests/Feature/PublicPagesTest.php est celle du chapitre 1.19, avec ce test en dernière ligne.

L'accessibilité complète d'un site et son cadre légal, déclaration d'accessibilité et protection des données comprises, viendront avec le projet en binôme.

3. Pratique : les cinq vérifications et vos mentions (20 min)

Temps annoncé : 20 minutes.

Faites les cinq vérifications sur chaque page publique : l'accueil, la liste, une fiche, l'à-propos, le contact et les mentions légales. Corrigez au fur et à mesure.

  • La console répond 0 à document.querySelectorAll('img:not([alt])').length, et chaque alt non vide décrit l'image.
  • Chaque page a un seul h1, et les titres se suivent sans sauter de niveau.
  • Chaque texte atteint 4,5:1 sur son fond, dans chaque mode que votre site propose, appel à l'action compris.
  • Avec la touche Tab, chaque lien et chaque bouton montre un focus visible.
  • Un clic sur chaque libellé du contact place le curseur dans son champ.
  • /mentions-legales nomme l'éditeur et l'hébergeur, dit ce que deviennent les messages du formulaire, et indique qu'aucun cookie tiers n'est déposé.
  • Le pied de page de chaque page publique mène aux mentions légales.
  • Le test des mentions légales est vert, et php artisan test aussi.

Ce que votre portfolio contient maintenant

Des pages publiques qui passent les cinq vérifications de base : des images avec leur texte alternatif, des titres dans l'ordre, des contrastes mesurés, un focus visible et des champs avec leur libellé. Une page de mentions légales, reliée depuis chaque page publique, qui dit qui édite le site, qui l'héberge et ce que deviennent les données du formulaire.

À retenir

  • Chaque image a un attribut alt, vide pour une image décorative, descriptif pour une image qui informe.
  • Les titres se suivent sans sauter de niveau, et leur taille vient des classes, pas du niveau.
  • Le contraste se mesure dans le sélecteur de couleur du navigateur, pour chaque paire réellement affichée.
  • La touche Tab montre un focus visible sur chaque lien et chaque bouton, et chaque champ a un <label for> relié à son id.
  • Route::inertia('mentions-legales', 'Legal') suffit pour une page sans données, à condition de déclarer la route avant d'importer legal().