Critérios de Sucesso WCAG · Level AA

WCAG 2.4.7: Foco Visível

A WCAG 2.4.7 exige que qualquer interface de usuário operável por teclado tenha um indicador de foco visível, para que as pessoas possam sempre ver qual elemento está atualmente com o foco do teclado. Isso é essencial para pessoas que usam apenas o teclado, pessoas com deficiências motoras e qualquer pessoa que não possa usar um mouse.

O que Esta Regra Significa

WCAG 2.4.7 Focus Visible exige que todo elemento interativo em uma página da web — links, botões, campos de formulário, widgets personalizados e qualquer outro componente operável por teclado — exiba um indicador de foco visível quando receber foco pelo teclado. Em termos simples, quando uma pessoa usuária pressiona a tecla Tab para percorrer a página, ela deve conseguir ver exatamente qual elemento está ativo naquele momento.

O critério não exige um estilo visual específico para o indicador de foco. Ele apenas requer que ocorra alguma mudança visível. Dito isso, um indicador quase imperceptível — por exemplo, um contorno pontilhado de um pixel que se confunde com o fundo — pode, tecnicamente, estar em conformidade com 2.4.7, mas ainda assim falhar no critério mais exigente WCAG 2.4.11 (Focus Appearance) introduzido no WCAG 2.2. Considerando apenas o 2.4.7, qualquer mudança visual discernível é suficiente.

O que conta como aprovação: Um indicador de foco é considerado aprovado se uma pessoa usuária com visão, ao usar Tab para percorrer a página, conseguir identificar qual elemento está em foco sem depender de anúncios de leitor de tela ou outros sinais não visuais. Implementações comuns aceitáveis incluem contornos padrão do navegador, regras CSS personalizadas de outline ou box-shadow, mudanças de sublinhado ou de cor de fundo aplicadas em :focus ou :focus-visible.

O que conta como falha: Ocorre falha quando uma pessoa desenvolvedora remove o anel de foco padrão do navegador — normalmente via outline: none ou outline: 0 em CSS — e não o substitui por um indicador personalizado equivalente. Falhas também ocorrem quando um componente personalizado (construído com elementos <div> ou <span>) é tornado focável por teclado via tabindex, mas não recebe nenhuma mudança de estilo visível ao ganhar foco.

Exceções oficiais: As WCAG observam que o critério se aplica apenas a interfaces operáveis por teclado. Componentes que são puramente decorativos ou explicitamente excluídos da ordem de tabulação (via tabindex='-1') não são obrigados a exibir um indicador de foco, porque não podem receber foco por meio da navegação normal por teclado.

Por Que Isso Importa

A visibilidade do foco é fundamental para a acessibilidade por teclado, e a acessibilidade por teclado é a porta de entrada para o acesso de uma ampla gama de grupos de pessoas com deficiência. Aproximadamente 26% dos adultos nos Estados Unidos vivem com algum tipo de deficiência, de acordo com o CDC, e muitas dessas pessoas dependem de teclados ou de tecnologias assistivas que emulam teclado, em vez de dispositivos apontadores.

Pessoas com deficiência motora — incluindo pessoas com condições como ELA, paralisia cerebral, lesão por esforço repetitivo ou doença de Parkinson — frequentemente dependem de teclados, dispositivos de varredura, controladores de sopro e sucção ou softwares de rastreamento ocular. Todos esses métodos de entrada dependem do modelo de foco de teclado do navegador. Se o indicador de foco for invisível, essas pessoas não conseguem determinar onde estão na página, não conseguem ativar o controle correto e podem ficar totalmente impedidas de realizar tarefas críticas, como enviar um formulário, concluir uma compra ou navegar em um menu.

Pessoas com baixa visão que não usam leitor de tela, mas podem ampliar a tela, também dependem do foco visível. Quando ampliam uma parte da página, o anel de foco visível indica qual elemento está ativo e orienta sua interação.

Pessoas com deficiências cognitivas e relacionadas à atenção também se beneficiam de indicadores de foco claros. Pessoas com TDAH ou dificuldades de memória frequentemente perdem a noção de sua posição em uma página complexa; um indicador de foco proeminente fornece uma âncora visual confiável.

Um cenário concreto do mundo real: considere uma pessoa com esclerose múltipla que navega em um site de e-commerce usando apenas o teclado porque a precisão do mouse se tornou difícil. Ela usa Tab na página de produto para chegar ao botão "Add to Cart". Se a pessoa desenvolvedora suprimiu o anel de foco, a pessoa usuária não vê nenhuma indicação de onde o foco está. Ela pressiona Enter e ou nada acontece (o foco caiu em um elemento não interativo) ou a ação errada é disparada. O resultado é frustração, abandono da tarefa e perda de receita para o negócio — tudo evitável com uma única regra CSS.

Além da deficiência, indicadores de foco beneficiam todas as pessoas usuárias em situações em que o uso do mouse é inconveniente: pessoas usuárias avançadas que navegam por atalhos de teclado, pessoas usando laptop sem mouse externo e pessoas preenchendo formulários longos. O foco visível também melhora o SEO indiretamente, ao incentivar HTML semântico e ordem de tabulação adequada, ambos valorizados por rastreadores de mecanismos de busca.

Regras Relacionadas do Axe-core

WCAG 2.4.7 exige testes manuais porque ferramentas automatizadas não conseguem determinar de forma confiável se um indicador de foco é visível. Axe-core e mecanismos semelhantes podem detectar que existe uma regra CSS como outline: none, mas não conseguem avaliar o resultado visual renderizado em todos os temas, modos de alto contraste e mecanismos de renderização de navegador. A seguir, uma explicação do cenário de testes:

  • Teste manual obrigatório — supressão de focus-visible: Axe-core não inclui uma regra dedicada que sinalize de forma definitiva falhas em 2.4.7, porque isso exigiria renderizar a página, usar Tab em cada elemento e realizar análise de contraste em nível de pixel no indicador de foco — uma tarefa além da análise estática ou em nível de DOM. Em vez disso, pessoas testadoras devem percorrer manualmente a página com Tab e confirmar visualmente que cada elemento interativo mostra uma mudança de foco.
  • Sinal parcial de css-orientation-lock e verificações de estilo: Algumas configurações do axe-core sinalizam a presença de outline: 0 ou outline: none em folhas de estilo como um aviso de boa prática, mas isso é uma heurística, não uma verificação definitiva de violação, porque a regra pode ser sobrescrita por um estilo de foco personalizado válido em outro ponto da cascata.
  • Por que a automação é insuficiente: Um indicador de foco pode estar oculto apenas em certos estados (por exemplo, quando um modal está aberto), apenas para certos tipos de elementos ou apenas em determinados temas de cor. Essas falhas condicionais exigem que uma pessoa testadora navegue por cada elemento interativo no ambiente realmente renderizado e confirme a visibilidade. Ferramentas como axe DevTools Pro podem ajudar destacando elementos que têm outline: none aplicado, mas a decisão final de aprovação/reprovação deve ser humana.

Como Testar

  1. Pré-varredura automatizada: Execute axe DevTools (extensão de navegador ou CLI) ou Google Lighthouse na página. Procure avisos de boas práticas ou experimentais relacionados a estilos de foco. Embora eles não confirmem de forma definitiva uma falha em 2.4.7, destacam elementos que valem a inspeção. No Lighthouse, verifique a categoria "Accessibility" para achados relacionados a foco. Exporte o relatório e anote todos os elementos interativos sinalizados.
  2. Teste manual de tabulação por teclado: Desconecte ou afaste o mouse. Pressione Tab repetidamente a partir do topo da página e navegue por todos os elementos interativos — links, botões, campos, dropdowns, modais, abas, acordeões e seletores de data. Em cada parada, confirme que o elemento em foco é visualmente distinguível de seus vizinhos sem foco. Registre qualquer elemento em que a chegada do foco não produza mudança visível.
  3. Teste de tabulação reversa: Use Shift+Tab para navegar para trás pela página e repita a verificação visual. Algumas implementações só quebram a visibilidade do foco em uma direção devido a problemas de especificidade de CSS.
  4. Teste NVDA + Firefox: Abra o Firefox com o NVDA em execução. Use o Modo de Navegação (setas) e depois mude para o Modo de Formulários (Enter) para interagir com controles de formulário. Confirme que todo elemento que o NVDA anuncia como em foco também exibe um indicador visível na tela — útil para detectar discrepâncias entre o foco do TA e o foco do navegador.
  5. Teste VoiceOver + Safari (macOS/iOS): Ative o VoiceOver e use Tab ou VO+Seta para a Direita para percorrer elementos interativos. Verifique visualmente se o anel de foco na tela corresponde ao que o VoiceOver anuncia.
  6. Teste JAWS + Chrome: Use o JAWS no modo de cursor virtual e depois no modo de aplicativo. Use Tab pelos controles interativos e confirme que o indicador de foco visível aparece em todo elemento focado.
  7. Teste em modo de alto contraste: Ative o Modo de Alto Contraste do Windows (ou Aumentar Contraste no macOS) e repita o teste com Tab. Alguns indicadores de foco dependem de cores que desaparecem em temas de alto contraste; o indicador deve permanecer visível nesses modos.
  8. Inspeção de CSS: Abra o DevTools do navegador, selecione um elemento interativo, coloque-o em foco pressionando Tab até que esteja ativo e inspecione os estilos computados. Verifique se nenhuma regra define outline: none ou outline: 0 sem um estilo de foco compensatório. Verifique também :focus-visible versus :focus para garantir que o foco acionado por teclado esteja coberto.

Como Corrigir

Supressão global de outline sem substituição — Incorreto

<!-- CSS resets que removem todos os indicadores de foco globalmente -->
<style>
  * {
    outline: none; /* Remove o anel de foco de todos os elementos */
  }
</style>

<a href='/products'>View Products</a>
<button type='submit'>Buy Now</button>

Supressão global de outline sem substituição — Correto

<!-- Remova o reset global outline: none.
     Forneça um estilo de foco personalizado visualmente claro. -->
<style>
  /* Respeite pessoas que preferem movimento reduzido */
  :focus-visible {
    outline: 3px solid #005fcc;
    outline-offset: 2px;
  }
</style>

<a href='/products'>View Products</a>
<button type='submit'>Buy Now</button>
<!-- Agora ambos os elementos exibem um contorno azul de alto contraste quando focados via teclado -->

Botão personalizado baseado em div sem estilo de foco — Incorreto

<!-- Uma div estilizada como botão, tornada focável, mas sem CSS :focus -->
<style>
  .fake-btn {
    display: inline-block;
    padding: 10px 20px;
    background: #e00;
    color: #fff;
    cursor: pointer;
  }
  /* Nenhuma regra :focus ou :focus-visible definida */
</style>

<div class='fake-btn' tabindex='0' role='button'
     onclick='addToCart()' onkeydown='handleKey(event)'>
  Add to Cart
</div>

Botão personalizado baseado em div sem estilo de foco — Correto

<!-- Adicione :focus-visible ao componente personalizado para que
     pessoas usuárias de teclado vejam um indicador claro quando este elemento estiver em foco -->
<style>
  .fake-btn {
    display: inline-block;
    padding: 10px 20px;
    background: #e00;
    color: #fff;
    cursor: pointer;
  }
  .fake-btn:focus-visible {
    outline: 3px solid #ffcc00;
    outline-offset: 3px;
  }
</style>

<div class='fake-btn' tabindex='0' role='button'
     onclick='addToCart()' onkeydown='handleKey(event)'>
  Add to Cart
</div>
<!-- O contorno amarelo aparece apenas no foco por teclado, não no clique do mouse -->

Anel de foco oculto dentro de um modal overlay — Incorreto

<!-- O modal aplica overflow:hidden e um contexto de empilhamento que
     recorta o outline padrão, tornando-o invisível -->
<style>
  .modal-body {
    overflow: hidden; /* Recorta outlines que se estendem além do elemento */
    border-radius: 8px;
  }
</style>

<div class='modal-body'>
  <button>Confirm Order</button>
  <button>Cancel</button>
</div>

Anel de foco oculto dentro de um modal overlay — Correto

<!-- Use box-shadow em vez de outline para que ele seja renderizado
     dentro do contexto de empilhamento e nunca seja recortado -->
<style>
  .modal-body {
    overflow: hidden;
    border-radius: 8px;
  }
  .modal-body button:focus-visible {
    /* box-shadow não é recortado por overflow:hidden --
       ele permanece dentro da própria caixa do elemento -->
    box-shadow: 0 0 0 3px #005fcc;
    outline: none; /* Remova o padrão para evitar anel duplo */
  }
</style>

<div class='modal-body'>
  <button>Confirm Order</button>
  <button>Cancel</button>
</div>

Erros Comuns

  • Adicionar outline: none a um reset CSS base sem auditar quais elementos ele afeta. Muitos resets populares (por exemplo, versões mais antigas do normalize.css ou utilitários do Bootstrap) suprimem anéis de foco globalmente. Sempre complemente com uma regra explícita de :focus-visible que restaure a visibilidade para pessoas usuárias de teclado.
  • Confiar apenas em :focus quando :focus-visible é mais apropriado — ou vice-versa. Usar apenas :focus aplica o indicador também em cliques de mouse, o que pode parecer estranho. Usar apenas :focus-visible sem um fallback em :focus pode deixar navegadores mais antigos sem qualquer indicador. Teste em todos os navegadores-alvo.
  • Aplicar outline: none dentro de uma sobrescrita de tema de biblioteca de componentes sem entender a cascata. Uma única sobrescrita em um arquivo de tema pode apagar silenciosamente indicadores de foco de todos os componentes que herdam dela, incluindo widgets de terceiros.
  • Usar uma cor de foco com contraste insuficiente em relação ao elemento ou ao fundo da página. Um contorno cinza-claro em um fundo branco tecnicamente adiciona um contorno, mas pode ser imperceptível. Embora 2.4.7 não exija uma taxa de contraste específica, 2.4.11 exige — e indicadores de foco com baixo contraste são uma fonte comum de falhas em auditorias, mesmo quando pessoas desenvolvedoras acreditam estar em conformidade.
  • Definir overflow: hidden ou clip-path em um contêiner, o que recorta o outline padrão do navegador. A correção é mudar para indicadores de foco baseados em box-shadow, que são renderizados dentro da própria caixa do elemento e não são recortados por regras de overflow do elemento pai.
  • Esquecer indicadores de foco em elementos interativos dentro de componentes SVG ou Canvas. Tooltips personalizados de gráficos, botões de ícone baseados em SVG e ferramentas de desenho baseadas em canvas frequentemente não têm estilo de foco nativo. Eles exigem papéis ARIA explícitos, tabindex e CSS :focus-visible ou feedback visual acionado por JavaScript.
  • Remover a visibilidade do foco apenas no CSS de produção (por exemplo, via pós-processador ou etapa de build) enquanto a mantém visível no ambiente de desenvolvimento. Isso faz com que a equipe de desenvolvimento aprove o QA local enquanto entrega acessibilidade quebrada para as pessoas usuárias finais.
  • Aplicar um indicador de foco apenas ao elemento <a>, mas não a elementos role='link' usados como links de navegação em SPA. Todo elemento focável por teclado — independentemente de sua tag nativa — precisa de um estado de foco visível.
  • Ocultar anéis de foco apenas em certas larguras de viewport via media queries, presumindo que pessoas usuárias em dispositivos móveis sempre tocam na tela. Pessoas usuárias de tablet com teclados Bluetooth e pessoas em orientação paisagem que dependem de entrada por teclado ficam sem qualquer indicador de foco.
  • Usar JavaScript para chamar .blur() imediatamente após o foco programático para impedir que o anel de foco apareça. Este é um erro crítico que remove completamente a visibilidade do foco e nunca deve ser usado como atalho de design.

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 web e móvel para uma ampla gama de entidades que operam na Turquia. A circular exige conformidade com WCAG 2.2 no Nível AA para as organizações abrangidas, tornando WCAG 2.4.7 Focus Visible um requisito diretamente aplicável, e não apenas uma recomendação de boa prática.

As entidades abrangidas pela circular incluem instituições e agências públicas, plataformas de e-commerce, bancos e prestadores de serviços financeiros, hospitais e organizações de saúde, empresas de telecomunicações com 200.000 ou mais assinantes, agências de viagem, empresas de transporte privado e escolas particulares autorizadas pelo Ministério da Educação Nacional (MoNE). Para todas essas organizações, deixar de fornecer indicadores de foco visíveis em suas interfaces digitais é uma questão de não conformidade regulatória, não apenas uma deficiência de usabilidade.

O Erişilebilirlik Logosu (Logotipo de Acessibilidade), emitido pelo Ministério da Família e Serviços Sociais, serve como marca oficial de certificação que as entidades abrangidas podem exibir para demonstrar conformidade. Alcançar o Logotipo de Acessibilidade exige aprovação em uma auditoria formal em WCAG 2.2 Nível AA. WCAG 2.4.7 é um dos critérios de Nível AA que as pessoas auditoras irão avaliar, normalmente por meio de testes manuais de teclado, conforme descrito na seção de testes acima. Uma organização cujo site suprime anéis de foco ou não implementa foco visível em componentes personalizados não será aprovada na auditoria necessária para o logotipo.

Para plataformas turcas de e-commerce em particular, a visibilidade do foco tem implicações comerciais diretas: sites acessíveis alcançam uma base de pessoas usuárias mais ampla, incluindo clientes com deficiências motoras que compram exclusivamente via teclado ou acesso por varredura, e a conformidade com a Circular Presidencial 2025/10 protege as organizações de ações administrativas. Incorporar padrões de foco visível na biblioteca de componentes desde o início — em vez de fazer adaptações após uma auditoria — é o caminho mais econômico para manter o Erişilebilirlik Logosu e cumprir as obrigações de acessibilidade da Turquia.