Fenêtre modale
Une fenêtre modale est une fenêtre qui apparaît par-dessus la fenêtre en cours du navigateur et qui prend le contrôle total du clavier et de l'écran.
Règles d’implémentation pour l’accessibilité
- Une fenêtre modale porte le rôle aria
role="dialog"
, l’attributaria-modal="true"
et un attributaria-labelledby
qui fait référence à l’id
de l’élément contenant le titre de la boîte de dialogue. - Une fenêtre modale est considéré comme un changement de contexte. On veillera donc à commencer son contenu par un titre de niveau 1 (élément HTML
h1
). - Pour bien signifier l’ouverture d’un nouveau contexte, on veillera à opacifier le fond de la page pour bien faire apparaître la fenêtre modale.
- À l’ouverture de la fenêtre modale, le focus sera positionné sur le premier élément pouvant recevoir le focus.
- La fenêtre modale pourra être fermée en appuyant sur la touche [Echap] du clavier.
- Après la fermeture de la fenêtre modale, le focus clavier se repositionne sur le bouton qui a provoqué l’ouverture de la fenêtre modale.
- Pour relier le bouton qui ouvre la modale à la fenêtre modale, le bouton d’ouverture aura pour attribut
aria-controls
avec comme valeur l’id
de la fenêtre modale.
Visuel
Voir la fenêtre modale accessible sur CodePen.
Extraits de code
Code HTML
<button id="btnActionModale" aria-controls="maModale">Modale</button>
<div id="maModale" role="dialog" aria-labelledby="titreModale" aria-describedby="descriptionModale">
<h1 id="titreModale">Titre de la modale</h1>
<p id="descriptionModale">Contenu de la modale</p>
<button id="fermer" aria-label="Fermer la modale">×</button>
</div>
Code CSS
Pour adapter les couleurs, modifier les codes couleurs dans la déclaration :root
.
:root {
--BORDER-color: #b0aeae;
--BUTTON-color: #215990;
--BACKGROUND-color: #FFFFFF;
--BODY-FADE-color: #000;
--BOX-SHADOW: 0 19px 38px rgba(0, 0, 0, 0.12), 0 15px 12px rgba(0, 0, 0, 0.22);
--FOCUS-color: #531AFF;
}
[role="dialog"] {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
padding: 1em;
max-height: 30vh;
max-width: 50vw;
background: var(--BACKGROUND-color);
box-shadow: var(--BOX-SHADOW);
display: none;
border: 0;
}
[role="dialog"] * + * {
margin-top: 0.5em;
}
[role="dialog"][open] {
display: block;
}
button {
cursor: pointer;
background: var(--BUTTON-color);
border: 0;
color: #fff;
padding: 0.25em 0.5em;
font-size: 1em;
}
button:focus,
button:hover {
outline: 3px solid var(--FOCUS-color);
}
#fermerModale {
position: absolute;
top: 0.5em;
right: 0.5em;
margin-top: 0;
line-height: 1;
}
#opaque {
background: var(--BODY-FADE-color);
opacity: 0.75;
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
display: block;
}
Code javascript
var btnDeclencheur = document.getElementById('btnActionModale');
var fenetreModale = document.getElementById('maModale');
var fermerModale = document.getElementById('fermerModale');
function openDialog() {
fenetreModale.setAttribute('open', '');
fermerModale.focus();
fermerModale.addEventListener('keydown', function(e) {
if (e.keyCode == 9) {
e.preventDefault();
}
});
var opaque = document.createElement("div");
opaque.id = 'opaque';
document.body.insertBefore(opaque, fenetreModale);
document.addEventListener('keydown', addESC);
}
function closeDialog() {
fenetreModale.removeAttribute('open');
btnDeclencheur.focus();
document.getElementById("opaque").remove();
document.removeEventListener('keydown', addESC);
}
var addESC = function(e) {
if (e.keyCode == 27) {
closeDialog();
}
};
btnDeclencheur.addEventListener('click', function() {
openDialog();
});
fermerModale.addEventListener('click', function() {
closeDialog();
});