Modal Componentes
Janela que abre por cima da página, com fundo escurecido: confirmar, avisar, mostrar um formulário rápido. <div sw-modal id='aviso'> + <button sw-modal-open='#aviso'>.
O que é
O modal é aquela janelinha que aparece no meio da tela e escurece o resto: "Tem certeza que quer excluir?", "Deixe seu e-mail", "Veja os detalhes do plano". Você escreve a janela no HTML (ela fica escondida) com sw-modal e um id, e em qualquer botão da página coloca sw-modal-open="#id". Dentro, peças prontas: cabeçalho com título e ×, corpo e rodapé com os botões. Com palavras no valor de sw-modal você escolhe o tamanho, o jeito de entrar (deslizando, com zoom, como gaveta lateral) e o vidro.
O JavaScript do núcleo abre e fecha a janela colocando a classe is-active. Enquanto aberta: a rolagem da página trava, a tecla Tab fica presa dentro da janela, e ela fecha com Esc, com clique no fundo escuro, no × (sw-modal-cls) ou em qualquer coisa marcada com sw-modal-close. Ao fechar, o foco volta para o botão que abriu. Leitores de tela já recebem role="dialog" e aria-modal. Funciona no tema claro e no escuro.
Quando usar
- Confirmar ação importante: excluir, cancelar pedido, sair sem salvar.
- Formulário curto sem sair da página: newsletter, "me ligue", login rápido.
- Detalhes que não cabem no cartão: descrição de plano, política de troca, vídeo.
- Para aviso rápido que some sozinho, use o Alerta. Para painel lateral de filtros/carrinho, prefira o Panel.
Comece aqui
-
1
Coloque o SWCore na página: CSS no
<head>e JS no fim do<body>. O modal precisa dos dois.<link rel="stylesheet" href="https://swcore.sanweb.com.br/dist/2.1.0/swcore.min.css"> <!-- fim do <body> --> <script src="https://swcore.sanweb.com.br/dist/2.1.0/swcore.min.js"></script> -
2
Escreva o botão com
sw-modal-open="#id"e a janela com o mesmoid. O × e o "Cancelar" fecham porque têmsw-modal-close. Clique para testar.Agendar visita
Escolha um horário e um corretor entra em contato para confirmar.
<button type="button" sw-btn="pri" sw-modal-open="#agendar">Agendar visita</button> <div sw-modal id="agendar"> <div sw-modal-box> <div sw-modal-hdr> <h4 sw-modal-ttl>Agendar visita</h4> <button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button> </div> <div sw-modal-bdy><p>Escolha um horário e um corretor entra em contato para confirmar.</p></div> <div sw-modal-ftr> <button type="button" sw-btn="ghost" sw-modal-close>Cancelar</button> <button type="button" sw-btn="pri" sw-modal-close>Quero agendar</button> </div> </div> </div>
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. Tamanhos
Sem palavra de tamanho, a janela tem até 600 px de largura. pp 320 px, p 460 px, g 760 px, gg 960 px, xg 80% da tela (largura e altura), fl tela inteira. No celular todas ocupam a largura disponível.
Sair da conta?
Você vai precisar entrar de novo.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-t-pp">Abrir pp</button>
<div sw-modal="pp" id="mdl-t-pp">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Sair da conta?</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Você vai precisar entrar de novo.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="ghost" sw-modal-close>Cancelar</button>
<button type="button" sw-btn="pri" sw-modal-close>Confirmar</button>
</div>
</div>
</div>
Newsletter
Receba as promoções da semana no seu e-mail.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-t-p">Abrir p</button>
<div sw-modal="p" id="mdl-t-p">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Newsletter</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Receba as promoções da semana no seu e-mail.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="ghost" sw-modal-close>Cancelar</button>
<button type="button" sw-btn="pri" sw-modal-close>Confirmar</button>
</div>
</div>
</div>
Política de troca
Trocas em até 30 dias com a etiqueta. O frete da primeira troca é por nossa conta.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-t-m">Abrir padrão</button>
<div sw-modal id="mdl-t-m">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Política de troca</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Trocas em até 30 dias com a etiqueta. O frete da primeira troca é por nossa conta.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="ghost" sw-modal-close>Cancelar</button>
<button type="button" sw-btn="pri" sw-modal-close>Confirmar</button>
</div>
</div>
</div>
Plano Profissional
Site com até 10 páginas, blog, formulários, integração com WhatsApp e suporte mensal.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-t-g">Abrir g</button>
<div sw-modal="g" id="mdl-t-g">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Plano Profissional</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Site com até 10 páginas, blog, formulários, integração com WhatsApp e suporte mensal.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="ghost" sw-modal-close>Cancelar</button>
<button type="button" sw-btn="pri" sw-modal-close>Confirmar</button>
</div>
</div>
</div>
Comparar planos
Básico, Profissional e Empresa lado a lado — use o espaço para uma tabela.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-t-gg">Abrir gg</button>
<div sw-modal="gg" id="mdl-t-gg">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Comparar planos</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Básico, Profissional e Empresa lado a lado — use o espaço para uma tabela.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="ghost" sw-modal-close>Cancelar</button>
<button type="button" sw-btn="pri" sw-modal-close>Confirmar</button>
</div>
</div>
</div>
Contrato de serviço
Janela alta para textos longos: termos, contratos, relatórios.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-t-xg">Abrir xg</button>
<div sw-modal="xg" id="mdl-t-xg">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Contrato de serviço</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Janela alta para textos longos: termos, contratos, relatórios.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="ghost" sw-modal-close>Cancelar</button>
<button type="button" sw-btn="pri" sw-modal-close>Confirmar</button>
</div>
</div>
</div>
Galeria do imóvel
Ocupa a tela toda, sem cantos — bom no celular e para mídia.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-t-fl">Abrir fl</button>
<div sw-modal="fl" id="mdl-t-fl">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Galeria do imóvel</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Ocupa a tela toda, sem cantos — bom no celular e para mídia.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="ghost" sw-modal-close>Cancelar</button>
<button type="button" sw-btn="pri" sw-modal-close>Confirmar</button>
</div>
</div>
</div>
2. Jeito de entrar
Sem palavra, a janela cresce levemente ao abrir. sld desce do alto, zoo nasce pequena e cresce, drw vira uma gaveta que entra pela direita, na altura toda da tela.
Pedido enviado
Você vai receber a confirmação por e-mail.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-e-pad">Abrir</button>
<div sw-modal id="mdl-e-pad">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Pedido enviado</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Você vai receber a confirmação por e-mail.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="pri" sw-modal-close>Ok</button>
</div>
</div>
</div>
Cupom liberado
Use VOLTA10 e ganhe 10% na próxima compra.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-e-sld">Abrir sld</button>
<div sw-modal="sld" id="mdl-e-sld">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Cupom liberado</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Use VOLTA10 e ganhe 10% na próxima compra.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="pri" sw-modal-close>Ok</button>
</div>
</div>
</div>
Parabéns!
Seu cadastro foi concluído.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-e-zoo">Abrir zoo</button>
<div sw-modal="zoo" id="mdl-e-zoo">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Parabéns!</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Seu cadastro foi concluído.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="suc" sw-modal-close>Começar</button>
</div>
</div>
</div>
Filtros
Tamanho, cor e faixa de preço ficariam aqui.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-e-drw">Abrir drw</button>
<div sw-modal="drw" id="mdl-e-drw">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Filtros</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Tamanho, cor e faixa de preço ficariam aqui.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="ghost" sw-modal-close>Limpar</button>
<button type="button" sw-btn="pri" sw-modal-close>Aplicar</button>
</div>
</div>
</div>
3. Vidro e combinações
gls deixa a caixa translúcida, mostrando a página desfocada atrás. As palavras se combinam no mesmo atributo, em qualquer ordem: tamanho + entrada + vidro.
Assista ao vídeo
Conheça a clínica em 1 minuto.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-c-gls">Abrir gls</button>
<div sw-modal="gls" id="mdl-c-gls">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Assista ao vídeo</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Conheça a clínica em 1 minuto.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="glass" sw-modal-close>Fechar</button>
</div>
</div>
</div>
Excluir foto?
A foto sai da galeria do seu site.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-c-psld">Abrir p sld</button>
<div sw-modal="p sld" id="mdl-c-psld">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Excluir foto?</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>A foto sai da galeria do seu site.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="ghost" sw-modal-close>Manter</button><button type="button" sw-btn="err" sw-modal-close>Excluir</button>
</div>
</div>
</div>
Tudo certo
Dados salvos.
<button type="button" sw-btn="pri p" sw-modal-open="#mdl-c-all">Abrir pp zoo gls</button>
<div sw-modal="pp zoo gls" id="mdl-c-all">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Tudo certo</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>Dados salvos.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="pri" sw-modal-close>Ok</button>
</div>
</div>
</div>
4. Peças opcionais
Só a caixa sw-modal-box é obrigatória. Cabeçalho, corpo e rodapé são opcionais — use o que precisar. Sem o ×, a pessoa fecha pelo fundo, pelo Esc ou por um botão com sw-modal-close.
Clique no fundo escuro ou aperte Esc para fechar.
<button type="button" sw-btn="pri p" sw-modal-open="#simples">Abrir simples</button>
<div sw-modal="p" id="simples">
<div sw-modal-box>
<p>Clique no fundo escuro ou aperte Esc para fechar.</p>
</div>
</div>
Termos de uso
1. O serviço é prestado conforme o plano contratado.
2. O pagamento é mensal, com vencimento todo dia 10.
3. O cancelamento pode ser pedido a qualquer momento, sem multa.
4. Os dados são tratados conforme a LGPD.
5. Backups diários são mantidos por 30 dias.
6. O suporte atende de segunda a sexta, das 9h às 18h.
7. Alterações nestes termos são avisadas por e-mail.
8. Fica eleito o foro da comarca de Belo Horizonte.
<!-- o corpo (sw-modal-bdy) rola sozinho quando passa de 60% da altura da tela -->
<div sw-modal id="termos">
<div sw-modal-box>
<div sw-modal-hdr>…</div>
<div sw-modal-bdy>…texto longo…</div>
<div sw-modal-ftr><button type="button" sw-btn="pri" sw-modal-close>Li e aceito</button></div>
</div>
</div>
Tabela de opções
| Palavra | O que faz | Exemplo |
|---|---|---|
| Peças | ||
sw-modal | O fundo escuro que cobre a tela; precisa de um id. O valor recebe as palavras de tamanho/efeito. | <div sw-modal id="aviso"> |
sw-modal-box | A caixa branca/escura da janela. Obrigatória. | <div sw-modal-box> |
sw-modal-hdr | Cabeçalho (título à esquerda, × à direita). | <div sw-modal-hdr> |
sw-modal-ttl | Título. | <h4 sw-modal-ttl> |
sw-modal-cls | Desenha o × e fecha ao clicar (sozinho já basta; com sw-modal-close junto continua valendo). | <button sw-modal-cls sw-modal-close aria-label="Fechar"> |
sw-modal-bdy | Corpo; rola se passar de 60% da altura da tela. | <div sw-modal-bdy> |
sw-modal-ftr | Rodapé com os botões, alinhados à direita. | <div sw-modal-ftr> |
| Abrir e fechar | ||
sw-modal-open | Em qualquer botão/link: abre o modal do id indicado (começando com #). | <button sw-modal-open="#aviso"> |
sw-modal-close | Em qualquer elemento dentro do modal: clicar nele fecha. | <button sw-modal-close> |
(clique no fundo) | Clicar fora da caixa fecha. | |
Esc | A tecla Esc fecha. | |
autofocus | Num campo dentro do modal: recebe o cursor ao abrir. | <input sw-inp autofocus> |
| Tamanho | ||
pp | Até 320 px. | sw-modal="pp" |
p | Até 460 px. | sw-modal="p" |
(nenhum) | Até 600 px. | sw-modal |
g | Até 760 px. | sw-modal="g" |
gg | Até 960 px. | sw-modal="gg" |
xg | 80% da largura e da altura da tela. | sw-modal="xg" |
fl | Tela inteira, sem cantos. | sw-modal="fl" |
| Entrada | ||
(nenhum) | Cresce de leve. | |
sld | Desce do alto. | sw-modal="sld" |
zoo | Zoom: nasce pequena e cresce. | sw-modal="zoo" |
drw | Gaveta pela direita, altura toda (420 px de largura). | sw-modal="drw" |
| Visual | ||
gls | Caixa de vidro translúcido. | sw-modal="gls" |
Receitas prontas — usos reais
Situações que aparecem em quase todo site. Copie a que servir.
Excluir "Maria Souza"?
O histórico de agendamentos dela também será apagado. Não dá para desfazer.
<button type="button" sw-btn="err out" sw-modal-open="#excluir"><i class="swi-trash"></i> Excluir cliente</button>
<div sw-modal="p sld" id="excluir">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>Excluir "Maria Souza"?</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<div sw-modal-bdy><p>O histórico de agendamentos dela também será apagado. Não dá para desfazer.</p></div>
<div sw-modal-ftr>
<button type="button" sw-btn="ghost" sw-modal-close>Manter</button>
<button type="button" sw-btn="err" id="confirmar-exclusao"><i class="swi-trash"></i> Excluir de vez</button>
</div>
</div>
</div>
<script>
document.getElementById('confirmar-exclusao').addEventListener('click', async () => {
await fetch('/admin/clientes/42', { method: 'DELETE' });
SW.Modal.hide('#excluir');
SW.Alert.ok('Cliente excluído.');
});
</script>
A gente te liga
<button type="button" sw-btn="suc" sw-modal-open="#me-liga"><i class="swi-phone"></i> Quero que me liguem</button>
<div sw-modal="p" id="me-liga">
<div sw-modal-box>
<div sw-modal-hdr>
<h4 sw-modal-ttl>A gente te liga</h4>
<button type="button" sw-modal-cls sw-modal-close aria-label="Fechar"></button>
</div>
<form sw-frm action="/me-liga" method="post">
<div sw-fld><label for="nome">Nome</label><input sw-inp id="nome" name="nome" autofocus></div>
<div sw-fld><label for="tel">Telefone</label><input sw-inp id="tel" name="tel" type="tel"></div>
<div sw-modal-ftr><button type="submit" sw-btn="suc">Pedir ligação</button></div>
</form>
</div>
</div>
<div sw-modal="p zoo" id="promo">
<div sw-modal-box>…Cupom BEMVINDO10…</div>
</div>
<script>
document.addEventListener('sw:ready', () => {
if (localStorage.getItem('promo-vista')) return;
setTimeout(() => SW.Modal.show('#promo'), 3000); // abre depois de 3 segundos
localStorage.setItem('promo-vista', '1');
});
</script>
const video = document.getElementById('modal-video');
video.addEventListener('sw:modal:open', () => {
video.querySelector('video').play();
});
video.addEventListener('sw:modal:close', () => {
video.querySelector('video').pause(); // não deixa o vídeo tocando escondido
});
Eventos
sw:modal:open[sw-modal] quando ele abre.sw:modal:close[sw-modal] quando ele fecha (por qualquer caminho, inclusive se ele sair da página ainda aberto).API (JavaScript)
SW.Modal.show('#id')true se abriu, false se já estava aberto ou não existe.SW.Modal.hide('#id')true se fechou.SW.Modal.initAll(raiz)sw-modal-open e os modais dentro de raiz. O núcleo já faz sozinho.Precisa de quê
swcore.min.css+swcore.min.js.swcore.compl.min.css— só se usar íconesswi-*nos botões.
Cuidados — erros comuns
sw-modal-opensem o#(sw-modal-open="aviso"): não abre. Tem que ser"#aviso".- Dois modais com o mesmo
id: o botão sempre abre o primeiro. - Botão "Salvar" dentro de um
<form>no modal comsw-modal-close: fecha antes de você tratar o envio. Feche pelo código (SW.Modal.hide) depois de salvar. - Usar
SWModal.show(): o nome certo éSW.Modal.show().
O que ele não faz
- Não dá para impedir o fechamento pelo fundo escuro ou pelo Esc (não existe modo "obrigatório").
- Não abre um modal dentro de outro de forma organizada (o segundo fica por cima, mas o Esc fecha os dois).
- Não carrega conteúdo de outra página sozinho: o HTML da janela precisa estar na página (ou ser colocado por você antes de abrir).

