A ordem de tabulação padrão fornecida pela posição DOM dos elementos HTML semânticos é conveniente, mas pode haver momentos que você precise modificar a ordem da tabulação. Mover elementos no HTML é o ideal, mas pode não ser viável. Nesses casos, você
pode usar o atributo HTML tabindex
para definir explicitamente a posição da guia de um
elemento.
A tabindex
pode ser aplicada a qualquer elemento, embora não seja necessariamente
útil em todos eles, e usa um intervalo de valores inteiros. Com
tabindex
, você pode especificar uma ordem explícita para elementos de página focalizáveis,
inserir um elemento que não seria focalizável na ordem da tabulação e remover elementos
da ordem. Exemplo:
tabindex="0"
: insere um elemento na ordem natural de tabulação. O elemento pode
ser focado pressionando Tab, e o elemento pode ser focado chamando
o método focus()
.
tabindex="-1"
: remove um elemento da ordem natural de tabulação, mas o elemento
ainda pode ser focado chamando o método focus()
.
tabindex="5"
: qualquer tabindex maior que 0
coloca esse elemento na frente
da ordem natural de tabulação. Se houver vários elementos com um tabindex maior
que 0
, a ordem da tabulação começará pelo valor mais baixo que for maior que zero
e vai subindo. O uso de um tabindex maior que 0
é considerado um
antipadrão.
Isso é particularmente verdadeiro para elementos não de entrada, como cabeçalhos, imagens ou títulos de
artigos. Quando possível, é melhor organizar seu código-fonte de forma que a sequência DOM forneça uma ordem lógica de tabulação. Se você usar tabindex
, restrinja-o a controles interativos personalizados,
como botões, guias, menus suspensos e campos de texto, ou seja, elementos que
o usuário pode usar para inserir entradas.
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 entendê-lo sem
adicionar foco.
Gerenciar o foco no nível da página
Às vezes, tabindex
é necessário para uma experiência do usuário perfeita. Por exemplo,
se você criar uma única página robusta com diferentes seções de conteúdo, em que nem
todo o conteúdo fique visível simultaneamente. Isso pode significar que os links de navegação
mudam o conteúdo visível sem que a página seja atualizada.
Nesse caso, identifique a área de conteúdo selecionada, atribua 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 em sincronia com o conteúdo visual do site.
Gerenciar o foco em componentes
Em alguns casos, você também precisa gerenciar o foco no nível de controle, como no caso de componentes personalizados.
Por exemplo, o elemento select
pode receber foco básico, mas,
uma vez lá, você pode usar as teclas de seta para expor mais opções selecionáveis.
Se você criar um elemento select
personalizado, é importante replicar esse
comportamento para que os usuários do teclado ainda possam interagir com seu controle.
Saber quais comportamentos de teclado implementar pode ser difícil. O guia Práticas de criação de aplicativos de rich Internet acessíveis (ARIA, na sigla em inglês) lista os tipos de componentes e os tipos de ações de teclado compatíveis.
Talvez você esteja trabalhando em Elementos personalizados que se parecem com um conjunto de botões de opção, mas com uma visão única 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 a compatibilidade de teclado necessária, consulte o Guia de práticas de criação do ARIA. A seção 2 contém uma lista de padrões de design, incluindo a tabela de características para grupos de rádio, o componente existente que melhor corresponde ao novo elemento.
Um dos comportamentos comuns do teclado que precisa ser compatível são as teclas de seta para cima/para baixo/para a esquerda/direita. Para adicionar esse comportamento ao novo componente, usamos uma técnica chamada tabindex de itinerário.
O tabindex itinerante funciona definindo tabindex
como -1 para todos os filhos, exceto o
que está 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
anteriormente em foco 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 filho (ou primeiro, dependendo da direção em que ele está movendo o foco), o foco volta para o primeiro (ou o último) filho.
Teste o exemplo a seguir. Inspecione o elemento no DevTools para observar o tabindex se mover de um rádio para o próximo.
Armadilhas modais e de teclado
É melhor evitar gerenciar o foco manualmente, já que 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 a deixe até que ela seja concluída. Isso é chamado de armadilha do 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 pode ficar bloqueado ou preso em um elemento de página específico. O usuário precisa conseguir navegar de e para todos os elementos da página usando apenas o teclado.
A exceção a essa regra são os modais. No entanto, ainda é necessário evitar o uso de
tabindex
ao criar um modal. Com o inert
, você pode
garantir que os usuários não interajam acidentalmente com um elemento (uma armadilha
de teclado intencional). Use o elemento <dialog>
,
que é inerte por padrão, para criar um modal para os usuários e, ao mesmo tempo, bloquear
cliques e guias fora dele. Isso permite que o usuário se concentre em
uma seleção necessária.