Sabe aquela “janelinha” que aparece no meio da tela e escurece o fundo quando você clica em um botão?
Isso é um modal.

Neste post você vai aprender, passo a passo, a criar um modal simples usando:

  • HTML para montar a estrutura
  • CSS para deixar o layout organizado
  • JavaScript para abrir e fechar o modal

A ideia é que você acompanhe no seu computador, criando os arquivos e testando cada etapa.

Se você ainda não sabe:

Como criar um arquivo HTML básico, recomendo ver:
https://vivendodeprogramacao.com.br/como-criar-arquivo-html-basico

Como separar o HTML do CSS:
https://vivendodeprogramacao.com.br/como-separar-o-html-do-css

Como separar o JavaScript do HTML:
https://vivendodeprogramacao.com.br/como-separar-o-javascript-do-html

O que vamos construir

Vamos criar uma página bem simples com:

  • Um título
  • Um botão “Abrir modal”
  • Um modal que:
    • aparece no centro da tela
    • escurece o fundo
    • tem um botão de fechar “X”
    • fecha ao clicar fora da caixa
    • (opcional) fecha ao apertar a tecla ESC

Tudo isso com o layout mais simples possível, apenas para ilustrar o conceito.

Passo 1: Preparar a pasta do projeto

Crie uma pasta no seu computador, por exemplo:

modal-javascript/

Dentro dela, vamos criar 3 arquivos:

index.html → nosso HTML

style.css → nosso CSS

script.js → nosso JavaScript

Fica assim:

modal-javascript/  
	index.html  
	style.css  
	script.js

Passo 2: Criar o HTML base (index.html)

Abra o index.html no seu editor e coloque o seguinte código:

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <title>Exemplo de Modal com JavaScript</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>

    <h1>Exemplo de Modal com JavaScript</h1>

    <button id="abrir-modal">Abrir modal</button>

    <!-- Estrutura do modal -->
    <div id="modal-overlay" class="modal-overlay">
        <div class="modal">
            <button class="fechar-modal" aria-label="Fechar modal">&times;</button>
            <h2>Título do modal</h2>
            <p>Este é um exemplo de conteúdo dentro do modal.</p>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>

Entendendo o HTML

<link rel="stylesheet" href="style.css">

Conecta nosso arquivo CSS à página.

<button id="abrir-modal">Abrir modal</button>

É o botão que o usuário vai clicar para abrir o modal.

<div id="modal-overlay" class="modal-overlay">

É a “camada escura” que cobre a tela quando o modal está aberto.

<div class="modal">

É a caixinha branca que aparece no centro (o modal em si).

<button class="fechar-modal">

É o botão “X” dentro do modal para fechar.

<script src="script.js"></script>

Conecta nosso arquivo JavaScript no final da página.

Teste rápido:
Abra o index.html no navegador.
Por enquanto vai aparecer só o título, o botão e o conteúdo do modal todo “bagunçado”.
Não se preocupe, o CSS vai arrumar tudo!

Passo 3: Estilizar a página (style.css – parte 1)

Agora vamos começar o style.css com algumas regras básicas de layout.

Abra o style.css e coloque:

/* Deixar a página com uma cara simples e centralizada */
body {
    margin: 0;
    padding: 0;
    font-family: Arial, sans-serif;
    background-color: #f2f2f2;
    color: #333;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

/* Título */
h1 {
    margin-bottom: 20px;
}

/* Botão que abre o modal */
#abrir-modal {
    padding: 10px 20px;
    font-size: 16px;
    cursor: pointer;
}

Teste:
Atualize a página no navegador.
Você já deve ver o título centralizado e o botão com uma aparência melhor.

Passo 4: Estilizar o modal (style.css – parte 2)

Agora vamos transformar a estrutura do modal em um “pop-up” centralizado com fundo escuro.

Adicione abaixo do que já está no style.css:

/* Fundo escuro por trás do modal */
.modal-overlay {
    position: fixed;        /* Fica parado na tela mesmo se rolar */
    inset: 0;               /* Atalho para top: 0; left: 0; right: 0; bottom: 0; */
    background-color: rgba(0, 0, 0, 0.5); /* preto com transparência */
    display: none;          /* Começa invisível */
    align-items: center;    /* Alinha verticalmente o conteúdo */
    justify-content: center;/* Alinha horizontalmente o conteúdo */
}

/* Quando o modal estiver ativo, mostramos o overlay */
.modal-overlay.ativo {
    display: flex;
}

/* Caixa branca do modal */
.modal {
    background-color: #fff;
    padding: 20px;
    border-radius: 6px;
    max-width: 400px;
    width: 90%;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
    position: relative;
}

/* Botão de fechar (X) */
.fechar-modal {
    position: absolute;
    top: 8px;
    right: 8px;
    border: none;
    background: transparent;
    font-size: 20px;
    cursor: pointer;
}

Conceitos importantes aqui

position: fixed + inset: 0

Faz o overlay ocupar a tela toda.

display: none

Esconde o modal por padrão.

.modal-overlay.ativo

Essa classe extra ativo será adicionada/removida pelo JavaScript para mostrar ou esconder o modal.

display: flex com align-items e justify-content

Centraliza a caixinha (.modal) no meio da tela.

Teste:
Ainda não vai abrir/fechar ao clicar, porque o JavaScript não foi programado.
Mas o layout do modal já está pronto.

Passo 5: Criar o JavaScript base (script.js)

Agora vamos para a parte que dá vida ao modal: o JavaScript.

Abra o script.js e, primeiro, vamos só “pegar” os elementos que vamos manipular:

// Pegando os elementos do HTML
const botaoAbrir = document.querySelector('#abrir-modal');
const overlay = document.querySelector('#modal-overlay');
const botaoFechar = document.querySelector('.fechar-modal');
const modal = document.querySelector('.modal');

O que está acontecendo aqui?

document.querySelector('#abrir-modal')

Procura no HTML o elemento que tem id="abrir-modal" e guarda na variável botaoAbrir.

document.querySelector('#modal-overlay')

Pega o fundo escuro (div com id modal-overlay).

document.querySelector('.fechar-modal')

Pega o botão “X” (classe fechar-modal).

document.querySelector('.modal')

Pega a caixinha branca do modal (classe modal).

Pense assim:
Estamos “criando apelidos” em JavaScript para conseguir mexer nesses elementos depois.

Passo 6: Funções para abrir e fechar o modal

Agora vamos criar duas funções: uma para abrir e outra para fechar o modal.

Adicione abaixo do código que já está no script.js:

// Função para abrir o modal
function abrirModal() {
    // Adiciona a classe "ativo" no overlay
    overlay.classList.add('ativo');
}

// Função para fechar o modal
function fecharModal() {
    // Remove a classe "ativo" do overlay
    overlay.classList.remove('ativo');
}

Quando o JavaScript adiciona a classe ativo, o display deixa de ser none e vira flex, então o modal aparece.

Quando o JavaScript remove a classe ativo, o modal volta a ficar invisível.

Passo 7: Abrir o modal ao clicar no botão

Agora vamos dizer para o navegador:

“Quando o usuário clicar no botão Abrir modal, execute a função abrirModal().”

Adicione no script.js:

// Quando o usuário clicar no botão "Abrir modal"
botaoAbrir.addEventListener('click', abrirModal);

Entenda essa linha

botaoAbrir → é o botão que pegamos do HTML.

.addEventListener('click', abrirModal) → diz:

escute o evento de clique ('click')

quando acontecer, chame a função abrirModal.

Teste:
Atualize a página no navegador e clique em “Abrir modal”.
O fundo deve escurecer e a caixinha branca aparecer.
Ainda não fecha, vamos resolver isso agora.

Passo 8: Fechar o modal (botão X, clique fora e tecla ESC)

8.1 – Fechar pelo botão X

Adicione isto no script.js:

// Quando o usuário clicar no botão "X" dentro do modal
botaoFechar.addEventListener('click', fecharModal);

Teste:
Clique em “Abrir modal” e depois no “X”.
O modal deve fechar.

8.2 – Fechar ao clicar fora do modal

Vamos fazer com que, se o usuário clicar no fundo escuro, o modal também feche.

Adicione no script.js abaixo do código atual:

// Quando o usuário clicar no fundo escuro (overlay)
overlay.addEventListener('click', function (evento) {
    // Se o clique foi exatamente no overlay (e não dentro do modal)
    if (evento.target === overlay) {
        fecharModal();
    }
});

Por que essa verificação?

evento.target é o elemento onde o usuário clicou.

Se o clique foi na área escura, evento.target é o próprio overlay.

Se o clique foi dentro da caixa branca, o target é algum elemento dentro do modal, e não queremos fechar nesse caso.

Teste:
Abra o modal, clique fora da caixa (no fundo escuro).
O modal deve fechar.

Passo 9: Fechar com a tecla ESC (opcional, mas muito legal)

Vamos adicionar um atalho de teclado: fechar o modal com ESC.

Adicione ao script.js:

// Quando o usuário apertar alguma tecla
document.addEventListener('keydown', function (evento) {
    // Se a tecla for "Escape" (ESC) e o modal estiver aberto
    if (evento.key === 'Escape' && overlay.classList.contains('ativo')) {
        fecharModal();
    }
});

Entendendo:

document.addEventListener('keydown', ...)

Escuta qualquer tecla pressionada na página.

evento.key === 'Escape'

Verifica se a tecla foi o ESC.

overlay.classList.contains('ativo')

Confere se o modal está aberto.

Teste:
Abra o modal, aperte ESC no teclado.
O modal deve fechar.

Código completo para conferir

Se algo não funcionou, compare o seu código com este.

index.html

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <title>Exemplo de Modal com JavaScript</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>

    <h1>Exemplo de Modal com JavaScript</h1>

    <button id="abrir-modal">Abrir modal</button>

    <!-- Estrutura do modal -->
    <div id="modal-overlay" class="modal-overlay">
        <div class="modal">
            <button class="fechar-modal" aria-label="Fechar modal">&times;</button>
            <h2>Título do modal</h2>
            <p>Este é um exemplo de conteúdo dentro do modal.</p>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>

style.css

/* Layout básico da página */
body {
    margin: 0;
    padding: 0;
    font-family: Arial, sans-serif;
    background-color: #f2f2f2;
    color: #333;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

h1 {
    margin-bottom: 20px;
}

/* Botão que abre o modal */
#abrir-modal {
    padding: 10px 20px;
    font-size: 16px;
    cursor: pointer;
}

/* Fundo escuro por trás do modal */
.modal-overlay {
    position: fixed;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.5);
    display: none;
    align-items: center;
    justify-content: center;
}

/* Quando o modal estiver ativo */
.modal-overlay.ativo {
    display: flex;
}

/* Caixa branca do modal */
.modal {
    background-color: #fff;
    padding: 20px;
    border-radius: 6px;
    max-width: 400px;
    width: 90%;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
    position: relative;
}

/* Botão de fechar (X) */
.fechar-modal {
    position: absolute;
    top: 8px;
    right: 8px;
    border: none;
    background: transparent;
    font-size: 20px;
    cursor: pointer;
}

script.js

// Pegando os elementos do HTML
const botaoAbrir = document.querySelector('#abrir-modal');
const overlay = document.querySelector('#modal-overlay');
const botaoFechar = document.querySelector('.fechar-modal');
const modal = document.querySelector('.modal');

// Função para abrir o modal
function abrirModal() {
    overlay.classList.add('ativo');
}

// Função para fechar o modal
function fecharModal() {
    overlay.classList.remove('ativo');
}

// Abrir o modal ao clicar no botão
botaoAbrir.addEventListener('click', abrirModal);

// Fechar o modal ao clicar no "X"
botaoFechar.addEventListener('click', fecharModal);

// Fechar ao clicar no fundo escuro (fora da caixa do modal)
overlay.addEventListener('click', function (evento) {
    if (evento.target === overlay) {
        fecharModal();
    }
});

// Fechar ao apertar ESC
document.addEventListener('keydown', function (evento) {
    if (evento.key === 'Escape' && overlay.classList.contains('ativo')) {
        fecharModal();
    }
});

Quer aprender a organizar seus arquivos da forma correta?

Usar index.html, style.css e script.js já é um ótimo começo para manter seus projetos limpos e fáceis de entender — e é exatamente assim que começamos quando estamos aprendendo.
Mas conforme seus projetos crescem, a organização precisa crescer junto! Estruturas mais profissionais exigem pastas bem definidas, arquivos separados por função e um fluxo de trabalho pensado para evitar bagunça.

Quer aprender como organizar seus projetos web do jeito certo, mesmo como iniciante?
Acesse o guia completo:
https://vivendodeprogramacao.com.br/como-organizar-pastas-em-projetos-web

Esse conteúdo vai te mostrar como estruturar pastas, o que vai em cada lugar e como montar a base perfeita para qualquer projeto — do simples ao avançado.

Conclusão: o que você aprendeu

Neste passo a passo você viu:

  • Como montar a estrutura HTML de um modal
  • Como usar CSS para:
  • criar um fundo escuro
  • centralizar o modal com flex
  • esconder/mostrar o modal com classes
  • Como usar JavaScript para:
  • pegar elementos do HTML
  • criar funções de abrir/fechar
  • reagir a eventos de clique e teclado

Agora você pode:

  • Trocar o texto do modal
  • Mudar cores e tamanhos no CSS
  • Reaproveitar esse código em outros projetos

Isso significa que você não só copiou um código, você entendeu a lógica por trás de como um modal funciona e poderá melhorar e alterar de acordo com as necessidades dos seus projetos.

FAQ – Perguntas Frequentes sobre Como Criar um Modal com JavaScript

1. O que é exatamente um modal?

Um modal é uma pequena janela que aparece sobre o conteúdo principal da página, geralmente para exibir mensagens, formulários, avisos ou opções importantes. Ele impede que o usuário interaja com o restante da página até fechá-lo.

 

2. Por que o modal precisa de HTML, CSS e JavaScript separados?

Separar o código em três arquivos é uma boa prática porque:

O HTML cuida apenas da estrutura do conteúdo.

O CSS fica responsável pela aparência visual.

O JavaScript controla o comportamento do modal.

Isso deixa seu código mais organizado, fácil de entender e de manter — mesmo em projetos simples.

 

3. Posso criar um modal usando apenas HTML e CSS?

Até é possível criar um modal simples usando apenas HTML e CSS, mas isso limita bastante o comportamento.
Com JavaScript, você tem muito mais controle, como:

fechar ao clicar fora da caixa

fechar com a tecla ESC

adicionar animações

controlar múltiplos modais

Por isso, a versão ensinada no post usa JavaScript.

 

4. O modal não aparece quando clico no botão. O que fiz de errado?

As causas mais comuns são:

Erro no caminho dos arquivos (style.css ou script.js não carregaram)

IDs ou classes diferentes entre o HTML, CSS e JavaScript

Esquecer de adicionar o evento:

botaoAbrir.addEventListener('click', abrirModal);

Não ter criado a classe .ativo no CSS

Recomendo revisar o código e compará-lo com a seção “Código completo” do post.

 

5. O modal abre, mas não fecha. Como resolver?

Isso geralmente acontece quando:

O botão de fechar não tem a classe fechar-modal

O JavaScript não está pegando o botão certo

O evento não foi adicionado:

botaoFechar.addEventListener('click', fecharModal);

O overlay não recebeu o comportamento de fechar

Verifique se os nomes utilizados estão exatamente iguais aos do post.

 

6. Por que o modal usa display: none e depois display: flex?

Porque:

display: none esconde completamente o modal.

display: flex o mostra e ainda permite centralizar seu conteúdo.

Adicionar e remover a classe .ativo é uma forma simples e elegante de alternar entre esses dois estados.

 

7. Para que serve o evento.target no clique do overlay?

Ele identifica onde exatamente o usuário clicou.

A lógica é:

Se clicou no fundo escuro, o modal fecha.

Se clicou dentro da caixa branca, nada acontece.

Isso evita fechar o modal quando o usuário está tentando interagir com o conteúdo dele.

 

8. Preciso usar const no JavaScript?

Não obrigatoriamente, mas é recomendado.
Usar const deixa claro que você não quer alterar o valor daquela variável, o que evita erros e deixa o código mais profissional.

 

9. Posso usar esse modal em um projeto maior?

Sim!
Esse modal é simples, mas serve como base para qualquer projeto.
Porém, em projetos grandes você vai querer organizar melhor seus arquivos, criando pastas como:

/css /js /img /components

Para entender como organizar isso corretamente, veja o post recomendado no CTA.

 

10. É possível colocar animações quando o modal aparece?

Sim!
Você pode usar:

  • CSS transitions
  • CSS animations
  • JavaScript para adicionar efeitos

Por exemplo, adicionar uma animação de fade-in ou slide ao modal é bem simples.

 

11. Posso usar esse modal para exibir formulários?

Com certeza!
Basta substituir o conteúdo da <div class="modal"> por um formulário HTML.
O comportamento de abrir e fechar continuará funcionando da mesma forma.

 

12. Como faço para abrir o modal automaticamente quando a página carregar?

Basta chamar a função abrirModal() dentro do JavaScript:

window.addEventListener('load', abrirModal);

 

13. Como adicionar mais de um modal na mesma página?

Você precisa:

Criar estruturas HTML diferentes

Dar IDs diferentes para cada botão e para cada overlay

Criar funções que identifiquem qual modal abrir

Ou pode usar uma abordagem mais avançada, criando um modal “genérico” que muda o conteúdo dinamicamente.

 

14. Por que colocar o <script> no final do HTML?

Colocar o JavaScript antes de fechar o <body> garante que todo o HTML já foi carregado antes do script ser executado.
Assim, o JavaScript consegue “enxergar” os elementos corretamente.

 

15. Meu modal fica atrás de outros elementos. Como corrijo?

Isso é um problema de z-index.
No CSS, adicione ao overlay:

.modal-overlay {    z-index: 999; }

Assim ele fica acima de todo o conteúdo da página.

 

16. Como deixar o modal responsivo?

O exemplo já é responsivo porque usa:

max-width: 400px; width: 90%;

Isso faz com que ele se ajuste automaticamente em telas pequenas como celulares.

 

17. Posso reutilizar esse modal em outros projetos?

Sim — e deve!
Esse é um modal genérico, simples e eficiente, perfeito para ser usado em qualquer projeto pessoal ou acadêmico.

 

18. Como adicionar acessibilidade ao modal?

Você pode melhorar o modal com atributos como:

role="dialog" aria-modal="true"

E controlar o foco pelo JavaScript.
Isso ajuda leitores de tela e aumenta a acessibilidade.

 

19. Por que o ESC nem sempre fecha o modal?

Esse comportamento depende de:

O navegador estar com o foco ativo

O modal estar realmente aberto (classe .ativo presente)

Nenhum outro script estar bloqueando o evento

Se existir outro código na página usando keydown, pode haver conflito.

 

20. O modal trava a rolagem da página?

Este modelo não trava por padrão, mas você pode adicionar isso ao abrir o modal:

document.body.style.overflow = 'hidden';

E no fechar:

document.body.style.overflow = 'auto';