As 10 principais coisas que a IA erra no desenvolvimento web

Publicado em: 11 de novembro de 2026

Esta semana, lançamos a versão 1.0 do Modern Web Guidance, um conjunto de habilidades que incorpora conhecimento da plataforma da Web, práticas recomendadas e dados de compatibilidade de navegadores diretamente nos seus agentes de programação. Nosso objetivo com o Modern Web Guidance é ajudar os desenvolvedores que usam agentes de programação de IA a aproveitar ao máximo o poder e as capabilities da plataforma da Web moderna e, por fim, melhorar as experiências na Web para os usuários.

Desde que lançamos o pré-lançamento do Modern Web Guidance em maio, os agentes de programação estão cada vez melhores, e muitos modelos de fronteira incríveis foram lançados. Uma das perguntas que mais ouvimos é: esses novos modelos de fronteira já não seguem as práticas recomendadas de desenvolvimento web?

Infelizmente, a resposta é "não", e sabemos disso porque testamos.

Cada guia do Modern Web Guidance define um conjunto de expectativas que precisam ser verdadeiras se as práticas recomendadas no guia forem seguidas corretamente. Em seguida, nosso pacote de avaliação testa esses guias enviando o mesmo comando para um agente em execução com o Modern Web Guidance instalado (o agente guiado) e outro agente em execução sem o Modern Web Guidance instalado (o agente não guiado). A saída de ambas as execuções é comparada com as expectativas definidas pelo guia.

Ao comparar as taxas de aprovação guiadas e não guiadas, é possível notar que os modelos de IA, mesmo os modelos de fronteira mais recentes, não seguem de forma confiável as práticas recomendadas de desenvolvimento web moderno por conta própria.

Em média, os agentes de programação sem orientação passam em apenas cerca de 50% das verificações no nosso pacote de avaliação, em comparação com cerca de 90% quando o Modern Web Guidance é usado.

Gráfico de barras horizontais comparando as taxas médias de aprovação na verificação de avaliação entre agentes de programação de fronteira (em 9 de novembro de 2026): 52% sem o Modern Web Guidance em comparação com 91% com o Modern Web Guidance.

Confira nosso painel de avaliação para ver a lista completa de verificações específicas que realizamos para cada guia e como cada modelo se sai nelas.

Mas, para uma visão geral de alto nível, este post aborda 10 das áreas mais problemáticas em que os modelos de IA costumam errar, em disciplinas importantes que os desenvolvedores Web provavelmente vão encontrar no trabalho diário, como acessibilidade, experiência do usuário, desempenho e segurança.

1. Acessibilidade: foco do teclado e gerenciamento de inert

Para pessoas que navegam com um teclado ou leitor de tela, a ordem de foco previsível é o que torna as interfaces interativas utilizáveis. Sem ele, o foco pode se perder no conteúdo oculto em segundo plano ou ficar preso em dezenas de paradas de tabulação extras.

O gerenciamento de foco e inert é uma das maiores lacunas de acessibilidade nas nossas avaliações e uma das áreas que mais melhora com o Modern Web Guidance. Os erros mais comuns incluem:

  • Não mover o foco para as visualizações recém-abertas e esquecer de restaurar o foco para o elemento acionador ao voltar.
  • Depender de traps de tabulação manuais em JavaScript e aria-modal="true" em modais personalizados, em vez de usar um modal <dialog> ou marcar o conteúdo em segundo plano como inert.
  • Expor cada item em uma barra de ferramentas ou grade direcional como uma parada de tabulação separada em vez de usar uma única parada de tabulação com tabindex móvel.
  • Criar contornos personalizados de :focus-visible que não têm uma proporção de contraste de 3:1 em relação aos planos de fundo adjacentes.

2. Acessibilidade: suporte a movimento reduzido

Movimentos inesperados na página e animações em grande escala não são apenas uma distração. Para usuários com distúrbios vestibulares ou sensibilidade ao movimento, eles podem causar tontura, náusea ou dores de cabeça.

Os modelos de IA geralmente se lembram de verificar se há prefers-reduced-motion ao adicionar transições CSS padrão ou animações de frame-chave. No entanto, ao usar recursos mais recentes, como rolagem suave, transições de visualização ou animações orientadas por rolagem, eles geralmente se esquecem do movimento reduzido ou cometem erros ao implementá-lo:

  • Definir scroll-behavior:smooth de forma global e incondicional no elemento raiz.
  • Uso de animações CSS de rolagem sem verificação de movimento reduzido.
  • Remover as durações de transition nos itens do carrossel para reduzir o movimento durante a rolagem, mas esquecer de remover as propriedades de transformação, fazendo com que os itens mudem de tamanho durante a rolagem.
  • Aplicar uma redefinição geral da duração de 0.01ms em *, *::before e *::after quando o movimento reduzido está ativo, eliminando também todas as transições essenciais sem movimento (necessárias para comunicar mudanças de estado da interface).
  • Ativar transições de visualização entre documentos de forma incondicional e substituir as animações de ::view-transition-* quando o movimento reduzido estiver ativo, em vez de apenas restringir a regra @view-transition por trás de uma verificação de movimento reduzido.

3. Acessibilidade: validação de formulários, dicas de formato e estados de preenchimento automático

Os formulários são uma parte fundamental das jornadas ideais do usuário mais importantes na Web. Um pequeno problema em um formulário de finalização de compra pode ter um grande impacto nos resultados de uma empresa.

Ao criar formulários, os modelos de IA acertam muitos dos conceitos básicos. No entanto, eles geralmente falham em detalhes pequenos, mas críticos, como erros de validação, posicionamento adequado de marcadores de posição e dicas de formato, além de integração correta com gerenciadores de senhas e recursos de preenchimento automático:

  • Reimplementação de :user-invalid de CSS com validação personalizada de JavaScript blur, que geralmente sinaliza campos required intocados assim que os usuários passam por eles.
  • Deixar que aria-invalid perca a sincronização com erros visíveis, seja definindo aria-invalid="true" prematuramente em blur ou estilizando :user-invalid em CSS sem sincronizar aria-invalid em JavaScript.
  • Depender do texto placeholder que desaparece para mostrar os formatos necessários (como MM/YY em uma entrada de validade do cartão) em vez de renderizar uma dica persistente vinculada a aria-describedby.
  • Colocar dicas de formato e regras de senha abaixo do <input> (em vez de acima dele), onde podem ser ocultadas por teclados de dispositivos móveis e popovers de preenchimento automático no momento em que o usuário precisa ler essas informações.
  • Destacar entradas de :autofill mudando apenas a cor da borda, em vez de combinar a cor com uma indicação não colorida que não muda o layout (como um box-shadow inserido).

4. Experiência do usuário: gestos de deslizar e tocar

Os agentes são bons em implementar gestos de toque usando JavaScript imperativo e em escrever a própria lógica de física personalizada. Essas implementações funcionam, mas as interações por toque com JavaScript raramente são tão suaves quanto as que os usuários esperam de apps nativos.

Muitas dessas interações podem ser implementadas com CSS e APIs de rolagem nativas, permitindo que o navegador execute a física de gestos fora da linha de execução principal. No entanto, em nossas avaliações, os modelos de IA geralmente ignoram esses recursos:

  • Implementar gestos de deslizar para dispensar ou deslizar para revelar com listeners pointermove ou touchmove em vez de usar o ajuste de rolagem do CSS.
  • Omitir overscroll-behavior-x:none em interfaces de deslizar para trocar de guia, o que pode acionar acidentalmente uma navegação para frente ou para trás no navegador durante um deslize excessivo.
  • Gerar efeitos de progresso de deslizar na linha de execução principal em callbacks do JavaScript em vez de usar animações de rolagem.
  • Não oferecer suporte adequado ao foco do teclado em painéis de ação de deslizar baseados em rolagem.

5. Experiência do usuário: caixas de diálogo, popovers e transições de camada superior

Nas nossas avaliações, os modelos geralmente usam soluções alternativas de JavaScript imperativo ao animar, dispensar ou conter a rolagem em caixas de diálogo modais e pop-overs.

Em vez de usar recursos modernos de HTML e CSS criados para sobreposições de camada superior, os agentes costumam criar manualmente máquinas de estado de entrada e saída, hooks de histórico e bloqueios de rolagem do corpo, que são mais difíceis de manter e propensos a bugs sutis na interface.

Quando você acerta nessas interações, pode transformar uma experiência que parece frágil em uma experiência refinada em que os usuários confiam. Estes são os erros mais comuns que encontramos:

  • Criar sobreposições personalizadas de position:fixed com gerenciadores manuais de clique fora para dispensar com um toque, em vez de apenas usar popover.
  • Criar animações de entrada e saída alternando as classes de transição CSS e coordenando com os listeners requestAnimationFrame() e transitionend (com substitutos setTimeout()), em vez de fazer isso em CSS puro com @starting-style e transition-behavior.
  • Bloqueio da rolagem da página atrás de um modal aberto ao definir overflow:hidden em <html> em vez de usar um elemento <dialog> para conter a rolagem esticada.
  • Adição de listeners popstate para detectar gestos de voltar do Android e fechar modais abertos, em vez de usar a funcionalidade nativa de fechamento do botão "Voltar" de um elemento modal <dialog>.

6. Experiência do usuário: modo escuro e controles adaptáveis ao tema

Os usuários ativam o modo escuro para reduzir o cansaço visual e o brilho. Por isso, um flash branco brilhante no carregamento de página, controles de formulário sem tema ou um botão que não sincroniza com a preferência do SO prejudicam imediatamente a experiência.

Um botão de alternância para o modo escuro pode parecer simples, mas os modelos sem orientação nas nossas avaliações sempre deixam passar detalhes importantes da plataforma necessários para acertar na alternância de temas e nos controles de formulário nativos:

  • Falta de <meta name="color-scheme" content="light dark"> no <head>, o que faz com que os usuários do modo escuro vejam um flash de tela branca enquanto as folhas de estilo externas são carregadas.
  • Estilizar temas escuros ou componentes de superfície escura com cores personalizadas sem definir color-scheme, deixando as barras de rolagem nativas e os controles de formulário presos no modo claro.
  • Ignorar a função CSS light-dark() ao definir tokens de cor adaptáveis ao tema que seguem automaticamente o color-scheme ativo.
  • Oferecer apenas um botão binário de claro ou escuro que define uma substituição explícita em localStorage sem opção de retornar ao padrão do SO.
  • Esquecer de adicionar um listener de eventos storage, deixando outras guias abertas fora de sincronia quando o usuário muda de tema.

7. Desempenho: capacidade de resposta e suavidade do ambiente de execução

Os usuários passam a maior parte do tempo em uma página da Web depois que ela termina de carregar. Por isso, interações lentas e transições instáveis podem prejudicar a experiência do usuário tanto quanto um carregamento inicial lento.

Nas nossas avaliações, os modelos geralmente seguem as práticas recomendadas clássicas de tempo de carregamento que são promovidas em ferramentas como o Lighthouse há anos e geralmente sabem como transferir loops pesados óbvios para um Web Worker. A maior dificuldade é a responsividade da linha de execução principal, que é essencial para otimizar a INP: isolar o trabalho de layout, programar tarefas por prioridade e aproveitar os novos recursos de HTML e CSS que fazem o trabalho de renderização fora da linha de execução principal.

Por exemplo, é comum que os agentes:

  • Criar filas personalizadas de setTimeout() para trabalho em segundo plano ou de baixa prioridade em vez de priorizar tarefas visíveis ao usuário com scheduler.postTask() ou aproveitar a continuação de tarefas com scheduler.yield() quando o navegador oferece suporte.
  • Criar layouts complexos (como grades de dados densas) sem aplicar content-visibility:auto e contain-intrinsic-size, o que significa que as atualizações após as interações do usuário acionam um refluxo de página inteira.
  • Ocultar visualizações de SPA inativas com display:none (ou removê-las) em vez de usar content-visibility:hidden (pareado com inert). O primeiro destrói o estado de renderização em cache, então voltar aciona o layout e a pintura completos.
  • Pausar animações <canvas> fora da tela e loops em segundo plano com callbacks do Intersection Observer em vez de parear content-visibility:auto com o evento contentvisibilityautostatechange (quando disponível), perdendo a margem de pré-renderização do navegador antes que os elementos sejam rolados para a visualização.
  • Criar dicas de interface de affordance de rolagem usando listeners de eventos scroll que forçam cálculos de layout contínuos, em vez de usar consultas de estado de rolagem CSS quando disponíveis (com substitutos do Intersection Observer).

8. Performance: mudanças de layout e oscilação visual

Mudanças inesperadas no layout atrapalham o foco do leitor e podem fazer com que os usuários cliquem em botões inesperados, às vezes com consequências irreversíveis.

Os modelos adicionam de forma confiável os atributos width e height aos elementos <img> padrão para evitar mudanças de layout, mas eles sempre deixam passar outras fontes comuns de mudanças de layout e flashes de pré-pintura de elementos <video>, trocas de fontes da Web, barras de ferramentas de navegadores para dispositivos móveis e experimentos do lado do cliente, que podem afetar a CLS.

  • Omitir atributos width e height explícitos em elementos <video> (para que os players descarregados usem 300×150 como padrão e mudem o layout quando os metadados forem carregados) ou estilizar elementos de wrapper de mídia em vez de definir aspect-ratio e object-fit diretamente nos elementos de mídia.
  • Combinar fontes da Web com fontes substitutas do sistema sem font-size-adjust, fazendo com que parágrafos e títulos sejam reajustados de forma visível quando as fontes da Web são trocadas.
  • Dimensionar seções de destaque e layouts de tela cheia com unidades vh estáticas em vez de unidades de janela de visualização dinâmicas ou pequenas (dvh, svh), fazendo com que o conteúdo pule conforme as barras de ferramentas do navegador para dispositivos móveis se expandem e se retraem.
  • Ocultar conteúdo com snippets antioscilação legados opacity:0 ou visibility:hidden e tempos limite de vários segundos para testes A/B do lado do cliente (atrasando o LCP e deixando elementos invisíveis clicáveis), em vez de usar scripts com blocking="render" quando disponíveis.
  • Acionar transições de visualização entre documentos antes que a marcação crítica acima da dobra seja analisada, em vez de manter a primeira renderização com rel="expect" e blocking="render", fazendo com que elementos analisados pela metade apareçam no meio da transição.

9. Segurança: defesas contra DOM XSS e limpeza de HTML

Uma única falha de scripting em vários sites (XSS) permite que um invasor execute código arbitrário nos navegadores dos usuários, roubando dados de sessão ou realizando ações em nome deles. É por isso que as defesas aplicadas pelo navegador, como a sanitização segura de HTML, os Tipos Confiáveis e as CSPs rigorosas, são tão importantes.

Os modelos raramente abordam essas preocupações de segurança de forma proativa. Por exemplo, em todas as tarefas do nosso pacote de avaliação completo, os modelos não adicionaram uma Política de Segurança de Conteúdo (CSP) ou um cabeçalho de isolamento de origem cruzada sem um comando explícito.

Mesmo quando os comandos solicitam segurança diretamente, os modelos sem orientação continuam falhando em mais da metade das nossas verificações de segurança, buscando substitutos personalizados frágeis ou políticas incompletas. Isso fica claro ao se defender contra o DOM XSS:

  • Escrever limpadores de lista de permissões DOMParser personalizados, seja como substituto de setHTML() ou dentro de uma política de Tipos confiáveis, em vez de usar uma biblioteca aprovada, como o DOMPurify, quando a limpeza nativa não estiver disponível.
  • Agrupar o DOMPurify em cada carregamento de página em vez de usar o setHTML() nativo quando houver suporte e carregar o DOMPurify de forma lenta apenas como substituto.
  • Registrar políticas de Trusted Types de passagem (input) => input permissivas que prejudicam a aplicação de coletores.
  • Parear os Trusted Types em páginas estáticas com CSPs script-src 'self' de lista de permissões de host em vez de bloquear scripts inline com hashes SHA-256.
  • Omitir 'strict-dynamic' e 'report-sample' ao configurar políticas de segurança de conteúdo script-src baseadas em valor de uso único.

10. Segurança: login com chave de acesso, reautenticação e ciclo de vida das credenciais

As chaves de acesso melhoram a segurança dos usuários e as conversões de login para as empresas, mas a implementação delas (mesmo com a ajuda de agentes) é um desafio.

O WebAuthn tem APIs específicas de serialização, detecção de recursos e sinalização que os modelos sem orientação quase não conseguem usar nas nossas avaliações. Se você pedir a um modelo de IA para adicionar o login, o gerenciamento ou a reautenticação de chave de acesso, ele geralmente vai escrever auxiliares de codificação de bytes manuais, pular as verificações de capacidade na interface de gerenciamento ou deixar as credenciais fora de sincronia com os gerenciadores de senhas:

  • Criar manualmente assistentes de conversão Base64URL atob() e btoa(), seja como o caminho principal ou como um código boilerplate de fallback redundante, em vez de usar métodos de serialização integrados, como parseCreationOptionsFromJSON(), parseRequestOptionsFromJSON() e credential.toJSON().
  • Omitir PublicKeyCredential.signalUnknownCredential() durante o login quando o servidor informa um ID de credencial desconhecido, deixando chaves de acesso excluídas ou revogadas nos gerenciadores de senhas dos usuários.
  • Ignorando PublicKeyCredential.getClientCapabilities() antes de renderizar a interface de criação e gerenciamento de chaves de acesso.
  • Omitir um AbortController e um AbortSignal ao iniciar solicitações de reautenticação de chave de acesso de nível superior.
  • Transmitir a opção de teste de origem mediation:"immediate" em vez de uiMode:"immediate" para solicitações de login simplificadas.

Preencher essas lacunas

Essas 10 áreas estão longe de ser uma lista completa, e esperamos que as lacunas de conhecimento específicas mudem com o tempo. Os modelos vão se atualizar, e a plataforma da Web vai continuar evoluindo.

A boa notícia é que o Modern Web Guidance aborda todas essas lacunas e vai continuar evoluindo com a plataforma.

Para começar a usar o Modern Web Guidance, execute o comando a seguir ou pesquise por ele no marketplace de plug-ins do seu agente:

npx modern-web-guidance@latest install

Você já viu modelos errarem em outras tarefas de desenvolvimento web? Informe-nos a respeito. Abra um problema no repositório do GitHub do Modern Web Guidance ou ajude a preencher essas lacunas para outros desenvolvedores contribuindo com o projeto.