Um popover costuma nascer como uma solução visual: colocar um painel acima da página, perto do botão que o abriu. O trabalho de verdade começa depois. O painel precisa entrar na ordem de teclado, ter semântica compatível com o conteúdo e fechar sem fazer a pessoa perder o ponto em que estava.

A Popover API resolve a camada de exibição e oferece comportamentos nativos de abertura e fechamento. Ela não decide se o conteúdo é uma lista de links, um formulário, um menu de aplicativo ou um diálogo. Este guia mostra como fazer essa escolha, implementar o caso não modal e conferir a URL publicada.

Confirme se popover é o padrão certo

Use um popover quando a pessoa precisa abrir conteúdo contextual e ainda pode interagir com o restante da página. Alguns casos comuns são ações secundárias, seletores compactos, ajuda com controles e pequenos formulários.

Escolha outro padrão quando:

  • a mensagem é apenas uma descrição curta sem interação, caso de um tooltip;
  • a pessoa precisa responder antes de continuar, caso de um diálogo modal;
  • o conteúdo deveria estar sempre visível para compreender a oferta;
  • a abertura inicia uma navegação para outra página;
  • o painel exige uma tarefa longa ou muitos campos.

A documentação da Popover API no MDN define popovers como não modais. O restante da página continua disponível. Se o produto exige fundo inerte e foco preso dentro da janela, use dialog com comportamento modal.

Comece pela relação nativa entre botão e painel

O caso simples pode ser declarado em HTML:

<button type="button" popovertarget="acoes-compartilhar">Compartilhar</button>
<section id="acoes-compartilhar" popover aria-labelledby="titulo-compartilhar">
<h2 id="titulo-compartilhar">Compartilhar esta página</h2>
<button type="button">Copiar URL</button>
<a href="mailto:?subject=Veja esta página">Enviar por e-mail</a>
</section>

O atributo popover sem valor equivale a popover="auto". O navegador esconde o painel inicialmente, coloca-o na camada superior quando aberto e permite fechamento ao clicar fora ou usar Escape.

Segundo o guia de uso da Popover API, popovertarget também cria relações implícitas de aria-expanded e aria-details. Quando o painel abre, seus controles entram numa posição lógica da ordem de foco. Quando ele fecha por teclado, o foco volta ao acionador.

Prefira essa relação declarativa a um listener que apenas alterna uma classe. Se JavaScript precisar abrir o painel, mantenha uma origem conhecida e teste o retorno de foco.

Dê semântica ao conteúdo, não ao efeito visual

O atributo popover não cria uma função acessível para um div. O HTML Standard orienta autores a aplicar o HTML ou ARIA adequado ao conteúdo.

Escolha a estrutura pelo que existe dentro do painel:

  • uma lista de destinos continua sendo uma lista de links;
  • um conjunto de ações simples pode usar botões com nomes claros;
  • um formulário precisa de rótulos, instruções e erros associados;
  • um menu com role="menu" exige o modelo completo de teclado e foco de um menu de aplicativo;
  • um diálogo não modal precisa de nome acessível e gerenciamento de foco coerente.

Não adicione role="dialog" a todo painel flutuante. Também não use role="menu" para uma lista comum de links. A função anunciada cria expectativas de teclado que a implementação precisa cumprir.

O artigo sobre menus de navegação acessíveis ajuda a separar navegação, disclosure e menu de aplicativo.

Defina para onde o foco deve ir

Abrir um popover não significa sempre mover foco imediatamente. A decisão depende do conteúdo e da tarefa.

Se o painel apresenta poucas ações e a pessoa deve escolher uma delas, mover o foco para a primeira opção pode ser adequado. O atributo autofocus pode indicar esse destino. Se o painel apenas complementa o controle e a pessoa pode seguir pela ordem normal, mantenha o foco no acionador e deixe Tab entrar no painel.

Evite mover foco para um contêiner genérico sem nome. Evite também prender o foco num popover não modal. A pessoa deve conseguir seguir para o restante da página.

Ao fechar:

  • devolva o foco ao botão que abriu o painel quando a ação de fechamento partiu de dentro dele;
  • não roube foco se a pessoa clicou de propósito em outro controle da página;
  • escolha um destino substituto se o acionador foi removido;
  • confirme que nenhum item escondido continua alcançável com Tab.

O roteiro de navegação por teclado ajuda a encontrar saltos, armadilhas e foco encoberto.

Escolha entre auto, manual e hint

popover="auto" atende a maioria dos painéis acionados pela pessoa. Ele responde a Escape, permite fechamento leve e normalmente mantém apenas uma cadeia de popovers automáticos aberta.

popover="manual" não fecha ao clicar fora nem responde automaticamente a pedidos de fechamento. Use-o apenas quando o produto precisa manter o conteúdo aberto e fornece controles claros para encerrar o estado. Uma mensagem que ninguém consegue dispensar pode cobrir conteúdo ou permanecer no caminho do teclado.

popover="hint" foi pensado para conteúdo de interesse, como dicas que coexistem com outro popover. O suporte e o comportamento de recursos relacionados podem variar. Não troque um tooltip testado por hint sem conferir os navegadores e tecnologias assistivas do projeto.

Registre a escolha por componente. Misturar os estados conforme o breakpoint ou o dispositivo torna o fechamento imprevisível.

Não trate light dismiss como única saída

Clicar fora é útil, mas não basta. O painel deve responder a Escape quando o estado escolhido oferece esse comportamento. Conteúdo que exige confirmação ou pode ficar aberto por muito tempo também precisa de um botão visível para fechar ou cancelar.

O rótulo desse botão deve dizer o que fecha, principalmente quando existem painéis aninhados. Um ícone sem nome cria uma parada muda. Use “Fechar opções de compartilhamento”, por exemplo, e esconda o SVG decorativo da árvore de acessibilidade.

Não feche o painel quando o foco passa do acionador para o conteúdo. Não imponha um limite curto de tempo. Uma pessoa pode precisar ampliar a tela, usar controle por voz ou percorrer os itens com leitor de tela.

Preserve o painel em zoom e telas estreitas

A camada superior evita cortes causados por overflow de ancestrais, mas não garante que o painel caiba na viewport. Teste textos longos, traduções, teclado virtual, orientação retrato, zoom de 200% e 400% e largura equivalente a 320 pixels CSS.

Defina largura máxima relativa à viewport e permita rolagem interna apenas quando o conteúdo não puder crescer na página. O acionador e o painel precisam continuar relacionados visualmente, mas uma tentativa de mantê-los colados não pode colocar metade das ações fora da tela.

Se houver animação, respeite prefers-reduced-motion. Abertura e fechamento não devem atrasar a mudança de visibilidade programática nem deixar controles invisíveis recebendo foco.

Teste estados, não apenas o painel aberto

Monte uma matriz que cubra o ciclo completo:

Situação Evidência esperada
estado inicial painel não aparece, não é lido e não recebe foco
abertura pelo botão nome, estado e conteúdo formam uma relação compreensível
entrada com Tab foco chega ao primeiro destino previsto
fechamento com Escape painel fecha e foco retorna ao acionador
clique externo fechamento não envia foco para um lugar inesperado
painel aninhado fechar o filho preserva o contexto do pai
zoom e tela estreita conteúdo e controles permanecem visíveis e operáveis
JavaScript indisponível ação essencial tem alternativa ou falha compreensível

Repita com teclado, mouse, toque e leitor de tela. Confira o nome do acionador, o estado expandido, a ordem de leitura, o foco depois de cada saída e o comportamento durante a hidratação.

Peça ao agente uma correção verificável

Revise os popovers desta landing page sem publicar ainda.
Escopo:
- fonte e commit: [referência]
- rotas: [lista]
- acionadores e painéis: [inventário]
Para cada popover:
1. Confirme se o conteúdo deve ser tooltip, popover não modal, menu ou diálogo.
2. Registre acionador, painel, semântica, estado inicial e regra de fechamento.
3. Prefira popovertarget e popover quando o suporte do projeto permitir.
4. Defina entrada, percurso e retorno de foco sem criar armadilha.
5. Teste Escape, clique externo, controle visível de fechar e painéis aninhados.
6. Teste teclado, leitor de tela, toque, zoom e movimento reduzido.
7. Preserve conteúdo, URLs, analytics e lógica de negócio.
Entregue a matriz de estados, o diff e as evidências antes de publicar.

O pedido evita uma troca superficial de z-index. O resultado precisa funcionar como uma pequena interface, não apenas aparecer acima das outras camadas.

Reteste a versão publicada

Depois da aprovação, siga a documentação de Publicação: publique uma nova Version, acompanhe o deploy e abra a URL final. Percorra cada popover na build servida, depois que scripts, fontes e dados terminarem de carregar.

Confirme também o comportamento nos navegadores cobertos pelo projeto. Se um fallback duplicar controles, a hidratação mover o painel ou o fechamento perder o acionador, corrija a fonte e republique o mesmo Site. O popover está pronto quando abrir, usar e fechar preservam nome, ordem e contexto.