Critérios de Sucesso WCAG · Level A

WCAG 3.2.1: Ao receber foco

WCAG 3.2.1 On Focus exige que, quando qualquer componente da interface do usuário recebe foco do teclado, ele não deve desencadear uma mudança de contexto inesperada. Isso protege usuários de teclado e de tecnologias assistivas de comportamentos desorientadores e imprevisíveis que podem tornar uma página impossível de navegar de forma eficaz.

O que Esta Regra Significa

O Critério de Sucesso 3.2.1 On Focus (Nível A) das WCAG afirma: “Se qualquer componente receber foco, isso não inicia uma mudança de contexto.” Em termos simples, o ato de mover o foco para um elemento interativo — pressionando Tab, Shift+Tab, teclas de seta ou qualquer outro mecanismo de teclado — não deve, por si só, causar que algo dramático e inesperado aconteça na página.

Uma mudança de contexto é definida pelas WCAG como uma mudança importante no conteúdo da página que, se feita sem o conhecimento do usuário, pode desorientá-lo. A especificação identifica quatro tipos concretos de mudança de contexto: mudanças no user agent (como abrir uma nova janela ou aba do navegador), mudanças na viewport (como rolar automaticamente para uma parte distante da página), mudanças no próprio foco (como mover o foco automaticamente para outro lugar) e mudanças no conteúdo que alteram significativamente o significado da página (como enviar um formulário ou carregar uma visão completamente diferente).

A distinção fundamental que o critério faz é entre receber foco e ativar um controle. Entrar com Tab em um botão e, com isso, fazer com que ele envie um formulário é uma violação. Mas pressionar Enter ou Barra de Espaço enquanto esse botão está em foco — uma ativação intencional e deliberada — é perfeitamente aceitável e até esperado. A intenção do usuário é o que separa uma interação previsível de uma desorientadora.

Padrões comuns que falham neste critério incluem:

  • Um dropdown <select> que navega automaticamente para uma nova URL assim que uma opção recebe foco (e não quando o usuário confirma sua escolha).
  • Um widget de seleção de data que abre uma caixa de diálogo modal no momento em que qualquer um de seus campos de entrada recebe foco, sem qualquer ativação pelo usuário.
  • Um carrossel ou slideshow que avança automaticamente para o próximo slide quando seus pontos de navegação recebem foco.
  • Um tooltip ou popover que, quando acionado pelo foco, simultaneamente move o foco do teclado para si mesmo sem aviso, deixando o usuário preso em um local inesperado.
  • Um campo de busca que envia imediatamente e recarrega a página quando recebe foco.

Padrões que explicitamente não são violações incluem: um tooltip ou painel de descrição que aparece visualmente, mas não move o foco nem altera o conteúdo principal da página; um destaque de indicador de foco (como um contorno ou anel) aparecendo ao redor do elemento em foco; ou um elemento que se expande para mostrar conteúdo adicional inline, desde que o foco permaneça onde o usuário o colocou.

Não há exceções oficiais definidas nas WCAG 3.2.1. O critério se aplica universalmente a todos os componentes de UI em uma página. No entanto, o documento Understanding das WCAG observa que mudanças de contexto acionadas pela ativação deliberada do usuário (clique, Enter, Espaço) estão fora do escopo deste critério, que diz respeito apenas ao ato passivo de receber foco.

Por Que Isso Importa

O critério On Focus se enquadra no Princípio 3 — Compreensível — porque a previsibilidade é um pré-requisito fundamental para a usabilidade. Quando uma página se comporta de forma inesperada em resposta apenas ao foco, as consequências variam de leve confusão à perda completa de acesso, dependendo das necessidades e ferramentas do usuário.

Usuários que usam apenas teclado (pessoas que não podem usar mouse devido a deficiências motoras, lesões por esforço repetitivo ou paralisia) dependem exclusivamente da navegação por teclado. Quando entrar com Tab em um campo de formulário aciona um recarregamento da página, eles podem perder todos os dados já inseridos e se ver redirecionados para longe de seu objetivo. Recuperar-se de tal interrupção pode exigir tempo e esforço significativos — ou eles podem simplesmente desistir.

Usuários de leitores de tela (que muitas vezes também são usuários apenas de teclado) enfrentam uma camada adicional de desorientação. Leitores de tela anunciam o elemento atualmente em foco para o usuário. Se o foco pular inesperadamente para um novo elemento — por exemplo, um modal que abriu automaticamente — o leitor de tela anuncia o novo contexto sem dar ao usuário qualquer referência sobre o que acabou de acontecer ou por quê. Isso é análogo a ser fisicamente pego e levado para outra sala sem aviso.

Usuários com deficiências cognitivas, incluindo pessoas com TDAH, transtornos de ansiedade ou comprometimentos de memória, dependem de interfaces previsíveis para construir e manter um modelo mental de uma página. Mudanças súbitas e inexplicadas de contexto destroem esse modelo, criando confusão, ansiedade e erros. Um estudo do projeto WebAIM Million encontra consistentemente que componentes interativos complexos com comportamentos inesperados estão entre as principais fontes de reclamações de acessibilidade de usuários com deficiências cognitivas.

Usuários com baixa visão que usam softwares de ampliação de tela (como ZoomText ou Windows Magnifier) veem apenas uma pequena parte da tela por vez. Se o foco causar uma rolagem ou navegação automática, o conteúdo relevante pode sair completamente de sua viewport ampliada, deixando-os olhando para uma área em branco ou não relacionada da tela.

Considere um cenário concreto do mundo real: o formulário de transferência de dinheiro online de um banco turco contém um menu dropdown para selecionar o banco de destino. O desenvolvedor implementou um evento estilo onchange no elemento <select> que dispara não na confirmação, mas assim que qualquer opção recebe foco pelas setas. Um usuário de leitor de tela que entra com Tab no campo e pressiona a seta para baixo para explorar os bancos disponíveis aciona imediatamente o envio do formulário ou o recarregamento da página. Ele nunca conclui a transferência e não consegue determinar o que deu errado. Este cenário não é hipotético — foi um padrão documentado em muitas aplicações de página única (single-page applications) iniciais.

Além da acessibilidade, há benefícios tangíveis de usabilidade e de negócio. Formulários que não sequestram o foco têm taxas menores de abandono. Páginas que se comportam de forma previsível obtêm melhores resultados em testes de usabilidade com todos os públicos. Rastreadoras de mecanismos de busca também se beneficiam de fluxos de navegação previsíveis, já que redirecionamentos inesperados acionados por eventos de foco podem confundir a lógica de rastreamento em certos cenários de renderização dinâmica.

Regras Relacionadas do Axe-core

WCAG 3.2.1 On Focus exige testes manuais porque ferramentas automatizadas não conseguem determinar de forma confiável a intenção do usuário nem prever todas as possíveis mudanças de contexto. Axe-core e scanners automatizados semelhantes podem analisar HTML estático e atributos ARIA, mas não conseguem observar o comportamento de JavaScript em tempo de execução em resposta a eventos de foco — particularmente se esse comportamento constitui uma mudança de contexto “maior”, conforme definido pelas WCAG. Um script que move o foco, envia um formulário ou navega para uma URL no evento focus é invisível para um scanner estático, a menos que a ferramenta realmente simule interações de foco em todos os elementos interativos e depois analise o que mudou no DOM, na viewport e na URL. Esse nível de simulação de comportamento não é alcançável de forma confiável em uma varredura automatizada sem uma taxa proibitivamente alta de falsos positivos.

  • Teste Manual Necessário — Mudança de Contexto ao Focar: Testadores devem percorrer manualmente com Tab todos os elementos interativos da página (links, botões, inputs, selects, widgets personalizados) e observar se apenas o foco — sem qualquer ativação — aciona uma mudança de contexto conforme definida pelas WCAG. Isso inclui observar mudanças de URL, abertura de novas janelas ou abas, movimento do foco para longe do elemento atual, envios de formulário e substituições importantes de conteúdo. Ferramentas automatizadas sinalizam listeners de eventos JavaScript anexados a eventos relacionados a foco (focus, focusin, onfocus) como candidatos para revisão manual, mas não conseguem determinar se esses handlers causam uma mudança de contexto desqualificante.

Como Testar

  1. Pré-varredura automatizada: Execute axe DevTools (extensão de navegador ou CLI) ou Google Lighthouse na página. Embora nenhuma das ferramentas consiga sinalizar de forma definitiva violações de On Focus, o axe DevTools pode trazer à tona problemas relacionados à gestão de foco (como padrões scrollable-region-focusable ou de foco preso) que merecem inspeção manual mais detalhada. Use o painel “Needs Review” do axe DevTools — itens sinalizados ali frequentemente se relacionam a comportamentos de componentes interativos que exigem julgamento humano.
  2. Identifique todos os elementos interativos: Antes do teste de teclado, faça uma lista de todos os componentes interativos: links, botões, campos de formulário, dropdowns, checkboxes, botões de opção (radio buttons), seletores de data, carrosséis, acordeões, abas, modais e quaisquer widgets personalizados usando tabindex. Dê atenção especial a widgets JavaScript personalizados que escutam eventos focus ou focusin.
  3. Teste de navegação apenas por teclado: Usando apenas o teclado (sem mouse), pressione Tab sequencialmente por todos os elementos focáveis da página. Após cada pressionamento de Tab, antes de pressionar qualquer outra tecla, observe: A URL mudou? Uma nova janela ou aba foi aberta? O foco se moveu para longe do elemento em que você acabou de entrar com Tab? Um formulário foi enviado? O conteúdo principal da página mudou de forma dramática? Qualquer resposta “sim” é um candidato a violação.
  4. Teste de elementos select: Coloque o foco em qualquer dropdown <select>. Use as setas para cima e para baixo para percorrer as opções sem pressionar Enter ou Espaço. Verifique se navegar pelas opções não aciona nenhuma navegação, envio de formulário ou mudança de contexto. Este é um dos padrões mais comumente violados.
  5. NVDA + Firefox: Ative o NVDA (gratuito, Windows). Abra o Firefox e navegue até a página. Pressione Tab por todos os elementos interativos. Ouça os anúncios do NVDA — se o NVDA começar a anunciar uma parte completamente diferente da página ou um novo contexto de página após um pressionamento de Tab (sem você pressionar Enter ou Espaço), isso é um forte sinal de violação.
  6. JAWS + Chrome: Ative o JAWS. Abra o Chrome. Use Tab para navegar. O JAWS anunciará cada elemento em foco. Monitore anúncios inesperados de novos diálogos, páginas ou locais de foco para os quais você não navegou deliberadamente.
  7. VoiceOver + Safari (macOS/iOS): Ative o VoiceOver (Cmd+F5 no macOS). Navegue com Tab (ou deslize no iOS). Monitore mudanças de contexto inesperadas. No iOS, teste também com acesso por interruptor (switch access) para simular usuários com deficiências motoras severas que navegam por varredura.
  8. Inspeção de listeners de eventos nas DevTools do navegador: No Chrome DevTools, selecione qualquer elemento interativo suspeito, vá ao painel Elements e clique em “Event Listeners”. Procure listeners focus ou focusin. Se existirem, revise o JavaScript anexado para determinar se o handler aciona navegação, envio de formulário, movimento de foco ou outras ações que mudem o contexto.

Como Corrigir

Dropdown select que envia automaticamente — Incorreto

<!-- FAIL: Selecting an option via arrow key immediately navigates to a new URL -->
<label for='region'>Select Region</label>
<select id='region' onchange='window.location = this.value;'>
  <option value='/istanbul'>Istanbul</option>
  <option value='/ankara'>Ankara</option>
  <option value='/izmir'>Izmir</option>
</select>

Dropdown select que envia automaticamente — Correto

<!-- PASS: Navigation only occurs when the user explicitly activates the Go button -->
<label for='region'>Select Region</label>
<select id='region'>
  <option value='/istanbul'>Istanbul</option>
  <option value='/ankara'>Ankara</option>
  <option value='/izmir'>Izmir</option>
</select>
<button type='button' onclick='navigateToRegion()'>Go</button>

<script>
function navigateToRegion() {
  var select = document.getElementById('region');
  window.location = select.value; // Only fires on deliberate button activation
}
</script>

Modal abrindo ao focar o input — Incorreto

<!-- FAIL: Focusing the date input immediately opens a modal dialog and moves focus -->
<label for='departure'>Departure Date</label>
<input type='text' id='departure' onfocus='openDatePickerModal()' />

<script>
function openDatePickerModal() {
  var modal = document.getElementById('date-modal');
  modal.style.display = 'block';
  modal.querySelector('button').focus(); // Moves focus away without user intent
}
</script>

Modal abrindo ao focar o input — Correto

<!-- PASS: The date picker opens only when the user explicitly clicks or presses Enter/Space -->
<label for='departure'>Departure Date</label>
<input type='text' id='departure' readonly aria-haspopup='dialog'
       aria-label='Departure Date — press Enter to open date picker' />
<button type='button' id='open-picker'
        aria-controls='date-modal'
        onclick='openDatePickerModal()'>
  Choose Date
</button>

<script>
function openDatePickerModal() {
  // Only called on explicit activation (click or Enter/Space on the button)
  var modal = document.getElementById('date-modal');
  modal.removeAttribute('hidden');
  modal.querySelector('[data-initial-focus]').focus();
}
</script>

Carrossel avançando automaticamente ao focar — Incorreto

<!-- FAIL: Focusing a navigation dot advances the carousel slide, changing page content -->
<div class='carousel-dots'>
  <button class='dot' onfocus='showSlide(0)'>1</button>
  <button class='dot' onfocus='showSlide(1)'>2</button>
  <button class='dot' onfocus='showSlide(2)'>3</button>
</div>

Carrossel avançando automaticamente ao focar — Correto

<!-- PASS: The carousel only changes slides when the dot is explicitly activated (click/Enter) -->
<div class='carousel-dots' role='tablist' aria-label='Carousel navigation'>
  <button class='dot' role='tab' aria-selected='true'
          aria-controls='slide-0' onclick='showSlide(0)'>
    Slide 1
  </button>
  <button class='dot' role='tab' aria-selected='false'
          aria-controls='slide-1' onclick='showSlide(1)'>
    Slide 2
  </button>
  <button class='dot' role='tab' aria-selected='false'
          aria-controls='slide-2' onclick='showSlide(2)'>
    Slide 3
  </button>
</div>
<!-- onclick only fires on deliberate activation, not on Tab focus -->

Erros Comuns

  • Usar onfocus como substituto de onclick em elementos de navegação: Desenvolvedores às vezes anexam handlers onfocus a links ou botões de navegação para “pré-carregar” um destino, acionando acidentalmente uma navegação completa em vez de apenas um prefetch. Sempre use onclick ou onkeydown (verificando Enter/Espaço) para qualquer ação que mude o contexto.
  • Vincular onchange em elementos <select> sem uma ação de envio: Em navegadores desktop, onchange em um <select> dispara quando uma opção é confirmada, mas em algumas implementações mais antigas e em certos navegadores móveis ele pode disparar à medida que as setas percorrem as opções. Sempre combine navegação acionada por select com um botão de envio explícito ou use um <form> com um <button type='submit'>.
  • Mover o foco programaticamente dentro de um handler de evento focus: Chamar element.focus() dentro do handler onfocus ou focusin de outro elemento cria um salto de foco inesperado. Isso é uma violação direta — o usuário entrou com Tab no elemento A e o foco se moveu silenciosamente para o elemento B. Sempre mova o foco apenas em resposta a ações deliberadas do usuário.
  • Abrir diálogos modais em eventos de foco de qualquer elemento disparador: Um atalho comum é anexar um handler de abertura de modal ao evento focus de um botão ou campo de entrada disparador. Modais só devem abrir em resposta a um clique, tecla Enter ou tecla Espaço — nunca apenas ao foco.
  • Reproduzir automaticamente mídia ou animações que mudam o contexto da viewport ao focar: Um banner principal que inicia um vídeo em tela cheia ou uma grande animação no momento em que seu botão de play recebe foco muda significativamente o contexto visual. Vincule ações de reprodução a eventos de ativação, não a eventos de foco.
  • Acionar atualizações de live region que rolam a página para novo conteúdo ao focar: Alguns widgets dinâmicos atualizam uma live region e então rolam a viewport até essa região assim que um input recebe foco. Isso muda o contexto da viewport e desorienta usuários de ampliação de tela. Desacople atualizações de live region de eventos de foco sempre que possível.
  • Implementar traps de foco personalizados que imediatamente prendem usuários sem aviso: Um componente personalizado que intercepta todos os pressionamentos de Tab no momento em que recebe foco, sem anunciar ao usuário que ele está dentro de um trap de foco, viola tanto a letra quanto o espírito deste critério. Traps de foco só são apropriados dentro de diálogos modais totalmente abertos, e os usuários devem ser informados sobre como sair.
  • Usar CSS :focus para acionar display: block em menus dropdown que contêm filhos focáveis, causando movimentos de foco inesperados em cascata: Menus acionados apenas por foco em CSS que revelam itens focáveis podem causar saltos confusos quando a ordem de foco do navegador então se move para os itens recém-visíveis. Garanta que menus revelados sejam esperados e claramente comunicados via atributos ARIA como aria-expanded.
  • Confiar em bibliotecas de widgets de terceiros sem auditar seu comportamento de foco: Muitas bibliotecas de componentes de UI (seletores de data, editores de rich text, dropdowns estilo select2) historicamente violaram a 3.2.1 abrindo popups ou movendo o foco em eventos focus. Sempre audite componentes de terceiros manualmente antes da implantação, independentemente das alegações de acessibilidade da biblioteca.
  • Esquecer de testar em contextos de roteamento de aplicações de página única (SPA): Em SPAs React, Vue e Angular, eventos de foco em links de navegação às vezes podem acionar mudanças de rota por meio da lógica de prefetch do roteador ou de event bubbling, especialmente quando eventos de foco não são devidamente impedidos de se propagar. Teste componentes de navegação de SPAs explicitamente quanto à conformidade com a 3.2.1.

Relação com os Regulamentos de Acessibilidade da Turquia

A Circular Presidencial 2025/10 da Turquia, publicada no Diário Oficial nº 32933 em 21 de junho de 2025, estabelece requisitos obrigatórios de acessibilidade na web que fazem referência explícita às WCAG 2.2 como padrão técnico. WCAG 3.2.1 On Focus é um critério de Nível A, o que significa que está na base da conformidade obrigatória sob a circular. Não há isenções para critérios de Nível A — todas as entidades abrangidas devem cumpri-los dentro dos prazos definidos.

Instituições públicas são obrigadas a alcançar conformidade total dentro de um ano a partir da data de publicação da circular. Entidades do setor privado dentro do escopo têm dois anos. As entidades abrangidas pela Circular Presidencial 2025/10 incluem uma ampla gama de organizações: todas as instituições e agências públicas, plataformas de e-commerce e marketplaces online, bancos e instituições financeiras, hospitais e prestadores de serviços de saúde privados, empresas de telecomunicações com 200.000 ou mais assinantes, agências de viagem e plataformas de reserva, empresas de transporte privado e escolas e instituições de ensino privadas autorizadas pelo Ministério da Educação Nacional (MoNE).

A relevância de WCAG 3.2.1 On Focus para esses tipos de entidades é direta e prática. Considere uma plataforma de e-commerce em que um dropdown de categoria de produto navega automaticamente ao receber foco — um cliente com deficiência de mobilidade que usa teclado não consegue navegar pelas categorias de produto e abandonará a compra. Um formulário de transferência online de um banco com envios acionados por foco pode causar transações financeiras não intencionais ou tentativas repetidas e fracassadas para usuários de leitores de tela. Um sistema de agendamento de consultas de um hospital em que campos de data abrem modais ao receber foco pode impedir que pacientes com deficiência agendem cuidados de forma independente.

Nos termos da circular, a falta de conformidade expõe as entidades abrangidas a sanções administrativas e risco reputacional. Para entidades que atualmente passam por transformação digital ou estão adquirindo novos sistemas web, incorporar a conformidade com WCAG 3.2.1 nos requisitos de contratação e nas diretrizes de desenvolvimento agora — em vez de fazer adaptações após uma reclamação — é ao mesmo tempo mais econômico e mais alinhado com o espírito da regulamentação. Organizações que usam o SDK de overlay Accsible se beneficiam de ferramentas de gestão de foco integradas que ajudam a identificar e remediar comportamentos inesperados ao focar como parte de um fluxo de trabalho mais amplo de conformidade com WCAG 2.2 Nível A.