A ordem de tabulação padrão fornecida pela posição DOM de elementos HTML semânticos é conveniente, mas pode ser necessário modificá-la. Mover elementos no HTML é ideal, mas pode não ser viável. Nesses casos, é possível usar o atributo HTML tabindex
para definir explicitamente a posição de tabulação de um elemento.
tabindex
pode ser aplicado a qualquer elemento, embora não seja necessariamente útil em todos eles, e usa um intervalo de valores inteiros. Com
tabindex
, é possível especificar uma ordem explícita para elementos da página que podem receber foco,
inserir um elemento que não pode receber foco na ordem de tabulação e remover elementos
dessa ordem. Exemplo:
tabindex="0"
: insere um elemento na ordem natural de tabulação. O elemento pode
ser focado pressionando Tab ou chamando
o método focus()
dele.
tabindex="-1"
: remove um elemento da ordem natural de tabulação, mas ele
ainda pode ser focado chamando o método focus()
.
tabindex="5"
: qualquer tabindex maior que 0
traz esse elemento para a frente
da ordem de tabulação natural. Se houver vários elementos com um tabindex maior que 0
, a ordem de tabulação começará do menor valor maior que zero e aumentará gradualmente.
Isso é especialmente verdadeiro para elementos que não são de entrada, como cabeçalhos, imagens ou títulos de artigos. Sempre que possível, organize o código-fonte para que a sequência do DOM forneça uma ordem de tabulação lógica. Se você usar tabindex
, restrinja a controles interativos personalizados, como botões, guias, menus suspensos e campos de texto. Ou seja, elementos em que o usuário pode esperar fornecer entrada.
Adicione tabindex
apenas a conteúdo interativo. Mesmo que o conteúdo seja importante, como uma imagem principal, os usuários de leitores de tela podem entender sem adicionar foco.
Gerenciar o foco no nível da página
Às vezes, o tabindex
é necessário para uma experiência do usuário perfeita. Por exemplo, se você criar uma página única robusta com diferentes seções de conteúdo, em que nem todo o conteúdo fica visível simultaneamente. Isso pode significar que os links de navegação
mudam o conteúdo visível sem atualizar a página.
Nesse caso, identifique a área de conteúdo selecionada e atribua a ela um tabindex
de -1
e chame o método focus
. Isso garante que o conteúdo não apareça na ordem natural de tabulação. Essa técnica, chamada de gerenciamento de foco, mantém o contexto percebido pelo usuário sincronizado com o conteúdo visual do site.
Gerenciar o foco em componentes
Em alguns casos, também é necessário gerenciar o foco no nível do controle, como com componentes personalizados.
Por exemplo, o elemento select
pode receber foco básico, mas, depois disso, é possível usar as teclas de seta para mostrar outras opções selecionáveis.
Se você criar um elemento select
personalizado, é importante replicar esse
comportamento para que os usuários de teclado ainda possam interagir com seu controle.
Pode ser difícil saber quais comportamentos de teclado implementar. O guia de práticas de criação de aplicativos avançados de Internet acessíveis (ARIA) lista tipos de componentes e quais tipos de ações de teclado eles oferecem suporte.
Talvez você esteja trabalhando em elementos personalizados que se parecem com um conjunto de botões de opção, mas com sua abordagem exclusiva de aparência e comportamento.
<radio-group>
<radio-button>Water</radio-button>
<radio-button>Coffee</radio-button>
<radio-button>Tea</radio-button>
<radio-button>Cola</radio-button>
<radio-button>Ginger Ale</radio-button>
</radio-group>
Para determinar qual suporte de teclado é necessário, consulte o guia de práticas de criação da ARIA. A seção 2 contém uma lista de padrões de design, incluindo tabela de características para grupos de opções e o componente atual que mais se parece com o novo elemento.
Um dos comportamentos comuns do teclado que precisam ser compatíveis são as teclas de seta para cima/baixo/esquerda/direita. Para adicionar esse comportamento ao novo componente, usamos uma técnica chamada tabindex móvel.
Para usar o tabindex móvel, defina tabindex
como -1 para todos os filhos, exceto o
ativo no momento.
<radio-group>
<radio-button tabindex="0">Water</radio-button>
<radio-button tabindex="-1">Coffee</radio-button>
<radio-button tabindex="-1">Tea</radio-button>
<radio-button tabindex="-1">Cola</radio-button>
<radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>
O componente usa um listener de eventos de teclado para determinar qual tecla o
usuário pressiona. Quando isso acontece, ele define o tabindex
do filho focado anteriormente como -1, define o tabindex
do filho a ser focado como 0 e chama o
método de foco nele.
<radio-group>
<!-- Assuming the user pressed the down arrow, we'll focus the next available child -->
<radio-button tabindex="-1">Water</radio-button>
<radio-button tabindex="0">Coffee</radio-button> // call .focus() on this element
<radio-button tabindex="-1">Tea</radio-button>
<radio-button tabindex="-1">Cola</radio-button>
<radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>
Quando o usuário chega ao último (ou primeiro, dependendo da direção em que está movendo o foco) filho, o foco volta ao primeiro (ou último) filho.
Confira o exemplo a seguir. Inspecione o elemento nas DevTools para observar o tabindex se movendo de um botão de opção para o próximo.
Modais e capturas de teclado
É melhor evitar o gerenciamento manual do foco, porque isso pode levar a situações complicadas. Por exemplo, um widget de preenchimento automático que tenta gerenciar o foco e captura o comportamento da guia, mas impede que o usuário saia até que esteja completo. Isso é chamado de armadilha de teclado e pode ser muito frustrante para o usuário.
A seção 2.1.2 das WCAG afirma que o foco do teclado nunca deve ser bloqueado ou preso em um elemento específico da página. O usuário precisa conseguir navegar para e de todos os elementos da página usando apenas o teclado.
A exceção a essa regra são os modais. No entanto, evite usar
tabindex
ao criar um modal. Com o inert
, você pode
garantir que os usuários não interajam acidentalmente com um elemento (uma
captura de teclado intencional). Use o elemento <dialog>
, que é inerte por padrão, para criar um modal para os usuários e bloquear
cliques e guias fora dele. Isso permite que o usuário se concentre em uma
seleção obrigatória.