- Com apenas recursos nativos do navegador, é possível criar uma UI de popover que aparece sobre a página, permitindo implementar padrões como menus, sugestões e notificações de forma mais consistente
- Os popovers da Popover API são sempre não modais, portanto `` é mais adequado para UIs que precisam bloquear a interação com a página
- Alternâncias simples podem ser feitas com atributos HTML como
popover, popovertarget e popovertargetaction, e, quando necessário, o estado de exibição pode ser controlado com métodos JavaScript
- É possível lidar com estilo e mudanças de estado com
::backdrop, :popover-open, beforetoggle, toggle etc., e os interest invokers oferecem suporte à exibição por hover/focus sem JavaScript
- É um recurso Baseline 2025 que funciona em dispositivos e navegadores atuais desde janeiro de 2025, mas vale verificar a compatibilidade em ambientes antigos ou em alguns recursos mais específicos
O problema que a Popover API resolve
- A Popover API fornece um mecanismo padrão para exibir conteúdo de popover sobre outro conteúdo da página
- Os popovers podem ser controlados apenas com atributos HTML ou com a API JavaScript para manipular diretamente os estados de exibição e ocultação
- Padrões de UI que na web eram chamados de overlays, popups, popovers e dialogs podem ser implementados de forma mais consistente com recursos nativos do navegador
Se você precisa de modal, use ``
- As UIs de popover se dividem, em geral, entre modais e não modais
- Em modais, não é possível interagir com o restante da página enquanto o popover estiver visível
- Em não modais, é possível continuar interagindo com o restante da página mesmo com o popover aberto
- Os popovers criados com a Popover API são sempre não modais
- Se você precisa de um popover modal que bloqueie a interação com a página, o elemento `` é o mais indicado
- Uma abordagem como
aplicar `popover` em também é válida, permitindo usar ao mesmo tempo o controle de popover e a semântica de dialog
Forma básica de uso
- A Popover API pode ser usada com frequência em UIs que exigem interação do usuário
- menus de ação
- notificações toast personalizadas
- sugestões para elementos de formulário
- seletores de conteúdo
- interfaces educacionais
- É possível criar um botão simples para alternar um popover apenas com HTML
Toggle the popover
Popover content
- Em JavaScript,
HTMLElement.togglePopover() alterna o estado de exibição/ocultação do popover
- A API também oferece eventos para reagir a mudanças de estado do popover e recursos de CSS para facilitar a estilização
Atributos HTML
interestfor
- Define elementos HTML
, e ou o elemento SVG como interest invoker
- O valor é o
id do elemento de destino, e esse elemento é afetado quando o interest aparece ou desaparece no elemento invoker
popover
- É um atributo global que transforma um elemento em um elemento popover
- Pode receber os estados
"auto", "hint" e "manual"
popovertarget
- Transforma um elemento
ou em um botão de controle de popover
- O valor é o ID do elemento popover a ser controlado
popovertargetaction
- Define a ação que o botão de controle executará no popover
- Os valores possíveis são
"hide", "show" e "toggle"
Estados de exibição via CSS
::backdrop
- É um pseudoelemento de tela cheia posicionado logo atrás do elemento popover
- Se necessário, ele pode aplicar efeitos como desfoque ao conteúdo da página atrás do popover
interest-delay, interest-delay-start, interest-delay-end
- Adicionam um tempo de espera entre o momento em que o usuário demonstra ou perde interest e o momento em que o navegador reage
:interest-source, :interest-target
- Permitem aplicar estilos, respectivamente, ao invoker e ao elemento de destino associado quando o interest estiver ativo
:popover-open
- É uma pseudoclasse que só corresponde quando o elemento popover está visível
- É usada para estilizar o popover em estado aberto
Interface JavaScript e extensões do DOM
InterestEvent
- É o objeto de evento dos eventos
interest e loseinterest
- Inclui a propriedade
source, que contém uma referência ao elemento interest invoker associado
ToggleEvent
- Representa o evento disparado quando o elemento popover alterna entre os estados visível e oculto
- É o objeto de evento dos eventos
beforetoggle e toggle
interestForElement
- Obtém ou define a referência do elemento que um interest invoker usa como alvo
- Pode ser usado em
HTMLButtonElement, HTMLAnchorElement, HTMLAreaElement e SVGAElement
HTMLElement.popover
- Obtém ou define via JavaScript o estado de popover de um elemento
- Usa os valores
"auto", "hint" e "manual", e também pode ser usado para detecção de recurso
- Reflete o valor do atributo global HTML
popover
popoverTargetElement
- Em
HTMLButtonElement e HTMLInputElement, obtém ou define o elemento popover controlado pelo botão
- É o equivalente em JavaScript do atributo HTML
popovertarget
popoverTargetAction
- Em
HTMLButtonElement e HTMLInputElement, obtém ou define a ação de popover a ser executada
- Usa os valores
"hide", "show" e "toggle" e reflete o atributo popovertargetaction
Métodos e eventos
HTMLElement.hidePopover()
- Remove o elemento popover da top layer e o oculta aplicando estilo
display: none
HTMLElement.showPopover()
- Adiciona o elemento popover à top layer para exibição
HTMLElement.togglePopover()
- Alterna o elemento popover entre os estados visível e oculto
beforetoggle
- É disparado imediatamente antes de o estado do elemento popover mudar entre visível e oculto
- Pode ser usado para impedir a abertura do popover ou atualizar outros elementos de acordo com o estado do popover
toggle
- É disparado logo após a mudança de estado do popover
interest
- É disparado no elemento de destino do interest invoker quando o interest é mostrado
loseinterest
- É disparado no elemento de destino do interest invoker quando o interest desaparece
Exemplos e links de especificação
- Popover API examples: coleção de exemplos da Popover API
- interest invoker examples: coleção de exemplos de interest invoker
- As especificações relacionadas estão incluídas nos itens de popover,
beforetoggle e toggle da especificação HTML
1 comentários
Opiniões no Hacker News
A Popover API parece que vai provocar uma mudança realmente grande quando chegar também o posicionamento por âncora em CSS (CSS Anchor Positioning)
O posicionamento por âncora permite posicionar um elemento com base em outro elemento da página
Combinado com a Popover API, dá para implementar tooltips personalizados ou menus de contexto de forma declarativa, sem precisar de bibliotecas como PopperJS
https://developer.chrome.com/blog/tether-elements-to-each-ot...
https://popper.js.org/docs/v2/
https://developer.chrome.com/blog/anchor-positioning-api
https://caniuse.com/css-anchor-positioning
Na semana passada tentei criar e lançar algo com a nova Popover API, mas a falta de suporte a posicionamento em todos os navegadores limitou bastante os casos de uso
Como o último navegador, o Firefox, parece já ter incluído posicionamento por âncora no beta, acho que não deve demorar muito
titleSe você precisa de uma caixa de diálogo modal, também existe o elemento
<dialog>https://developer.mozilla.org/en-US/docs/Web/HTML/Element/di...
<details>Curiosamente, ao contrário de
<dialog>ou<details>, parece que<popover>não consegue criar declarativamente o estadoopenapenas com um atributoParece uma funcionalidade ausente, e espero que tenha havido uma justificativa para essa decisão
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/de...
É totalmente possível, mas está longe de ser algo trivial
O suporte no Safari demorou, mas agora dá para usar em qualquer lugar
Acho melhor do que montar tags manualmente
Se for implementado em conjunto com o sistema de janelas do sistema operacional hospedeiro, esse recurso parece claramente necessário
Porque hoje popovers precisam ser imitados de um jeito que nem sempre funciona bem
Por exemplo, um
<select>nativo do navegador pode se estender para além dos limites da janela do navegador, então não é preciso se preocupar em ele ser cortado pela janela; já selects falsos e sofisticados de toolkits como Quasar não conseguem fazer isso, o que limita as opções de posicionamentoPara fazer direito, no win32 cada popover provavelmente teria que ter seu próprio
HWNDnativo e, no Cocoa/macOS, ficar dentro de sua própriaNSViewFico curioso se os navegadores hoje realmente implementam assim, ou se apenas desenham por cima dentro da janela do navegador
Se você permitir que sites desenhem fora do viewport designado, fica muito mais fácil imitar de forma convincente diálogos do navegador ou do sistema operacional, exceto em casos extremamente limitados como
alert(),confirm()e[title]Por exemplo, uma página poderia imitar o widget de desbloqueio de uma extensão de gerenciador de senhas
Isso é um grande risco de segurança e, na minha opinião, não vale a pena diante dos benefícios limitados
Essa não é uma preocupação teórica
Golpistas vêm criando há anos interfaces falsas muito convincentes, incluindo janelas popup falsas com até a chrome do navegador, e até arrastáveis
A impossibilidade de desenhar para fora dos limites do viewport era praticamente a única restrição que eles ainda não tinham conseguido contornar
Em dispositivos pequenos, o navegador quase sempre ocupa a tela inteira; mesmo em monitores grandes, normalmente ele encosta em pelo menos um dos cantos
O mesmo vale para acessibilidade e capacidade de ser rastreado, e também seria útil se alguém quisesse criar um plugin de “bloquear popups”
Esse recurso é exposto por meio de elementos XUL que só podem ser usados em [X]HTML privilegiado renderizado no processo principal do navegador
Acho que nenhum desenvolvedor de navegador gostaria de dar a páginas web comuns permissão para criar janelas do sistema operacional sem borda
O fato de alguns controles padrão se comportarem assim é um efeito colateral de implementação específico de cada sistema operacional, por terem sido implementados nativamente no OS, e não algo que necessariamente precise ser implementado dessa forma
É meio engraçado que os navegadores tenham bloqueadores de pop-up embutidos e, ainda assim, criem uma API dessas
Sei que há uma diferença, mas mesmo assim
Já tenho idade suficiente para lembrar das guerras de pop-ups/pop-unders do fim dos anos 90 e começo dos anos 2000
Acho que vencemos aquela batalha, mas a guerra pela nossa atenção ainda está longe de acabar
Um popover é um elemento flutuante que mostra informações de contexto quando necessário
O que você mencionou é algo completamente diferente
Pop-ups espalhavam janelas lixo pelo sistema operacional e, no pior caso, atrapalhavam o próprio uso do computador
Um diálogo popover acaba quando você fecha a aba
Esse estilo de popover é bem útil para mostrar informações e já é usado há muito tempo
Pode ser usado de forma irritante, mas, assim como modais, também tem muitos casos de uso reais
Hoje já dá para implementar popovers com
dive coisas do tipoEx.: https://getbootstrap.com/docs/5.3/components/popovers/
O que muda é que será possível implementar popovers sem uma biblioteca adicional mágica
Mesmo que bloqueassem um elemento explícito “popover”, as pessoas continuariam usando bibliotecas customizadas
As pessoas odeiam pop-ups porque são intrusivos e têm uma janela separada
Esta API substitui modais em
dive reduz o tempo e o código dos desenvolvedoresEsta API não quebra essa fronteira
Quando essa fronteira é quebrada, a usabilidade e a segurança do sistema pioram, então é uma direção indesejada
Dizem que “popovers criados com a Popover API são sempre não modais. Se quiser criar um popover modal, o elemento
<dialog>é o correto”, mas não entendo por quêEsse é um caso de uso legítimo para popovers
Especialmente se o fundo ficar desfocado quando aberto; se um botão desfocado puder ser acionado por um clique acidental do usuário, fico me perguntando por que esse recurso é oferecido
Pelo que encontrei, dá para combinar os dois
Algo como “se quiser combinar controle de popover com semântica de diálogo, você pode transformar um elemento
<dialog>em popover”Então acho que aqui faria mais sentido ter um atributo como
modalJá que o caso de uso é claramente reconhecido
<dialog>já existia bem antesMuito bom
Se entendi direito, em vez de introduzir uma funcionalidade nova, parece simplificar algo que antes exigia
divmodal,divde máscara,divcontêiner e CSS incômodo de posicionamentoTambém foram adicionadas pseudoclasses que facilitam a estilização, gostei
Sem precisar forçar o uso de um checkbox escondido
Não sei até onde dá para ir sem JS com popovers estilizados e animados, mas suporte sem JS com tratamento correto de foco é bom
Eu gostaria de dizer que o suporte a acessibilidade também vem embutido, mas não consegui encontrar isso na especificação atual
Se também cuidar de informar o elemento a ferramentas de acessibilidade, como leitores de tela, será uma grande ajuda
Porque, ao fazer isso manualmente, é bem fácil esquecer algo
É definitivamente útil
Demo: https://mdn.github.io/dom-examples/popover-api
Porque ninguém no Chrome ou no Firefox implementou o atraso antes de o submenu desaparecer
Décadas de pesquisa em experiência do usuário desapareceram e, de certa forma, era quase o esperado
https://mdn.github.io/dom-examples/popover-api/nested-popove...
Parece legal, mas não entendo por que esta página não tem nenhuma imagem mostrando o que é um popover
https://mdn.github.io/dom-examples/popover-api/
Há links para exemplos interativos, mas o estilo padrão do popover não parece tão interessante
https://mdn.github.io/dom-examples/popover-api/
Excelente
Aqui está uma implementação customizada feita com Stimulus usando Popper
https://github.com/tramlinehq/tramline/blob/main/app/javascr...
E aqui está a implementação para diálogos
https://github.com/tramlinehq/tramline/blob/main/app/javascr...