Modal nativo (sw-dialog) CSS
A janela de confirmação do próprio navegador, com entrada e saída animadas, fundo desfocado e a página travada atrás. Abrir é uma linha.
O que é
É a janelinha que aparece no meio da tela pedindo uma resposta: "Confirmar agendamento?", "Excluir este produto?", "Preencha seus dados". O HTML já tem uma peça para isso, o <dialog>: ele prende o foco dentro, fecha com Esc e avisa o leitor de tela. O sw-dialog dá o visual do SW Core, a animação de entrada e saída, escurece e desfoca o fundo e trava a rolagem da página enquanto está aberto. Tem dois formatos: central (padrão) e lateral (gaveta entrando pela direita).
Para abrir, uma linha de JavaScript: document.getElementById('id').showModal(). Para fechar, nenhuma: qualquer botão dentro de um <form method="dialog"> fecha o modal, e o value desse botão fica guardado em returnValue (assim você sabe se a pessoa clicou em "Confirmar" ou "Voltar"). É a opção leve para sites; o sw-modal continua existindo para os sistemas que já usam.
Quando usar
- Confirmar uma ação (agendar, excluir, cancelar pedido):
sw-dialogcentral com dois botões. - Formulário curto sem sair da página (orçamento, newsletter, login):
sw-dialogcom o formulário dentro. - Carrinho, detalhes, menu no celular: gaveta
sw-dialog="lateral". - Aviso que não precisa de resposta ("Salvo!")? Use o sw-popover "toast", que não trava a página.
Comece aqui
-
1
Coloque o SW Core no
<head>. Osw-dialogestá no arquivo principal.<link rel="stylesheet" href="swcore/swcore.min.css"> -
2
Escreva o
<dialog sw-dialog>com umid, um botão que chamashowModal()e, dentro, um<form method="dialog">com o botão de fechar. Clique para abrir; feche pelo botão ou com Esc.<button sw-btn="pri" onclick="document.getElementById('reserva').showModal()">Agendar horário</button> <dialog id="reserva" sw-dialog> <h3 class="mt-0">Horário reservado!</h3> <p>Terça, 14h — Corte + barba. Enviamos a confirmação no seu WhatsApp.</p> <form method="dialog"><button sw-btn="pri">Fechar</button></form> </dialog>
Todas as variações
Cada quadro abaixo é o componente de verdade, rodando. O código embaixo é exatamente o que está no quadro: copie e cole.
1. Formatos
Clique nos botões. O modal sai do quadro e abre por cima da página inteira.
<button sw-btn="pri" onclick="document.getElementById('confirma').showModal()">Abrir central</button>
<dialog id="confirma" sw-dialog>
<h3 class="mt-0">Confirmar agendamento?</h3>
<p>Terça, 14h — Corte + barba.</p>
<form method="dialog" class="flx gap-2">
<button sw-btn="pri" value="sim">Confirmar</button>
<button sw-btn="ghost" value="nao">Voltar</button>
</form>
</dialog>
<button sw-btn="pri out" onclick="document.getElementById('pedido').showModal()">Abrir lateral</button>
<dialog id="pedido" sw-dialog="lateral">
<h3 class="mt-0">Detalhes do pedido</h3>
<p>Pedido #1041 — 2 itens — R$ 388,00</p>
<p class="t-mut">Entrega prevista: sexta-feira.</p>
<form method="dialog"><button sw-btn="pri">Fechar</button></form>
</dialog>
2. Saber o que a pessoa escolheu
O value do botão que fechou fica em returnValue. O evento close avisa quando fechou. Abra, escolha e veja a resposta embaixo do botão.
Nenhuma escolha ainda.
<button sw-btn="err" id="btn-excluir"><i class="swi-trash"></i> Excluir produto</button>
<dialog id="excluir" sw-dialog>
<h3 class="mt-0">Excluir "Sapato social"?</h3>
<p>Essa ação não pode ser desfeita.</p>
<form method="dialog" class="flx gap-2">
<button sw-btn="err" value="excluir">Excluir de vez</button>
<button sw-btn="ghost" value="manter">Manter</button>
</form>
</dialog>
<script>
const dlg = document.getElementById('excluir');
document.getElementById('btn-excluir').onclick = () => {
dlg.returnValue = ''; // zera a resposta anterior
dlg.showModal();
};
dlg.addEventListener('close', () => {
if (dlg.returnValue === 'excluir') { /* apague o produto aqui */ }
});
</script>
Tabela de opções
| Palavra | O que faz | Exemplo |
|---|---|---|
| No <dialog> — formato (sw-dialog) | ||
(nenhum) | Central, até 52rem de largura, com fundo escurecido e desfocado. | <dialog sw-dialog> |
lateral | Gaveta na direita, altura total da tela, entrando de lado. | <dialog sw-dialog="lateral"> |
| Para fechar (do HTML) | ||
<form method="dialog"> | Qualquer botão dentro deste formulário fecha o modal. Não precisa de JavaScript. | <form method="dialog">…</form> |
value (no botão) | O que fica guardado em returnValue quando esse botão fecha o modal. | <button value="sim"> |
Tecla Esc | Fecha sempre. O returnValue não muda (continua com o valor da vez anterior) — por isso zere ele antes de abrir. | dialog.returnValue = '' |
| O que já vem pronto | ||
Fundo | Escurecido e desfocado atrás do modal. | |
Rolagem | A página de trás fica travada enquanto o modal está aberto. | |
Foco | O teclado fica preso dentro do modal; ao fechar, volta para o botão que abriu. | |
Receitas prontas — usos reais
Situações que aparecem em quase todo site. Copie a que servir.
<button sw-btn="suc g" onclick="document.getElementById('orcamento').showModal()">Pedir orçamento</button>
<dialog id="orcamento" sw-dialog>
<h3 class="mt-0">Peça seu orçamento</h3>
<form method="dialog" class="flx f-cl gap-3">
<div sw-fld><label for="nome">Nome</label><input id="nome" sw-inp placeholder="Seu nome"></div>
<div sw-fld><label for="zap">WhatsApp</label><input id="zap" sw-inp placeholder="(11) 99999-9999"></div>
<div class="flx gap-2">
<button sw-btn="suc" value="enviar">Enviar</button>
<button sw-btn="ghost" value="cancelar">Cancelar</button>
</div>
</form>
</dialog>
<!-- para enviar de verdade ao servidor, troque method="dialog" pelo seu
envio (action/AJAX) e feche com document.getElementById('orcamento').close() -->
<button sw-btn="pri" onclick="document.getElementById('carrinho').showModal()"><i class="swi-cart"></i> Carrinho (2)</button>
<dialog id="carrinho" sw-dialog="lateral">
<h3 class="mt-0">Seu carrinho</h3>
<p class="flx j-sb"><span>Sapato social</span><strong>R$ 239,00</strong></p>
<p class="flx j-sb"><span>Kit viagem</span><strong>R$ 149,00</strong></p>
<p class="flx j-sb bd-t bd-mut pt-3"><span>Total</span><strong>R$ 388,00</strong></p>
<form method="dialog" class="flx gap-2">
<button sw-btn="ghost">Continuar comprando</button>
<a href="/checkout" sw-btn="suc">Finalizar</a>
</form>
</dialog>
<button sw-btn="sec" onclick="document.getElementById('foto').showModal()">Ver foto ampliada</button>
<dialog id="foto" sw-dialog>
<div class="ar-4-3 r-m ov-hi"><img src="/cachoeira.jpg" alt="Cachoeira" class="media-fill"></div>
<p class="m-0 mt-2 t-mut t-p">Clique no fundo escuro para fechar.</p>
</dialog>
<script>
// o clique no fundo escuro chega no próprio <dialog>, FORA da caixa dele
const foto = document.getElementById('foto');
foto.addEventListener('click', (e) => {
const r = foto.getBoundingClientRect();
const fora = e.clientX < r.left || e.clientX > r.right || e.clientY < r.top || e.clientY > r.bottom;
if (fora) foto.close();
});
</script>
Eventos
close<dialog>: dispara quando fecha (por botão, Esc ou close()). Leia dialog.returnValue para saber qual botão fechou.cancelevent.preventDefault() impede o fechamento.API (JavaScript)
dialog.showModal()dialog.close(valor?)returnValue.dialog.returnValuevalue do botão que fechou (ou o passado em close()).dialog.opentrue se está aberto.Precisa de quê
swcore.min.css(2.1.0 ou mais novo) — visual, animação, fundo e trava da rolagem.swcore.compl.min.css— só se usar os íconesswi-*dentro.- O
<dialog>é do navegador (Chrome, Edge, Firefox e Safari atuais). A animação só aparece nos que já suportam; nos outros abre sem animar.
Cuidados — erros comuns
- Use
showModal(), nãoshow(): oshow()abre sem fundo, sem travar a página e sem prender o foco. - Não escreva
<dialog open>no HTML para "já abrir": assim ele abre como caixa comum, não como modal. Para abrir ao carregar, chameshowModal()no seu script. - O botão de fechar precisa estar dentro do
<form method="dialog">. Botão fora do form não fecha. - Um
<form method="dialog">não envia nada ao servidor — ele só fecha. Para enviar de verdade, use o seu envio (AJAX ouaction) e feche comclose(). - Clicar no fundo escuro não fecha por padrão (é do navegador). Se quiser, use o script da receita "Fechar também ao clicar fora".
- Cada modal precisa de um
idúnico na página.
O que ele não faz
- A gaveta lateral sai só pela direita.
- Um tamanho só para o central (até 52rem de largura, 90% da altura). Não há classes de tamanho.
- Nos sistemas que já usam o sw-modal (com JS, tamanhos e API própria), continue com ele — o
sw-dialognão o substitui.

