J'ai trouvé une approche légèrement différente de la plus votée, bien que le concept soit assez similaire. Je vais utiliser mon code de barres latérales comme exemple. En HTML j'ai des trucs comme ça :
En CSS j'ai ceci :
/*Besoin de réinitialiser le padding, qui est par défaut de 1rem, afin que le contenu du dialog "recouvre" tout l'élément.*/
dialog {
padding: 0;
}
/*Stylisation de l'élément enfant, dans mon cas j'ai `aside`*/
.sidebar aside {
/*Cela peut varier, mais le point est de s'assurer que quelque soit l'élément enfant que vous avez, il recouvre complètement la taille de l'élément dialog.*/
display: flex;
flex-direction: column;
justify-content: center;
height: inherit;
/*Si vous voulez avoir un espacement autour du contenu du dialog principal réel, utilisez du padding, pas de la marge, car si vous cliquez sur la marge de l'élément, il considérera que vous cliquez sur l'élément "en dessous" de celui-ci, mais le padding sera traité comme faisant partie de l'élément sur lequel vous cliquez. En fait, en fonction de la stylisation ci-dessus ou d'autres éléments enfants, vous pourriez même avoir besoin d'utiliser cela.*/
padding: 1rem;
}
Ensuite, dans mon code JS j'ai ceci :
//Gérer la fermeture du dialog en cliquant à l'extérieur du contenu du dialog
const dialogs = document.querySelectorAll('dialog');
if (!empty(dialogs)) {
dialogs.forEach((dialog) => {
dialogInit(dialog);
});
}
function dialogInit(dialog)
{
//Pour mes besoins je vérifie la classe `modal`, mais vous pouvez utiliser n'importe quelle autre classe ou faire cela pour tous les éléments dialog, si vous savez que tous seront modaux
if (dialog.classList.contains('modal')) {
dialog.addEventListener('click', (event) => {
//Si nous avons configuré la stylisation correctement, cliquer "à l'extérieur" du dialog signifie cliquer sur sa marge. Comme il s'agit de la marge, la cible de l'événement est en fait un élément sous l'élément dialog, qui est son arrière-plan, qui est un pseudo-élément, et est donc toujours traité comme le fait de cliquer sur le dialog.
if (event.target && event.target === dialog) {
dialog.close();
}
});
}
}
Encore une fois, le concept est pratiquement le même, mais inversé, et je pense que cela peut le rendre un peu plus universel, car vous n'êtes pas limité à quel type d'élément enfant vous avez dans le dialog, tant que vous définissez sa taille correctement.