Por que o ::backdrop não funciona com o atributo open do <dialog>
No meu tempo livre, estou estudando alguns elementos HTML que não existiam anos atrás e que surgiram para dar mais semântica às marcações, melhorar a usabilidade e a acessibilidade, além de reduzir a quantidade de scripts em JavaScript.
A tag da vez é a <dialog>, que permite criar caixas de diálogo semânticas e acessíveis em HTML. Em vez de usar um <div> ou <section> para criar uma caixa de diálogo, o <dialog> oferece uma maneira mais semântica e acessível de fazer isso. Além disso, é fácil customizar o estilo com CSS e adicionar recursos interativos com JavaScript.
Porém, descobri que, ao abrir o <dialog> com o atributo open, o pseudo-elemento ::backdrop não é aplicado, o que pode ser um problema se você estiver usando um backdrop personalizado. Implementei o <dialog> no projeto "Neymar Jogou?" e acabei descobrindo esse comportamento.
.dialog-modal::backdrop {
background: rgba(0, 0, 0, 0.65);
}
<dialog class="dialog-modal" open>
<p>Uma mensagem qualquer para exibir na modal</p>
</dialog>
Se usar o código acima em uma página HTML, vai notar que o <dialog> estará aberto, porém a formatação do ::backdrop não estará aplicada. Isso acontece porque o atributo open abre o diálogo de forma não modal, e o backdrop só existe em diálogos modais.
Dando uma fuçada no MDN, acabei encontrando essa nota de uso:
O pseudo-elemento CSS
::backdroppode ser usado para estilizar o plano de fundo de um elemento<dialog>, por exemplo, para escurecer o conteúdo inacessível enquanto uma janela de diálogo modal está aberta. Porém, o backdrop só é desenhado quando o diálogo é exibido comHTMLDialogElement.showModal().
Link: Notas de uso do <dialog> no MDN
Ou seja, se precisar usar o atributo open para manter o <dialog> aberto sem necessidade de JavaScript, vai perder o backdrop personalizado. Caso precise do backdrop personalizado com o <dialog> já aberto ao carregar a página, por exemplo, vai precisar usar o método HTMLDialogElement.showModal() e remover o atributo open da marcação.
Algo assim:
<style type="text/css">
.dialog-modal::backdrop {
background: rgba(0, 0, 0, 0.65);
}
</style>
<dialog class="dialog-modal">
<p>Uma mensagem qualquer para exibir na modal</p>
</dialog>
<script>
(() => {
const $dialog = document.querySelector('.dialog-modal');
if ($dialog) {
$dialog.showModal();
}
})();
</script>
Resumindo: ao usar <dialog>, você enfrenta um trade-off entre simplicidade e funcionalidade. O atributo open oferece um diálogo sem JavaScript, mas perde o backdrop visual. O método showModal() exige JS, mas traz a experiência completa. A escolha depende do seu caso de uso — se o backdrop é apenas estético, open resolve; se é essencial para a usabilidade, showModal() é o caminho.