Uma paginação pode parecer correta e ainda deixar a pessoa sem resposta para três perguntas básicas: em que página estou, para onde cada link leva e o que mudou depois do clique. Em sites criados por IA, o componente costuma nascer como uma fileira de botões visuais. O problema aparece quando esses botões não têm URL, a página atual depende só de cor ou a lista muda sem avisar o leitor de tela.

Paginação é navegação entre conjuntos de conteúdo. Comece com esse contrato. Use links quando cada página tem um endereço e trate a atualização parcial como um comportamento adicional, não como motivo para remover a estrutura que já funciona no HTML.

Decida se o conteúdo precisa de páginas

Antes de montar o componente, defina o conjunto:

Conteúdo: artigos do blog
Itens por página: 12
Ordenação: data de publicação, da mais recente para a mais antiga
URL da página 3: /blog/posts/?page=3
Comportamento sem JavaScript: abre a mesma página de resultados
Comportamento com JavaScript: atualiza a lista e o histórico do navegador

Não use paginação para esconder uma lista curta. Também não troque uma busca previsível por rolagem infinita apenas porque o agente sugeriu um componente mais chamativo. A pessoa precisa conseguir chegar a um item, voltar pelo histórico, copiar a URL e retomar a posição.

Se filtros e ordenação participam da consulta, mantenha esses parâmetros na URL. Uma página diferente precisa representar um estado diferente do conteúdo.

Agrupe os controles em um elemento nav com um nome que o diferencie da navegação principal:

<nav aria-label="Paginação dos artigos">
<ul>
<li><a href="?page=2" rel="prev">Anterior</a></li>
<li><a href="?page=1">1</a></li>
<li><a href="?page=2">2</a></li>
<li><a href="?page=3" aria-current="page">3</a></li>
<li><a href="?page=4">4</a></li>
<li><a href="?page=4" rel="next">Próxima</a></li>
</ul>
</nav>

O nav cria uma região de navegação. O rótulo explica a finalidade daquela região sem repetir a palavra “navegação”. A lista informa que os links pertencem ao mesmo conjunto.

Use <a> porque a ação leva a outro endereço. Um botão serve para uma ação na página atual. Trocar todos os links por button quebra abrir em nova aba, copiar endereço e navegar sem JavaScript.

O exemplo de regiões de navegação da W3C mostra como nomear mais de um nav sem criar rótulos redundantes.

Marque somente uma página como atual

Adicione aria-current="page" ao link da página exibida. O MDN explica aria-current e recomenda marcar somente um item do conjunto como atual.

A indicação visual também precisa existir. Use contraste, peso, contorno ou forma para distinguir a página atual sem depender só de cor. Não remova o link atual da lista sem avaliar o efeito na contagem e na leitura do conjunto. Se mantiver o link, ele pode recarregar a mesma URL; se usar texto sem link, preserve a ordem e a indicação de página atual.

Não aplique aria-selected. Esse estado descreve seleção em componentes como abas e opções. Na paginação, o item representa a localização atual.

Dê contexto aos números sem poluir a tela

Um link visível como 4 pode receber um nome mais claro:

<a href="?page=4" aria-label="Página 4">4</a>

Na página atual:

<a href="?page=3" aria-label="Página 3" aria-current="page">3</a>

Teste o resultado com leitor de tela. Alguns componentes geram nomes como “Ir para página 4, link, página 4”, que repetem contexto sem ajudar. Prefira o menor nome que continue inequívoco dentro da região “Paginação dos artigos”.

Os links “Anterior” e “Próxima” precisam manter texto visível. Um ícone isolado depende de nome acessível adicional e pode perder sentido fora do layout. O guia sobre nomes acessíveis de links e botões ajuda a comparar texto visível, nome anunciado e destino.

Não esconda dezenas de páginas no componente

Uma paginação com cem links vira outro problema de navegação. Mostre um intervalo útil em torno da página atual, preserve acesso à primeira e à última quando isso ajudar e represente a lacuna como texto, não como controle sem destino.

Uma sequência possível para a página 18 de 40 é:

Primeira 17 18 atual 19 Última

Os rótulos precisam refletir o destino real. Não chame a página 17 de “Anterior” e, ao mesmo tempo, mantenha outro link “Anterior” com o mesmo endereço sem uma razão clara. Duplicação aumenta paradas de teclado e torna o componente cansativo.

Em telas pequenas, não esconda os únicos controles que permitem avançar. Reduza o intervalo numérico antes de remover “Anterior” e “Próxima”. O roteiro de zoom e reflow ajuda a conferir largura estreita e ampliação.

Trate os limites como estados reais

Na primeira página, não existe destino anterior. Na última, não existe próxima página. Você pode omitir o link ausente ou mostrar texto indisponível, mas não deixe um link que aponta para a própria página fingindo que avançou.

Se o design exige um controle visível desabilitado, não use apenas aria-disabled="true" em um link que continua navegável. Remova o href, impeça a ativação de forma coerente e verifique se o item ainda precisa entrar na ordem de foco. Em muitos casos, texto simples resolve melhor.

Também trate consultas vazias e páginas fora do intervalo. Se ?page=99 não existe, redirecione para uma página válida ou mostre uma resposta explícita. Não devolva silenciosamente a página 1 com a URL 99, pois a interface passa a anunciar um estado que o endereço não representa.

Planeje o foco nas atualizações parciais

Com navegação normal, o navegador carrega o novo documento e o foco recomeça conforme o comportamento da página. Com atualização via JavaScript, a lista pode mudar enquanto o foco continua no link acionado.

Não mova o foco automaticamente para o primeiro resultado em toda situação. Isso pode interromper quem pretendia avançar mais uma página. Escolha uma regra e teste a tarefa completa. Duas opções comuns são:

  • manter o foco no controle acionado e anunciar “Página 4 carregada, 12 artigos”;
  • mover o foco para um título da lista quando a pessoa precisa começar a ler os novos resultados imediatamente.

Se mover o foco, use um destino lógico com tabindex="-1" e preserve a ordem de teclado. Se mantiver o foco, exponha a atualização como mensagem de status. A WCAG 2.2 sobre mensagens de status cobre resultados e progresso anunciados sem receber foco.

Atualize também document.title, a URL e o histórico. Os botões Voltar e Avançar devem restaurar página, filtros e lista correspondentes.

Teste o caminho, não só a aparência

Faça uma matriz curta antes de publicar:

Cenário Resultado esperado
primeira página não oferece destino anterior falso
página intermediária anterior, atual e próxima correspondem às URLs
última página não oferece destino seguinte falso
teclado todos os links úteis recebem foco visível na ordem
leitor de tela região, destino e página atual fazem sentido
sem JavaScript cada link abre o conjunto correto
atualização parcial resultado novo é percebido sem foco perdido
histórico Voltar restaura URL, filtros e resultados
zoom e largura pequena controles não somem nem se sobrepõem
URL fora do intervalo resposta é explícita e consistente

Percorra a paginação com Tab, Shift+Tab, Enter, Voltar e Avançar. Depois repita com leitor de tela. O guia de teste de navegação por teclado traz um roteiro para foco visível e ordem de interação.

Peça ao agente uma entrega verificável

Um pedido útil informa dados, URLs e comportamento:

Revise a paginação da lista de artigos.
Use 12 itens por página e preserve os filtros na URL.
Implemente links reais que funcionem sem JavaScript.
Nomeie a região e marque somente a página atual com aria-current="page".
Mantenha Anterior e Próxima disponíveis quando houver destino.
Teste teclado, leitor de tela, zoom, largura pequena e histórico.
Se a lista atualizar sem recarregar, informe a nova página e a contagem.
Não publique antes de apresentar as URLs e os resultados dos testes.

O agente pode montar o componente, testar rotas e registrar evidências. A quantidade de itens por página, a ordenação e a política para URLs fora do intervalo pertencem ao produto.

Reteste a URL publicada

Depois das correções, gere a saída pública e confira o componente no ambiente final. No Site no Ar, o agente mantém os arquivos em public/, executa deploy e acompanha deploy_status até o estado terminal, conforme o guia de Publicação.

Na URL publicada:

  1. abra uma página intermediária por endereço direto;
  2. avance e volte só com teclado;
  3. confirme a página atual com leitor de tela;
  4. copie uma URL com filtros e abra em outra aba;
  5. use Voltar e Avançar após várias trocas;
  6. repita sem JavaScript quando o projeto promete essa base;
  7. teste zoom, largura pequena e conexão lenta.

Uma paginação acessível não é uma fileira bonita de números. É um mapa pequeno do conjunto, com destinos reais, localização atual explícita e comportamento previsível antes e depois do clique.