Fotografia macro da tecla Tab de um teclado, iluminada em âmbar quente, isolada contra as teclas escuras ao redor

Navegação por teclado: como testar seu produto sem tocar no mouse

Ordem de tab, foco em modais e o skip link, explicados com os critérios reais do WCAG, mais um teste de dois minutos que qualquer designer pode rodar.

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.

Passo 1
Passo 2
Passo 3
Passo 4

Mesma ordem de marcação, sem reorder de CSS. Dê tab nessa também.

Passo 1
Passo 2
Passo 3
Passo 4

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.

Não visível
Quase invisível
Claramente visível

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.

  1. 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.
  2. TabO foco se move só pelos controles do próprio modal. Esperado: nunca alcança a página atrás dele.
  3. 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.
  4. 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.


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 <a class="skip-link" href="#main-content"> como primeiro elemento dentro do <body>, e um <main id="main-content" tabindex="-1"> correspondente como destino. tabindex="-1" no destino é o que permite que um link âncora simples realmente mova o foco de teclado para lá, não só role a viewport até ele.

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