1186 sujets

Accessibilité du Web

Bonjour,
Dans une modal, il faut, en tabulant, rester dans cette modal (ce qu'il y a derrière étant "inert").
Or, en utilisant la balise dialog, la tabulation sort de la modal, accède à l'interface du navigateur (juste la barre d'url, ou plus pour Firefox) avant de revenir dans la modal.
Ma question est : est-ce une bonne chose ?

J'ai l'impression que tout est sujet à interprétation (le W3C dit aussi que rien ne doit empêcher de sortir de la page. Oui mais pour cela il suffit de fermer la modal. Oui mais alors, etc.)

Alors, faut il, ne faut il pas, ou réponse C : c'est pas grave dans un cas comme dans l'autre ?

J'aimerais savoir si, en utilisant une balise dialog, je dois laisser tomber son comportement natif (que le W3C décrit pourtant comme vertueux; source : https://www.w3.org/WAI/WCAG22/Techniques/html/H102), et tout remplacer par du JS pour ne pas arriver sur la barre d'url après une tabulation.

En vous remerciant, je deviens dingo Smiley smile
Administrateur
Bonjour,

Bonne question parce que pendant longtemps les implémentations en JS avaient le comportement que tu décris...
Non ce n'est pas grave : on n'accède pas au reste de la page (sous l'overlay s'il y en a un) avec un dialogue (modal) natif HTML5. Il y a approx. 2 tabulations supplémentaires de mémoire dont la barre d'adresse/recherche, bah.
Arguments pour, AMHA :
- c'est natif et déjà reconnu par les Technologies d'Assistance dont les lecteurs d'écran (même Voiceover iOS, miracle...).
- le comportement est le même d'un navigateur à l'autre (edit : et d'un site à l'autre ; c'est donc un comportement cohérent pour l'utilisateur)
- (pas 100% du temps) Quand c'est natif, souvent les WCAG et le RGAA ont tendance à passer le sujet (exemple bateau : si un bouton disabled n'est pas assez contrasté mais parce que les styles par défaut du navigateur sont comme ça et l'auteur n'a touché à rien : c'est pas Non-Conforme, c'est Non-Applicable). Ce qui n'améliore rien du point de vue de l'utilisateur...
- surtout ce sera bien plus accessible ainsi qu'avec une implémentation par un.e dév qui ne sait pas exactement ce qu'il fait

On parle bien des dialogues modaux et non pas des dialogues non-modaux (Access & Use) avec lesquels on continue à interagir avec le reste de la page
Modifié par Felipe (03 Jun 2026 - 11:48)
Modérateur
Bonjour,

Comme indiqué dans les précédentes réponses, la balise <dialog> associée à la méthode .showModal() gère nativement le piège de focus et l'overlay. Voici un exemple complet et fonctionnel qui répond à ton besoin.

Code HTML + CSS + JavaScript

code html/JS

<!DOCTYPE html>
<html lang="fr">
    <head>
        <meta charset="UTF-8">
        <title>ACME</title>
        <meta name="viewport" content="width=device-width,initial-scale=1.0" />
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.9.0/dist/css/foundation.min.css" crossorigin="anonymous">
        <style>
            .required-label>span::after {
                content: ' *';
                color: red;
                font-weight: bold;
            }
        </style>
    </head>
    <body>
        <main>
            <h1>Contactez-nous</h1>
            <button class="button" aria-controls="form-contact" aria-expanded="false">Ouvrir le formulaire de contact</button>
            <dialog id="form-contact" aria-labelledby="modal-title" aria-modal="true">
                <form method="post">
                    <h2 id="modal-title">Formulaire de contact</h2>
                    <p>Les champs marqués d'un astérisque (*) sont obligatoires.</p>
                    <ul class="no-bullet">
                        <li><label for="contact-firstname"><span>Prénom</span><input type="text" name="firstname" id="contact-firstname" autocomplete="given-name"></label></li>
                        <li><label for="contact-lastname" class="required-label"><span>Nom</span><input type="text" name="lastname" id="contact-lastname" autocomplete="family-name" required></label></li>
                        <li><label for="contact-email" class="required-label"><span>Email</span><input type="email" name="email" id="contact-email" autocomplete="email" required></label></li>
                        <li><label for="contact-subject" class="required-label"><span>Sujet</span><input type="text" name="subject" id="contact-subject" required></label></li>
                        <li><label for="contact-message" class="required-label"><span>Message</span><textarea name="message" id="contact-message" required></textarea></label></li>
                    </ul>
                    <button class="button" type="submit">Envoyer</button>
                    <button type="button" class="button button--close">Fermer</button>
                </form>
            </dialog>
            <script>
const trigger = document.querySelector('[aria-controls="form-contact"]')
const dialog = document.getElementById('form-contact')
const closeButton = dialog.querySelector('.button--close')
const firstInput = dialog.querySelector('input:first-of-type')

// Ouverture
trigger.addEventListener('click', () => {
    dialog.showModal()
    trigger.setAttribute('aria-expanded', 'true')
    firstInput.focus()
})

// Fermeture
closeButton.addEventListener('click', () => {
    dialog.close()
    trigger.setAttribute('aria-expanded', 'false')
    trigger.focus()
})

// Fermeture avec Escape
dialog.addEventListener('close', () => {
    trigger.setAttribute('aria-expanded', 'false')
    trigger.focus()
})
            </script>
        </main>
    </body>
</html>



Points importants
1. aria-modal="true" indique aux technologies d'assistance que le contenu hors de la modale est inerte.
2. La méthode .showModal() gère nativement le piège de focus et l'overlay (::backdrop), sans besoin de JavaScript supplémentaire.
3. Le bouton "Fermer" utilise type="button" pour éviter toute soumission du formulaire, avec un simple dialog.close() en JavaScript.
4. Gestion de la touche Escape : la fermeture est automatique avec .showModal(), on écoute l'événement close pour gérer le retour de focus vers le déclencheur.
5. aria-expanded sur le déclencheur informe l'utilisateur de l'état de la modale (ouverte/fermée).
6. Labels explicites avec for/id pour une compatibilité optimale avec les lecteurs d'écran.
7. autocomplete sur les champs pertinents (given-name, family-name, email) pour faciliter la saisie (critère WCAG 1.3.5).
8. Champs obligatoires signalés par un astérisque en CSS via ::after, sans impacter la vocalisation par les technologies d'assistance.

Support navigateurs

La balise <dialog> est aujourd'hui supportée par tous les navigateurs modernes (Chrome, Firefox, Safari, Edge). Pour de la compatibilité avec d'anciens navigateurs, il existe des polyfills.

N'hésite pas si tu as des questions !
Modifié par Niuxe (04 Jun 2026 - 11:05)