Modificar a ordem do DOM com tabindex

Dave Gash
Dave Gash
Meggin Kearney
Meggin Kearney
Alexandra Klepper
Alexandra Klepper

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.

Compatibilidade com navegadores

  • 1
  • 12
  • 1,5
  • ≤4

Origem

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.