Falhas de acessibilidade são decisões de design. A prova está aqui. cobriu navegação por teclado em três parágrafos: quem depende dela, a estatística de indicador de foco, e o skip link que o YouTube ainda erra. Aquele era o formato do problema. Este artigo é o guia prático: como a ordem de tab realmente é decidida, por que "só tira o anel de foco feio" quebra o produto para um grupo específico de usuários toda vez, como especificar o comportamento de foco de um modal para que um desenvolvedor implemente uma vez em vez de chutar, como construir um skip link corretamente, e um teste de dois minutos que você pode rodar em qualquer coisa antes de lançar.
Quem realmente precisa disso
A pesquisa de leitores de tela do WebAIM coloca a dependência do teclado entre usuários de leitor de tela em 97,6%. Esse número sozinho já subestima o público. Um mouse pede algo específico: controle fino suficiente na mão para pousar um cursor num alvo pequeno e clicar nele. Tremor, uso limitado ou nulo de um ou mais dedos, paralisia, artrite, e dedos ausentes removem essa capacidade sem remover a capacidade de pressionar uma tecla, usar um dispositivo de switch, ou usar uma entrada adaptada a switch que o navegador trata exatamente como um teclado. Esse é um eixo diferente das deficiências de mobilidade que o CDC rastreia, andar e subir escadas, que na maior parte não têm relação com a capacidade de alguém usar um mouse.
Nada disso exige um leitor de tela rodando. Exige que o produto funcione quando o ponteiro nunca se move. Esse é um grupo muito maior e muito mais fácil de testar do que "funciona com leitor de tela", e é sobre esse grupo que este artigo é.
A ordem de tab é decidida pelo DOM, não pelo layout
2.1 O que realmente determina a sequência
Pressionar Tab move o foco para o próximo elemento focável na ordem do DOM, a ordem em que os elementos aparecem no HTML por baixo, não a ordem em que aparecem na tela. Na maior parte do tempo essas duas ordens coincidem, porque a maioria dos layouts é construída do mesmo jeito que se lê. Elas param de coincidir no momento em que um layout é reordenado visualmente sem que ninguém toque na marcação por baixo, e o CSS torna isso trivialmente fácil de fazer por acidente.
2.2 Como uma decisão de design quebra isso sem uma única linha de script customizado
Uma propriedade `order` de CSS grid ou flexbox, usada para reorganizar um layout de cards num breakpoint mais estreito, muda o que o usuário vê sem mudar o que o DOM contém. A ordem de tab continua seguindo o DOM. O resultado é um usuário de teclado dando tab do que parece ser o card um, para o que parece ser o card três, porque é isso que a marcação diz que vem a seguir, independente de onde o card foi repintado na tela.
A linha ao vivo abaixo tem exatamente esse bug, e é seguro tentar. Clique nela e pressione Tab.
Ordem visual 1, 2, 3, 4. Dê tab nela.
Mesma ordem de marcação, sem reorder de CSS. Dê tab nessa também.
Rótulos idênticos, posição visual idêntica. A sequência de Tab da primeira linha é 2, 4, 1, 3. A da segunda é 1, 2, 3, 4. Nada na aparência de nenhuma das duas diz qual é qual.
2.3 A outra forma de quebrar: tabindex
Um valor positivo de tabindex (`tabindex="1"`, `tabindex="2"`) força um elemento para a frente da sequência de tab, à frente de tudo que usa a ordem padrão, e cria uma segunda ordem, concorrente, que precisa ser mantida manualmente para sempre conforme a página muda. A própria documentação de técnicas do WCAG cita esse padrão como algo a evitar. As regras de build deste próprio projeto proíbem tabindex positivo diretamente pelo mesmo motivo. `tabindex="0"` adiciona um elemento naturalmente não-focável à sequência padrão de ordem do DOM, o que é seguro. `tabindex="-1"` remove um elemento da sequência de Tab enquanto ainda permite que receba foco programaticamente, o que é o que torna possível mover o foco para o título de um modal na seção 4. Esses são os únicos dois valores que pertencem à marcação de produção.
Indicadores de foco não são estilo opcional
3.1 De onde vêm os 78%
O relatório WebAIM Million encontrou problemas detectáveis de indicador de foco em 78% das homepages analisadas. A causa raiz mais comum é `outline: none`, adicionado para remover o anel de foco padrão do navegador de um botão ou link porque ele conflitava com o design visual, sem nada colocado de volta no lugar. Visualmente a correção parece limpa. Para um usuário de teclado, a interface para de dizer onde ele está.
3.2 :focus-visible resolve a reclamação real
A reclamação por trás da maioria das decisões de `outline: none` nunca foi "indicadores de foco são feios." Era "o anel de foco aparecendo depois de um clique de mouse parece quebrado." `:focus-visible` resolve isso diretamente: deixa o navegador mostrar o indicador quando o foco chega pelo teclado e suprimir quando o foco chega por um clique de ponteiro, sem uma única linha de JavaScript. Não sobra motivo para recorrer a `outline: none` em 2026.
Dê tab em cada botão. Mesmo componente, três implementações, três experiências completamente diferentes para um usuário de teclado.
3.3 O WCAG 2.2 elevou a régua do que "visível" significa
O SC 2.4.7 Focus Visible (AA) só exige que um indicador de foco de teclado exista. O WCAG 2.2 adicionou dois critérios de sucesso que vão além: o SC 2.4.13 Focus Appearance (AAA) define um tamanho mínimo e contraste para o próprio indicador, então um outline de 1px e baixo contraste pode tecnicamente satisfazer o 2.4.7 enquanto ainda falha no 2.4.13. O SC 2.4.11 Focus Not Obscured (Minimum) (AA) exige que o elemento com foco não fique inteiramente escondido por outro conteúdo, o header fixo ou banner de cookies cobrindo ele. Os dois apontam para o mesmo modo de falha: um indicador que está presente mas inútil porque é fraco demais, pequeno demais, ou fisicamente escondido atrás de outra coisa na página.
Gerenciamento de foco dentro de modais e dropdowns
4.1 O mesmo modal, o lado do teclado da especificação
O que é ARIA e por que designers de produto precisam entender cobre o modal de excluir projeto pelo lado do ARIA: o papel, o rótulo, o comportamento que um designer precisa escrever para um desenvolvedor implementar corretamente. Este é o mesmo modal, testado. Um designer pode escrever as notas de comportamento corretas e ainda lançar um modal que falha, porque atributos ARIA e comportamento real de teclado são duas implementações separadas da mesma intenção, construídas em pontos diferentes do código. A única forma de saber se a segunda existe é rodar com o teclado você mesmo.
- Clicar no gatilhoO modal abre. Esperado: o foco vai para o título do diálogo, não para o primeiro botão dentro dele.
- TabO foco se move só pelos controles do próprio modal. Esperado: nunca alcança a página atrás dele.
- Shift+Taba partir do primeiro controle dentro do modal. Esperado: o foco volta para o último controle dentro do modal, não sai para a página.
- EscapeO modal fecha. Esperado: o foco volta para o exato elemento que abriu, não para o corpo da página.
Quatro teclas, quatro resultados esperados. Qualquer modal que falha numa dessas linhas falha para todo usuário só-de-teclado, independente do que a marcação ARIA diz.
4.2 A falha na direção oposta: uma armadilha de teclado
O SC 2.1.2 No Keyboard Trap (A) existe porque a falha oposta é igualmente desqualificante: o foco entra num widget, geralmente um embed de terceiro, um editor de texto rico, ou um seletor de data customizado, e Tab ou Escape não conseguem mais movê-lo para fora. Um modal que prende o foco de propósito, dentro de si mesmo, enquanto está aberto, é correto e exigido. Um componente que prende o foco por acidente, sem forma de sair, falha completamente. Os dois são testados com as mesmas quatro teclas acima.
O skip link
5.1 Para que serve
O artigo anterior desta série apontou que o YouTube, construído pela organização que escreveu boa parte do padrão, ainda não implementa seu skip link corretamente. Sem um, um usuário de teclado chegando a qualquer página com navegação repetida precisa dar tab em cada item dela, toda vez, antes de alcançar o conteúdo pelo qual a página realmente existe.
5.2 Como construir um
Um skip link é o primeiro elemento focável da página, visualmente escondido até receber foco, apontando para uma âncora na região de conteúdo principal. Ao receber foco, ele fica visível e fica acima de tudo mais na página. Ativá-lo, pressionando Enter, move o foco diretamente para o destino, pulando todo item de navegação pelo caminho. Toda página deste site abre com exatamente esse padrão: um `` como primeiro elemento dentro do ``, e um `
Sem skip link
- Tab 1: Logo
- Tab 2–9: 8 links de navegação
- Tab 10: Seletor de idioma
- Tab 11: Busca
- Tab 12: CTA de contato
- Tab 13: Conteúdo principal, finalmente
13 tabs antes do conteúdo
Com skip link
- Tab 1: "Pular para o conteúdo principal"
- Enter
1 tab, 1 tecla
Mesma página, mesma navegação. A única diferença é um link âncora bem no topo do documento.
O teste de dois minutos que qualquer designer pode rodar
Sem leitor de tela, sem plugin, sem precisar de desenvolvedor. Coloque o mouse fora de alcance, de verdade, não figurativamente, e use só Tab, Shift+Tab, Enter, Espaço, as setas, e Escape para completar o fluxo principal do produto. Quatro coisas para observar enquanto faz isso: você consegue alcançar todo elemento interativo da página, você sempre consegue ver qual tem foco no momento, a ordem em que você passa por eles corresponde à ordem em que você os leria, e você consegue abrir e fechar completamente todo modal ou dropdown sem o ponteiro tocar em nada. Uma falha em qualquer um dos quatro é a seção 2, 3 ou 4 acima, não um problema novo, as mesmas seis fontes às quais esta série sempre volta, decididas antes de um desenvolvedor escrever uma linha de código.
Fontes
- WebAIM. Screen Reader User Survey #10 Results. webaim.org/projects/screenreadersurvey10
- WebAIM. The WebAIM Million: The 2025 report on the accessibility of the top 1,000,000 home pages. webaim.org/projects/million
- W3C Web Accessibility Initiative. WCAG 2.2, SC 2.1.1 Keyboard, 2.1.2 No Keyboard Trap, 2.4.1 Bypass Blocks, 2.4.3 Focus Order, 2.4.7 Focus Visible. w3.org/TR/WCAG22
- W3C Web Accessibility Initiative. Understanding SC 2.4.11 Focus Not Obscured (Minimum) and SC 2.4.13 Focus Appearance. w3.org/WAI/WCAG22/Understanding/focus-appearance
- MDN Web Docs. :focus-visible. developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible
- W3C Web Accessibility Initiative. ARIA Authoring Practices Guide (APG), Dialog (Modal) Pattern. w3.org/WAI/ARIA/apg/patterns/dialog-modal