Como criar um modal com JavaScript usando dialog e showModal

Aprenda como criar um modal com JavaScript puro usando o elemento nativo dialog, sem depender de bibliotecas externas como Bootstrap, jQuery ou plugins de interface.

Em muitos projetos, o modal é criado manualmente com div, overlay, controle de foco, eventos de clique fora da caixa e tratamento da tecla ESC. Isso funciona, mas aumenta a quantidade de código e pode gerar problemas de acessibilidade, principalmente quando o usuário continua conseguindo interagir com elementos atrás do modal.

Outro problema comum é o excesso de dependência de bibliotecas apenas para abrir uma janela modal simples. Em muitos casos, o próprio HTML já oferece uma solução nativa com o elemento dialog.

A Solução

A solução é usar o elemento HTML dialog junto com os métodos JavaScript showModal() e close(). Com isso, o navegador passa a tratar o modal de forma nativa, exibindo o conteúdo sobre a página e impedindo a interação com os elementos externos enquanto o modal estiver aberto.

Estrutura HTML do modal

Crie um botão para abrir o modal e, em seguida, adicione o elemento dialog com o conteúdo que será exibido.

<button type="button" class="btn-abrir-modal" data-modal-open="modalExemplo">
    Abrir modal
</button>
 
<dialog id="modalExemplo" class="modal">
    <div class="modal__conteudo">
        <button type="button" class="modal__fechar" data-modal-close aria-label="Fechar modal">
            &amp;times;
        </button>
 
        <h2>Título do modal</h2>
 
        <p>
            Este é um exemplo de modal criado com JavaScript puro usando o elemento nativo dialog.
        </p>
 
        <div class="modal__acoes">
            <button type="button" data-modal-close>
                Fechar
            </button>
        </div>
    </div>
</dialog>

CSS para estilizar o modal

O pseudo-elemento ::backdrop permite estilizar o fundo escuro exibido atrás do modal.

.modal {
    width: min(90%, 500px);
    border: 0;
    border-radius: 12px;
    padding: 0;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
}
 
.modal::backdrop {
    background: rgba(0, 0, 0, 0.65);
}
 
.modal__conteudo {
    position: relative;
    padding: 24px;
    background: #fff;
}
 
.modal__fechar {
    position: absolute;
    top: 12px;
    right: 12px;
    border: 0;
    background: transparent;
    font-size: 28px;
    line-height: 1;
    cursor: pointer;
}
 
.modal__acoes {
    margin-top: 24px;
    text-align: right;
}
 
.btn-abrir-modal,
.modal__acoes button {
    cursor: pointer;
    padding: 10px 16px;
    border: 0;
    border-radius: 6px;
}

JavaScript para abrir e fechar o modal

O método showModal() abre o modal em modo bloqueante. Já o método close() fecha o modal.

document.addEventListener('DOMContentLoaded', function () {
    const botoesAbrir = document.querySelectorAll('[data-modal-open]');
    const botoesFechar = document.querySelectorAll('[data-modal-close]');
 
    botoesAbrir.forEach(function (botao) {
        botao.addEventListener('click', function () {
            const modalId = botao.getAttribute('data-modal-open');
            const modal = document.getElementById(modalId);
 
            if (!modal) {
                return;
            }
 
            if (!modal.open) {
                modal.showModal();
            }
        });
    });
 
    botoesFechar.forEach(function (botao) {
        botao.addEventListener('click', function () {
            const modal = botao.closest('dialog');
 
            if (modal) {
                modal.close();
            }
        });
    });
});

Fechar o modal ao clicar fora do conteúdo

Também é possível fechar o modal quando o usuário clicar na área escura fora da caixa principal. Para isso, verificamos se o clique aconteceu diretamente no elemento dialog.

document.addEventListener('DOMContentLoaded', function () {
    const modais = document.querySelectorAll('dialog');
 
    modais.forEach(function (modal) {
        modal.addEventListener('click', function (event) {
            if (event.target === modal) {
                modal.close();
            }
        });
    });
});

Exemplo completo

Abaixo está um exemplo completo com HTML, CSS e JavaScript.

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Modal com JavaScript</title>
 
    <style>
        .modal {
            width: min(90%, 500px);
            border: 0;
            border-radius: 12px;
            padding: 0;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
        }
 
        .modal::backdrop {
            background: rgba(0, 0, 0, 0.65);
        }
 
        .modal__conteudo {
            position: relative;
            padding: 24px;
            background: #fff;
            font-family: Arial, sans-serif;
        }
 
        .modal__fechar {
            position: absolute;
            top: 12px;
            right: 12px;
            border: 0;
            background: transparent;
            font-size: 28px;
            line-height: 1;
            cursor: pointer;
        }
 
        .modal__acoes {
            margin-top: 24px;
            text-align: right;
        }
 
        .btn-abrir-modal,
        .modal__acoes button {
            cursor: pointer;
            padding: 10px 16px;
            border: 0;
            border-radius: 6px;
        }
    </style>
</head>
<body>
    <button type="button" class="btn-abrir-modal" data-modal-open="modalExemplo">
        Abrir modal
    </button>
 
    <dialog id="modalExemplo" class="modal">
        <div class="modal__conteudo">
            <button type="button" class="modal__fechar" data-modal-close aria-label="Fechar modal">
                &amp;times;
            </button>
 
            <h2>Modal com JavaScript</h2>
 
            <p>
                Este modal foi criado usando JavaScript puro e o elemento nativo dialog.
            </p>
 
            <div class="modal__acoes">
                <button type="button" data-modal-close>
                    Fechar
                </button>
            </div>
        </div>
    </dialog>
 
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            const botoesAbrir = document.querySelectorAll('[data-modal-open]');
            const botoesFechar = document.querySelectorAll('[data-modal-close]');
            const modais = document.querySelectorAll('dialog');
 
            botoesAbrir.forEach(function (botao) {
                botao.addEventListener('click', function () {
                    const modalId = botao.getAttribute('data-modal-open');
                    const modal = document.getElementById(modalId);
 
                    if (!modal) {
                        return;
                    }
 
                    if (!modal.open) {
                        modal.showModal();
                    }
                });
            });
 
            botoesFechar.forEach(function (botao) {
                botao.addEventListener('click', function () {
                    const modal = botao.closest('dialog');
 
                    if (modal) {
                        modal.close();
                    }
                });
            });
 
            modais.forEach(function (modal) {
                modal.addEventListener('click', function (event) {
                    if (event.target === modal) {
                        modal.close();
                    }
                });
            });
        });
    </script>
</body>
</html>

Conclusão

Criar um modal com JavaScript ficou mais simples usando o elemento nativo dialog. Com poucos métodos, como showModal() e close(), é possível abrir e fechar janelas modais sem depender de bibliotecas externas.

Essa abordagem reduz código, melhora a manutenção e aproveita recursos nativos do navegador, como o bloqueio da interação com o restante da página e o uso do ::backdrop para estilizar o fundo do modal.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Rolar para cima