Menu, aviso e painel (sw-popover) CSS
Menu suspenso, aviso no canto e painel lateral que abrem com um botão e fecham sozinhos (Esc ou clique fora) — sem JavaScript.
O que é
O navegador tem um recurso próprio para "caixinhas que abrem por cima de tudo": o atributo popover. Um botão com popovertarget="id" abre e fecha a caixa; ela fecha sozinha com a tecla Esc ou clicando fora, e funciona com teclado e leitor de tela. O sw-popover dá a roupa do SW Core e a animação de entrada, em três formatos prontos: menu (lista de links embaixo do botão), toast (aviso no canto de baixo) e painel (gaveta lateral com o fundo escurecido).
São três peças: o botão (popovertarget="meu-id"), a caixa (id="meu-id" popover sw-popover="menu") e nada mais. O navegador cuida de abrir, fechar e deixar por cima de tudo; o SW Core cuida do visual, que segue o tema claro/escuro. Em navegador sem a animação de entrada, a caixa abre e fecha sem animar — continua funcionando.
Quando usar
- Menu do usuário no topo (Meu perfil, Configurações, Sair):
sw-popover="menu". - Aviso rápido ("Salvo!", "Copiado!", "Item no carrinho"):
sw-popover="toast". - Filtros da loja, carrinho, menu no celular: gaveta lateral
sw-popover="painel". - Precisa que a caixa fique colada no botão? Use a Dica ancorada ou o Dropdown. Precisa de confirmação que bloqueia a página? Use o Modal nativo.
Comece aqui
-
1
Coloque o SW Core no
<head>. Osw-popoverestá no arquivo principal. Não precisa de JavaScript.<link rel="stylesheet" href="swcore/swcore.min.css"> -
2
Um botão aponta para o
idda caixa compopovertarget. A caixa levapopover(do navegador) esw-popovercom o formato. Clique — e clique fora ou aperte Esc para fechar.Horário salvo!<button sw-btn="pri" popovertarget="aviso">Mostrar aviso</button> <div id="aviso" popover sw-popover="toast"><i class="swi-check-circle"></i> Horário salvo!</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. Os três formatos
Clique nos botões. O menu abre embaixo do botão que o chamou; o aviso fica no canto de baixo à direita da janela e o painel na lateral direita.
<button sw-btn="pri" popovertarget="conta">Minha conta <i class="swi-chevron-down"></i></button>
<div id="conta" popover sw-popover="menu">
<a href="/perfil"><i class="swi-user"></i> Meu perfil</a>
<a href="/config"><i class="swi-cog"></i> Configurações</a>
<button popovertarget="conta"><i class="swi-log-out"></i> Sair</button>
</div>
<button sw-btn="suc" popovertarget="salvo">Salvar</button>
<div id="salvo" popover sw-popover="toast"><i class="swi-check-circle"></i> Alterações salvas.</div>
Filtros
<button sw-btn="pri out" popovertarget="filtros"><i class="swi-filter"></i> Filtros</button>
<div id="filtros" popover sw-popover="painel">
<h3 class="mt-0">Filtros</h3>
<p><label sw-chk><input type="checkbox"> Até R$ 100</label></p>
<p><label sw-chk><input type="checkbox"> Frete grátis</label></p>
<button sw-btn="pri" popovertarget="filtros">Ver resultados</button>
</div>
2. Como fecha
popover sozinho fecha com Esc e com clique fora. popover="manual" só fecha pelo botão — bom para aviso que a pessoa precisa ler.
<button sw-btn="sec" popovertarget="aviso">Abrir aviso</button>
<div id="aviso" popover sw-popover="toast">Clique em qualquer lugar para fechar.</div>
<button sw-btn="ale" popovertarget="sessao">Abrir aviso fixo</button>
<div id="sessao" popover="manual" sw-popover="toast">
<i class="swi-error"></i> Sua sessão expira em 5 minutos.
<button sw-btn="ghost p" popovertarget="sessao" popovertargetaction="hide">Entendi</button>
</div>
3. O que o botão faz
Por padrão o mesmo botão abre e fecha. Com popovertargetaction ele só abre ou só fecha.
<button sw-btn="suc p" popovertarget="aviso" popovertargetaction="show">Só abre</button>
<button sw-btn="err p" popovertarget="aviso" popovertargetaction="hide">Só fecha</button>
<div id="aviso" popover="manual" sw-popover="toast">Aberto pelo botão "Só abre".</div>
Tabela de opções
| Palavra | O que faz | Exemplo |
|---|---|---|
| Na caixa — formato (sw-popover) | ||
(nenhum) | Caixa no meio da tela. | sw-popover |
menu | Lista de links/botões embaixo do botão que abriu (alinhada pela direita; se não couber, vira para o outro lado). Aberto por código sem botão, ou em navegador sem "posicionamento por âncora", fica no canto de cima à direita da janela (6rem do topo). Links e botões dentro ganham o estilo de item de menu. | sw-popover="menu" |
toast | Aviso no canto de baixo à direita da janela. | sw-popover="toast" |
painel | Gaveta lateral na direita, altura total, com o fundo escurecido e desfocado atrás. | sw-popover="painel" |
| Na caixa — comportamento (do navegador) | ||
popover | Liga o recurso. Fecha com Esc e clique fora; abrir outro fecha este. | <div id="x" popover sw-popover="menu"> |
popover="manual" | Só fecha pelo botão (ou por código). Vários podem ficar abertos juntos. | <div id="x" popover="manual"> |
id | Obrigatório: é o nome que o botão usa para achar a caixa. | id="menu-conta" |
| No botão (do navegador) | ||
popovertarget | O id da caixa que ele abre/fecha. Só funciona em <button>. | <button popovertarget="x"> |
popovertargetaction | O que o botão faz: toggle (abre e fecha — padrão), show (só abre) ou hide (só fecha). | popovertargetaction="hide" |
Receitas prontas — usos reais
Situações que aparecem em quase todo site. Copie a que servir.
<header class="flx j-sb alc">
<strong>Minha Loja · Painel</strong>
<button sw-btn="ghost" popovertarget="menu-usuario"><i class="swi-user-circle"></i> Ana</button>
</header>
<div id="menu-usuario" popover sw-popover="menu">
<a href="/perfil"><i class="swi-user"></i> Meu perfil</a>
<a href="/pedidos"><i class="swi-package"></i> Meus pedidos</a>
<a href="/config"><i class="swi-cog"></i> Configurações</a>
<button popovertarget="menu-usuario"><i class="swi-log-out"></i> Sair</button>
</div>
<button sw-btn="pri" id="copiar"><i class="swi-copy"></i> Copiar chave Pix</button>
<div id="copiado" popover="manual" sw-popover="toast"><i class="swi-check-circle"></i> Chave Pix copiada!</div>
<script>
const aviso = document.getElementById('copiado');
document.getElementById('copiar').addEventListener('click', () => {
navigator.clipboard.writeText('12.345.678/0001-90');
aviso.showPopover(); // abre
setTimeout(() => aviso.hidePopover(), 2500); // fecha em 2,5 s
});
</script>
<button sw-btn="suc" popovertarget="carrinho"><i class="swi-cart"></i> Carrinho (2)</button>
<div id="carrinho" popover sw-popover="painel">
<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>
<div class="flx gap-2">
<button sw-btn="ghost" popovertarget="carrinho">Continuar comprando</button>
<a href="/checkout" sw-btn="suc">Finalizar</a>
</div>
</div>
Eventos
beforetoggleevent.newState diz "open" ou "closed".toggleevent.newState.API (JavaScript)
caixa.showPopover()caixa.hidePopover()caixa.togglePopover()caixa.matches(':popover-open')true/false).Precisa de quê
swcore.min.css(2.1.0 ou mais novo) — o visual e a animação.swcore.compl.min.css— só se usar os íconesswi-*dentro.- O abrir/fechar é do navegador: funciona em Chrome, Edge, Firefox e Safari atuais. A animação de entrada só aparece nos que já suportam; nos outros abre sem animar.
Cuidados — erros comuns
sw-popoversemmenu,toastoupainelabre no meio da tela — bom para um aviso rápido; para caixa grande com formulário, prefira o Modal nativo.- O
menusó fica embaixo do botão quando é aberto pelopopovertargetdesse botão. Aberto por código (showPopover()), ele não sabe de qual botão veio e vai para o canto de cima à direita da janela. popovertargetsó funciona em<button>(e<input type="button">). Num<a>ou<div>não faz nada.- O
iddo botão e o da caixa têm que ser iguais e únicos na página. Dois elementos com o mesmo id = o botão abre o errado. - Não escreva só
sw-popoversem o atributopopover: sem ele a caixa não abre nem esconde (osw-popoveré só o visual). - O
toastnão some sozinho. Para sumir depois de alguns segundos, use as 3 linhas da receita "Copiado!" — ou o componente SWAlert, que já faz fila de avisos.
O que ele não faz
- O painel sai só pela direita. Não há versão pela esquerda.
- Não há fila de avisos nem tempo automático — é uma caixa só. Para isso existe o SWAlert.
- Não prende o foco dentro nem trava a rolagem da página (o Modal nativo faz isso).
- O menu embaixo do botão usa o "posicionamento por âncora" do navegador (Chrome e Edge atuais e os que já suportam). Nos outros, o menu abre no canto de cima à direita da janela — continua funcionando.

