Uma busca pode devolver o resultado certo e ainda ser difícil de usar. O campo aparece só com um ícone, o botão não tem nome, a lista muda sem aviso e o foco pula para um lugar inesperado. Em um site feito por IA, isso costuma acontecer quando o agente recebe apenas a instrução “adicione uma busca” e preenche o resto com suposições.

Comece pelo caminho da pessoa: entender o que pode procurar, escrever ou revisar o termo, enviar a consulta, perceber o que aconteceu e abrir um resultado. A implementação precisa sustentar esse caminho com mouse, teclado, toque e leitor de tela.

Defina o contrato antes do campo

Escreva as decisões que afetam a busca:

Conteúdo pesquisado: artigos do blog
Campos indexados: título, descrição e tags
Envio: botão Buscar e tecla Enter
URL do exemplo: /blog/posts/?q=acessibilidade
Ordenação: relevância, com desempate por data
Estado vazio: informa o termo e sugere próximos passos

Não prometa busca por autor, conteúdo completo ou sinônimos se o índice não cobre esses dados. Também não diga “nenhum resultado” enquanto a consulta ainda está carregando. O texto da interface precisa representar o estado real.

Uma URL que guarda o termo ajuda a recarregar, compartilhar e usar os botões Voltar e Avançar. Se a busca funciona apenas em estado interno, a pessoa perde a consulta quando atualiza a página ou abre um resultado e retorna.

Use um formulário de busca com nome visível

Uma base pequena já fornece envio por Enter, participação no formulário e semântica conhecida:

<form role="search" aria-labelledby="titulo-busca" action="/blog/posts/">
<h2 id="titulo-busca">Buscar artigos</h2>
<label for="termo">Palavra ou assunto</label>
<input id="termo" name="q" type="search" autocomplete="off" />
<button type="submit">Buscar</button>
</form>

O role="search" identifica a região de busca. O MDN recomenda nomear regiões de busca distintas quando há mais de uma na página. Não repita “busca” no nome sem necessidade. Um leitor de tela já anuncia o tipo da região.

O campo continua precisando de rótulo. Placeholder não é rótulo, pois some durante a digitação e costuma ter contraste fraco. O tutorial da W3C sobre rótulos de controles recomenda associar label e controle de forma explícita sempre que possível.

Se o layout não comporta um título grande, mantenha um rótulo curto e visível perto do campo. Ocultar o texto visualmente é uma saída de último caso, não a primeira decisão de design.

Dê nome ao botão sem depender da lupa

Um botão com a palavra “Buscar” é mais claro que um ícone isolado. Se o projeto exige apenas a lupa, o botão precisa de um nome acessível:

<button type="submit" aria-label="Buscar artigos">
<svg aria-hidden="true" focusable="false"><!-- ícone --></svg>
</button>

Não coloque aria-label no SVG e deixe o botão sem nome. O elemento acionável é o botão. Também não transforme uma div em botão com evento de clique, pois isso exige recriar foco, teclado e semântica que o HTML já oferece.

O artigo sobre nomes acessíveis de links e botões ajuda a comparar o texto visível com o nome anunciado.

Escolha quando a consulta acontece

Busca ao enviar é previsível. A pessoa escreve, revisa e aciona o botão ou Enter. Busca a cada tecla pode ser útil em conjuntos pequenos, mas exige mais cuidado com atraso, cancelamento e anúncios.

Se atualizar enquanto a pessoa digita:

  • espere uma pausa curta antes de consultar;
  • cancele respostas antigas quando uma consulta nova começar;
  • não roube o foco do campo;
  • preserve o valor escrito;
  • diferencie carregamento, resultado e falha;
  • não anuncie cada tecla em uma região viva.

Uma resposta lenta para “acess” não pode substituir a resposta mais nova para “acessibilidade”. O estado visual e o anúncio precisam corresponder à mesma consulta.

Sugestões automáticas criam outro componente. Uma lista que pode ser percorrida e escolhida enquanto a pessoa digita se aproxima do padrão de combobox. Não adicione role="combobox" só para descrever um campo de busca comum. Se houver sugestões interativas, siga o guia de comboboxes acessíveis e teste o comportamento completo.

Anuncie a conclusão sem mover o foco

Quando a lista muda sem recarregar a página, informe a quantidade perto dos resultados:

<p role="status" aria-atomic="true">12 artigos encontrados para "acessibilidade".</p>

A WCAG 2.2 sobre mensagens de status cita resultados de busca como exemplo de mudança que pode ser anunciada sem receber foco. A W3C também mantém um exemplo de role="status" para resultados.

Não coloque a lista inteira dentro da região de status. O leitor de tela não precisa recitar todos os cartões após cada consulta. Anuncie uma frase curta. A pessoa decide quando navegar pelos resultados.

Durante o carregamento, use uma mensagem como “Buscando artigos” apenas quando a espera for perceptível. Ao concluir, substitua pelo resultado. Em caso de falha, mantenha uma mensagem visível e ofereça nova tentativa sem apagar o termo.

Faça o título e a lista descreverem a consulta

O resultado precisa ficar compreensível mesmo depois que a pessoa sai do campo:

<section aria-labelledby="titulo-resultados">
<h2 id="titulo-resultados">Resultados para "acessibilidade"</h2>
<ol>
<li><a href="/guia-a/">Título do primeiro artigo</a></li>
<li><a href="/guia-b/">Título do segundo artigo</a></li>
</ol>
</section>

Use links reais para os destinos. O texto do link deve identificar o conteúdo fora do cartão. Evite repetir “Leia mais” em todos os itens sem nome adicional.

Se a consulta retorna muitos resultados, combine a busca com uma paginação acessível. Preserve q, filtros, ordenação e página na URL. Ao trocar o termo, volte para a primeira página em vez de manter um número que talvez não exista no novo conjunto.

Escreva um estado vazio que ajude a continuar

“Nada encontrado” confirma o problema, mas não oferece saída. Mostre o termo e sugestões que fazem sentido para o índice:

Nenhum artigo encontrado para "acessibilidde".
Confira a grafia, tente menos palavras ou busque por "acessibilidade".

Só sugira uma correção quando o sistema realmente calculou essa alternativa. Não invente links ou categorias. Mantenha o campo preenchido para a pessoa corrigir uma palavra sem recomeçar.

Se um filtro eliminou os resultados, informe isso. Um botão “Limpar filtros” pode resolver melhor do que culpar o termo de busca. O estado vazio pertence ao conjunto completo de critérios ativos.

Preserve foco, histórico e título da página

Depois do envio, há dois caminhos válidos:

  • numa navegação completa, o navegador carrega a URL de resultados;
  • numa atualização parcial, o foco permanece no controle acionado e a mensagem de status informa a conclusão.

Mover o foco para o título dos resultados pode ajudar em uma página dedicada, mas não deve acontecer a cada tecla. Se essa for a regra escolhida, use um destino lógico com tabindex="-1" e teste Voltar, Avançar e uma nova consulta.

Atualize document.title quando a busca muda o conteúdo principal sem nova navegação. Restaure termo, resultados e foco de maneira coerente ao voltar pelo histórico. O guia de navegação por teclado cobre ordem, foco visível e perda de contexto.

Teste o percurso completo

Faça uma matriz antes de publicar:

Cenário Resultado esperado
teclado alcança campo, botão e resultados em ordem lógica
leitor de tela região, rótulo, consulta e quantidade fazem sentido
tecla Enter envia a mesma consulta do botão
consulta vazia explica o que pesquisar ou impede envio com orientação
zero resultados mantém o termo e oferece saída real
resposta lenta informa carregamento sem repetir anúncios
falha de rede preserva o termo e permite tentar novamente
respostas fora de ordem nunca mostra resultado de uma consulta antiga
histórico Voltar restaura URL, termo e conjunto corretos
zoom e largura pequena campo e botão continuam visíveis e operáveis

Procure também por termos com acento, espaços, aspas, caracteres não latinos e uma sequência longa. Confira se a busca distingue maiúsculas quando isso faz sentido e se o resultado explica a regra aplicada.

Peça ao agente o componente e as evidências

Um pedido verificável pode ser assim:

Revise a busca deste site.
Use um formulário com região de busca, rótulo visível e botão nomeado.
Guarde o termo no parâmetro q da URL.
Preserve o foco durante atualizações parciais.
Anuncie carregamento, quantidade, estado vazio e falha sem ler a lista inteira.
Teste teclado, leitor de tela, resposta lenta, falha e histórico.
Não publique antes de mostrar as URLs e os resultados dos testes.

O agente pode implementar a interface e reunir evidências. O produto precisa definir o conteúdo indexado, a ordenação, os sinônimos e a política para consultas vazias.

Reteste a versão publicada

No Site no Ar, o agente prepara os arquivos em public/, executa deploy e acompanha deploy_status até o estado terminal, conforme o guia de Publicação.

Na URL final:

  1. pesquise apenas com teclado;
  2. repita com leitor de tela;
  3. abra um resultado e volte;
  4. compartilhe a URL da consulta em outra sessão;
  5. simule conexão lenta e falha;
  6. teste zero, um e muitos resultados;
  7. confirme que Analytics, se usado, não altera foco nem nome dos controles.

Uma busca acessível não se resume ao campo. Ela mantém consulta, resposta e localização ligadas por uma sequência que a pessoa consegue entender e repetir.