</> HTML5Advent
ENFRESDEITPT

// html · Web Platform Advent #16

A Popover API: popups, menus e tooltips nativos sem biblioteca

O atributo HTML popover e a Popover API permitem criar menus, tooltips e cartões renderizados na camada de topo, com fecho ao clicar fora e Esc já tratados por si - sem biblioteca JavaScript.

Maquetes de páginas web abertas numa app de design num monitor

A Popover API é a resposta integrada do navegador a um problema que todo o programador já resolveu à mão cem vezes: mostrar um pequeno pedaço de UI - um menu, um tooltip, um cartão, uma notificação - por cima de tudo o resto e fechá-lo de novo de forma limpa. Com o atributo popover e uma minúscula interface JavaScript, obtém a camada de topo, o fecho leve e o tratamento de Esc grátis, sem biblioteca. Eis como funciona.

O popover mais simples

Qualquer elemento se torna um popover ao adicionar o atributo popover. Um botão abre-o com popovertarget a apontar para o id do popover:

<button popovertarget="menu">Open menu</button>

<div id="menu" popover>
  <p>I am a popover. Click outside or press Esc to close me.</p>
</div>

É tudo. Sem tratador de clique, sem z-index, sem escuta de clique fora. O navegador renderiza o popover na camada de topo (por cima de toda a página, sem guerras de z-index) e fecha-o com Esc ou um clique fora.

auto vs manual

Existem dois tipos de popover, e a diferença é quem os fecha:

<!-- auto: light-dismiss, only one open in a stack -->
<div id="tip" popover="auto">...</div>

<!-- manual: you open and close it yourself -->
<div id="toast" popover="manual">...</div>

Um popover auto suporta fecho leve: Esc ou um clique fora fecha-o, e abrir um novo fecha o anterior na mesma pilha. Um popover manual ignora tudo isso e permanece aberto até o seu código o esconder - a escolha certa para um toast ou um painel persistente.

Um editor de código num portátil a mostrar um tooltip para uma variável
Um editor de código a mostrar um tooltip para uma variável - exatamente o tipo de pequena UI sobreposta que a Popover API agora constrói de forma nativa na web.

Controlá-lo a partir do JavaScript

Quando precisa de abrir ou fechar um popover em código, três métodos fazem o trabalho, mais um evento toggle para reagir a mudanças de estado:

const menu = document.getElementById("menu");
menu.showPopover();     // open it
menu.hidePopover();     // close it
menu.togglePopover();   // flip it

menu.addEventListener("toggle", (e) => {
  console.log(e.newState); // "open" or "closed"
});

Há também um evento beforetoggle que dispara mesmo antes da mudança de estado, útil para carregar conteúdo de forma preguiçosa ou executar uma animação de entrada.

Estilo e posicionamento

Estilize um popover enquanto está aberto com a pseudo-classe :popover-open, e a camada escurecida atrás de um popover auto com ::backdrop:

[popover]:popover-open {
  /* styles while the popover is shown */
}

[popover]::backdrop {
  /* the layer behind an auto popover */
  background: rgb(0 0 0 / 0.3);
}

Para colocar um popover junto ao botão que o abriu - como um verdadeiro menu suspenso - combine-o com o posicionamento por âncora CSS (anchor()) em vez de medir coordenadas em JavaScript. As duas funcionalidades foram desenhadas para trabalhar juntas.

Quando usá-la (e quando não)

Recorra à Popover API para UI transitória e sobreposta: menus suspensos, tooltips, dicas contextuais, cartões pequenos e notificações. Para uma caixa de diálogo modal bloqueante que deve capturar o foco e parar a interação com a página, o elemento <dialog> continua a ser a melhor ferramenta. Veja-os como complementares: popovers para sobreposições leves, dialogs para verdadeiras modais.

Conclusão

A Popover API transforma um monte de JavaScript escrito à mão - renderização na camada de topo, deteção de clique fora, tratamento de Esc, malabarismo de foco - num único atributo HTML mais três métodos. Use auto para menus e tooltips, manual para a UI que controla, estilize com :popover-open e combine-a com o posicionamento por âncora para menus suspensos reais. É suportada pelos navegadores modernos hoje, por isso a maioria dos sites pode adotá-la sem polyfill.

Perguntas frequentes

O que é a Popover API?
A Popover API é uma funcionalidade integrada do navegador para mostrar conteúdo por cima da página - menus, tooltips, cartões, notificações - sem biblioteca JavaScript. Adiciona o atributo popover a um elemento e aponta um botão para ele com popovertarget. O navegador trata então da renderização na camada de topo, do fecho com Esc ou um clique fora, e da ligação básica de acessibilidade.
Qual é a diferença entre popover auto e manual?
Um popover auto (popover ou popover="auto") suporta fecho leve: fecha ao premir Esc ou clicar fora, e abrir outro popover auto fecha o anterior na mesma pilha. Um popover manual (popover="manual") não faz nada disso - permanece aberto até o seu código chamar hidePopover(). Use auto para menus e tooltips, manual para coisas como toasts que controla.
Ainda preciso do elemento dialog ou de uma biblioteca?
Para a maioria da UI sobreposta - menus, tooltips, cartões - a Popover API substitui o JavaScript que escrevia. Para uma verdadeira caixa de diálogo modal que bloqueia a página e captura o foco, o elemento <dialog> continua a ser a melhor escolha. E para posicionar um popover junto ao seu acionador, combine-o com o posicionamento por âncora CSS em vez de calcular coordenadas.
A Popover API é suportada pelos navegadores?
Sim. A Popover API faz parte do padrão HTML e é suportada pelos principais motores - navegadores Chromium, Safari e Firefox. Como sempre, verifique as suas próprias analíticas, e para navegadores muito antigos pode adicionar um pequeno fallback, mas para públicos modernos pode usá-la diretamente.