Um upload pode funcionar no mouse e falhar no resto. A área de arrastar arquivos não recebe foco, o limite aparece só depois do erro, o progresso muda sem anúncio e o botão “Remover” não diz qual arquivo será excluído. Em uma landing page criada por IA, esses problemas surgem quando o componente visual substitui o campo nativo antes de definir o contrato do envio.
Comece por input type="file". Ele abre o seletor do sistema, participa do formulário e já oferece comportamento conhecido. Arrastar e soltar, pré-visualização e envio assíncrono podem melhorar a tarefa, mas precisam complementar esse caminho.
Escreva as regras antes do componente
Defina o que o destino aceita:
Finalidade: anexar comprovante de residênciaQuantidade: 1 arquivoFormatos aceitos: PDF, JPG e PNGTamanho máximo: 10 MBValidação final: serviço que recebe o formulárioRetenção: conforme a política informada ao usuárioNão peça “imagem” se o processo também aceita PDF. Não diga “até 10 MB” e aplique outro limite no servidor. Se o arquivo contém dados pessoais, explique finalidade e retenção perto do campo ou em uma política acessível antes do envio.
O agente não deve inventar formatos, tamanho ou política de armazenamento. Essas regras pertencem ao produto e precisam ser iguais na instrução, no código e na validação do serviço.
Mantenha o campo nativo no caminho principal
Uma base pequena resolve a seleção:
<label for="comprovante">Comprovante de residência</label><p id="comprovante-ajuda">Envie um arquivo PDF, JPG ou PNG de até 10 MB.</p><input id="comprovante" name="comprovante" type="file" accept=".pdf,.jpg,.jpeg,.png,application/pdf,image/jpeg,image/png" aria-describedby="comprovante-ajuda"/>O MDN documenta input type="file" como o controle que permite escolher um ou mais arquivos do dispositivo. Use multiple somente quando o fluxo aceita mais de um arquivo.
Se o visual exige um botão próprio, associe um label ao input e oculte o controle sem removê-lo da árvore de acessibilidade. display: none e visibility: hidden tornam o input não interativo para tecnologias assistivas. Teste a técnica escolhida com teclado, modo de alto contraste e leitor de tela.
Não dependa de um clique programático num elemento genérico. O campo e o rótulo fornecem uma base mais resistente a diferenças entre navegadores e dispositivos.
Trate accept como orientação, não segurança
O atributo accept restringe as opções mostradas pelo seletor, mas não valida o arquivo. O MDN sobre accept explica que a pessoa pode conseguir substituir o filtro do seletor. Valide extensão, tipo, conteúdo e tamanho no serviço que recebe o upload.
Liste extensões e tipos MIME quando isso ajudar a cobrir variações do sistema. Ainda assim, não confie no File.type enviado pelo navegador como prova do conteúdo. Uma mensagem útil informa o arquivo, a regra violada e a correção possível:
"conta-heic.heic" não foi enviado. Escolha PDF, JPG ou PNG de até 10 MB.Não apague os outros campos do formulário por causa desse erro. Se houver vários arquivos, preserve os válidos e identifique apenas os rejeitados quando o contrato permitir reenvio parcial.
Faça de arrastar e soltar um atalho opcional
Uma área de drop não substitui o seletor. Pessoas que usam teclado, comando de voz ou dispositivos sem gesto de arrastar precisam de um botão visível para escolher arquivos.
Use um texto direto:
Arraste o arquivo para esta área ou escolha no dispositivo.O botão ou rótulo abre o mesmo input type="file". A área visual pode reagir durante o arrasto, mas não deve exigir precisão fina. Não use só mudança de cor para indicar que o arquivo pode ser solto.
Se a área inteira for interativa, evite criar dois focos com a mesma ação. Um único controle claro costuma ser melhor que uma caixa clicável e um botão interno competindo na ordem de teclado.
Mostre os arquivos escolhidos como dados, não decoração
Depois da seleção, apresente nome, tamanho e estado. Para vários arquivos, use uma lista:
<ul aria-label="Arquivos selecionados"> <li> contrato.pdf, 2,4 MB <button type="button" aria-label="Remover contrato.pdf">Remover</button> </li></ul>O texto visível pode dizer “Remover”, mas o nome acessível precisa identificar o arquivo. Se dois botões iguais aparecem na lista sem contexto, a pessoa que navega por controles ou comando de voz não sabe qual acionar.
Para imagens, uma miniatura não substitui o nome do arquivo e o estado. Também não transforme a prévia em texto alternativo inventado. Se a imagem será publicada com conteúdo, peça uma descrição num campo separado e explique a finalidade.
O artigo sobre nomes acessíveis de links e botões ajuda a revisar ações repetidas em listas.
Separe seleção, envio e confirmação
Escolher um arquivo não significa que o servidor o recebeu. Mostre os estados reais:
selecionado -> enviando -> processando -> concluído -> falhouSe o formulário envia tudo ao final, diga que o arquivo está selecionado. Não anuncie “enviado” antes da resposta do servidor. Se o upload começa logo após a seleção, ofereça cancelamento quando ele tiver efeito real e deixe claro o que acontece com um arquivo parcialmente transferido.
Uma mensagem breve de sucesso pode usar uma região de status. Uma falha que exige decisão precisa continuar visível junto ao arquivo e oferecer uma nova tentativa. A WCAG 2.2 sobre mensagens de status inclui progresso, espera, sucesso, resultado e erro apresentados sem mover o foco.
Evite regiões vivas que anunciam cada variação de 1%. Para um envio longo, anuncie marcos úteis ou use um indicador de progresso com valor programático. A pessoa precisa saber que o processo continua, não ouvir uma sequência ininterrupta de números.
Preserve foco e contexto ao remover ou reenviar
Quando a pessoa remove um arquivo, coloque o foco no próximo controle lógico. Pode ser o botão de remoção do arquivo seguinte, a lista atualizada ou o campo para escolher outro arquivo. Não devolva o foco ao início da página.
Ao tentar de novo, mantenha a mensagem de falha disponível até a nova resposta. Se o arquivo precisa ser escolhido novamente por uma limitação de segurança ou sessão, diga isso. Scripts não podem preencher um campo de arquivo com um caminho local em nome da pessoa.
Use o roteiro de mensagens de erro e status acessíveis para ligar cada falha ao arquivo e anunciar mudanças sem interromper a tarefa.
Não deixe segurança e privacidade só no texto
O serviço deve impor quantidade, tamanho e formatos. Renomeie ou isole arquivos conforme a arquitetura, não execute conteúdo enviado e não exponha o caminho local. A interface do navegador mostra um caminho fictício para evitar revelar a estrutura do dispositivo.
Se o upload contém documentos pessoais:
- use conexão segura;
- limite quem pode acessar o arquivo;
- defina retenção e exclusão;
- não registre conteúdo ou nomes sensíveis sem necessidade;
- explique a finalidade antes do envio.
Acessibilidade não reduz essas obrigações. Um erro detalhado precisa orientar a correção sem revelar regras internas que facilitem abuso.
Teste seleção, transferência e recuperação
Uma matriz mínima cobre o caminho completo:
| Cenário | Resultado esperado |
|---|---|
| teclado | abre o seletor e alcança remover, cancelar e reenviar |
| leitor de tela | rótulo, instruções, arquivos e estados fazem sentido |
| formato inválido | arquivo é identificado e a regra correta é informada |
| tamanho excedido | erro aparece antes ou depois do envio sem apagar o formulário |
| vários arquivos | quantidade, lista e ações correspondem a cada item |
| conexão lenta | progresso útil é visível e anunciado sem excesso |
| falha de rede | estado não finge sucesso e oferece nova tentativa |
| remoção | item some e o foco vai para um destino lógico |
| zoom e largura pequena | nomes longos não cobrem botões nem mensagens |
| validação do servidor | arquivo renomeado ou adulterado continua rejeitado |
Teste com nome longo, extensão em maiúsculas, arquivo vazio, limite exato, um byte acima do limite e seleção cancelada. Para vários arquivos, misture itens válidos e inválidos e confirme a política de tratamento.
O guia de teste de formulários ajuda a cobrir rótulos, instruções, erros, preservação de dados e resposta do destino.
Dê ao agente critérios que possam falhar
Um prompt específico evita um componente que só funciona na demonstração:
Revise o upload de comprovante desta landing page.
Aceite um arquivo PDF, JPG ou PNG de até 10 MB.Mantenha input type="file" e um botão visível para escolher o arquivo.Trate arrastar e soltar apenas como atalho.Mostre nome, tamanho e estado real do arquivo.
Valide novamente no servidor.Teste teclado, leitor de tela, zoom, conexão lenta, falha e reenvio.Não publique antes de apresentar as evidências e a política de retenção.O agente pode implementar o campo, simular respostas e organizar os resultados. A finalidade, os formatos aceitos, o limite e a retenção precisam vir do produto.
Reteste depois da publicação
O build e o domínio final podem mudar cabeçalhos, tamanho máximo da requisição, timeout e comportamento do serviço. No Site no Ar, mantenha os arquivos públicos em public/, execute deploy e acompanhe deploy_status até o estado terminal, conforme o guia de Publicação.
Na URL publicada:
- escolha um arquivo pelo teclado;
- repita por toque e, se existir, arrastar e soltar;
- teste formatos válidos, inválidos e o limite de tamanho;
- observe progresso com leitor de tela;
- interrompa a conexão e tente de novo;
- remova um arquivo e acompanhe o foco;
- confirme no destino o arquivo recebido e o estado final.
Um upload acessível não termina quando o seletor abre. A pessoa precisa entender a regra, escolher o arquivo por mais de um caminho, acompanhar o envio e se recuperar de uma falha sem perder o restante do formulário.
