Uma landing page criada por IA pode validar um formulário e ainda deixar a pessoa sem saber o que aconteceu. Um campo fica vermelho sem explicação. O botão muda para um spinner que ninguém ouve. A confirmação aparece no topo enquanto o foco permanece no rodapé.

Esses detalhes decidem se alguém consegue concluir uma tarefa. O problema não é “adicionar ARIA” ao fim. É decidir que informação mudou, quem precisa percebê-la e se a pessoa deve continuar no mesmo lugar ou seguir para outro ponto da página.

Este guia separa erro, progresso e confirmação. Depois mostra como testar cada estado antes e depois de publicar.

Dê um nome ao problema antes de escolher o atributo

Nem toda mensagem dinâmica pede a mesma resposta. Comece classificando o evento:

Situação O que a pessoa precisa saber Comportamento mais comum
Campo inválido qual campo falhou e como corrigir texto junto ao campo, associado à entrada
Envio em andamento a ação começou e o que permanece bloqueado estado visível e status discreto
Envio concluído o que foi enviado e o próximo passo confirmação visível e anúncio de status
Falha de rede o envio não terminou e como tentar de novo mensagem clara, controle disponível
Erro que bloqueia uma etapa o que exige atenção imediata resumo útil, às vezes com foco movido

O critério Error Identification da WCAG 2.2 exige que um erro detectado identifique o item e o descreva em texto. Cor, ícone e animação podem reforçar a mensagem. Não podem ser a mensagem inteira.

Quando a correção é conhecida, explique-a. “Email inválido” é melhor que uma borda vermelha. “Digite um email com @, como nome@empresa.com” poupa uma tentativa e atende também à ideia de sugestão de correção.

Construa o erro perto do campo

O HTML nativo já resolve bastante coisa. Mantenha o rótulo visível, use o tipo de campo adequado e acrescente a mensagem na relação do próprio controle.

<label for="email">Email de trabalho</label>
<input id="email" name="email" type="email" aria-invalid="true" aria-describedby="email-erro" />
<p id="email-erro">Digite um email no formato nome@empresa.com.</p>

aria-invalid comunica que o valor falhou na validação. aria-describedby liga a explicação ao campo. Só aplique os dois depois de detectar um erro ou depois que a pessoa tentou enviar. Marcar tudo como inválido no carregamento cria ruído e não ajuda a corrigir nada.

Evite apagar o valor digitado. A pessoa precisa comparar a instrução com o que escreveu. Se o sistema normaliza um valor, diga que mudança fez. Um telefone que perde o código do país sem aviso continua sendo um erro, mesmo que o formulário pareça “corrigido”.

O guia de teste de formulários cobre o envio até o destino do lead. Aqui, o foco é a conversa que acontece na página antes de essa requisição sair.

Use um resumo quando há vários erros

Depois de um envio com várias falhas, uma lista no início do formulário poupa navegação. Ela não substitui a explicação junto a cada campo.

<section aria-labelledby="erros-titulo" tabindex="-1">
<h2 id="erros-titulo">Revise 2 campos antes de enviar</h2>
<ul>
<li><a href="#email">Informe um email válido.</a></li>
<li><a href="#empresa">Informe o nome da empresa.</a></li>
</ul>
</section>

Mover o foco para esse resumo pode fazer sentido quando o envio falha e a pessoa precisa escolher por onde recomeçar. Faça isso de propósito. Se mover foco, garanta que o resumo esteja visível e que os links levem ao campo certo. Para um único erro enquanto alguém está digitando, essa mudança costuma ser mais irritante que útil.

Não crie um resumo que repete “erro” cinco vezes sem dizer onde está o problema. A lista precisa ser navegável e ter texto que descreve a correção.

Anuncie status sem interromper a tarefa

Uma mensagem de status informa uma mudança sem exigir que a pessoa abandone o que está fazendo. A WCAG 2.2 trata status messages como informação que tecnologias assistivas devem conseguir apresentar sem mover o foco.

Para avisos de rotina, role="status" é uma boa base. Ele representa uma live region educada: o leitor de tela pode terminar a fala atual antes de anunciar a atualização.

<p id="form-status" role="status" aria-atomic="true"></p>

Crie a região vazia no HTML inicial e atualize apenas seu texto depois. A documentação do MDN sobre live regions explica que assistentes geralmente anunciam mudanças quando o atributo já existia antes da alteração.

Exemplos de mensagens úteis:

  • “Enviando seu pedido.”
  • “Pedido enviado. Você receberá uma resposta por email.”
  • “Não foi possível enviar. Confira sua conexão e tente novamente.”
  • “3 resultados encontrados.”

“Sucesso” sozinho não diz o que mudou. “Carregando” sem contexto também não. Dê a ação, o resultado e, quando houver, o próximo passo.

Reserve alert para interrupções reais

role="alert" costuma interromper a fala atual. Isso pode ser correto para uma falha urgente, como expiração iminente de sessão ou perda de dados sem ação possível. Não use como atalho para cada validação enquanto a pessoa digita.

O papel status no MDN deixa a distinção prática: status oferece informação consultiva e não recebe foco. Se a interface exige mover foco, uma live region por si só não resolve o fluxo.

Um alerta em cada tecla torna o formulário cansativo. Um anúncio assertivo para uma confirmação comum também pode cortar a leitura de um rótulo ou instrução. Prefira uma validação previsível e menos barulho.

Não esconda estado no botão

Durante o envio, o botão deve continuar explicando o que está acontecendo. Desabilitá-lo pode evitar duplicidade, mas não pode fazer a ação parecer travada.

<button type="submit" aria-describedby="form-status" disabled>Enviando pedido</button>

Mantenha o texto legível, preserve os valores e informe se a pessoa pode ou não editar os campos durante a espera. Se um erro devolve o botão ao estado normal, teste se ele volta a ser operável por teclado e clique.

O artigo sobre navegação por teclado ajuda a conferir foco, ordem e controles desabilitados. Não trate um botão com spinner como um detalhe apenas visual.

Teste com uma tarefa, não com inspeção de atributo

Ferramentas podem apontar IDs ausentes. Elas não garantem que o anúncio aconteceu no momento certo. Faça um roteiro curto com teclado e leitor de tela:

  1. tente enviar campos vazios;
  2. ouça se o erro identifica o campo e explica a correção;
  3. corrija um campo e confirme que a mensagem antiga não continua sendo anunciada;
  4. envie dados sintéticos válidos;
  5. confira estado de espera, prevenção de duplo envio e confirmação;
  6. simule falha de rede e teste a tentativa seguinte;
  7. repita no zoom alto e numa largura pequena.

Registre a combinação de navegador e leitor de tela, a ação, a frase anunciada e o resultado esperado. O guia de teste com leitor de tela mostra como transformar esse registro em um bug reproduzível.

Reteste na URL publicada

O ambiente local pode usar uma integração, um domínio ou uma latência diferente. Depois de publicar, abra a URL final, use dados de teste autorizados e repita os estados de erro e sucesso.

No Site no Ar, o agente edita os arquivos públicos e precisa chamar deploy para criar uma nova Version. O roteiro de Publicação descreve esse caminho. Antes de republicar uma correção, confirme que ela não removeu rótulos, foco ou texto visível em nome de uma resposta mais curta.

Uma boa mensagem de estado deixa claro o que acabou de acontecer sem tomar o controle de quem está usando a página. Essa é a medida. Não é a quantidade de atributos ARIA.