Os elementos interativos, incluindo controles de formulário, links e botões, são focalizáveis e podem ser acessados com a tecla Tab por padrão. Os elementos que podem ser selecionados com a tecla Tab fazem parte da ordem de navegação sequencial do documento. Outros elementos são inertes, ou seja, não são interativos. Com atributos HTML, é possível tornar elementos interativos inertes e elementos inertes interativos.
Por padrão, a ordem de foco da navegação é a mesma da ordem visual, que é a ordem do código-fonte. Há atributos HTML que podem alterar essa ordem e propriedades CSS que podem mudar a ordem visual do conteúdo. Mudar a ordem de tabulação com HTML ou a ordem de renderização visual com CSS pode prejudicar a experiência do usuário.
Não altere a ordem de tabulação percebida e real com CSS e HTML. Como demonstram os dois exemplos a seguir, as ordens de tabulação que diferem da ordem visualmente esperada confundem os usuários e prejudicam a experiência.
Neste exemplo, o valor do atributo tabindex
tornou a ordem de tabulação caótica:
Neste exemplo, o CSS criou uma divergência entre a ordem de tabulação e a ordem visual do conteúdo:
A declaração flex-flow: row-reverse;
inverteu a ordem visual.
Além disso, a propriedade order do CSS foi aplicada à sexta palavra, "This", que moveu visualmente essa palavra. A sequência de tabulação é a ordem do código, que não corresponde mais à ordem visual, criando uma desconexão para usuários de teclado.
Tornar elementos inertes interativos
Os atributos contenteditable
e tabindex
, sendo globais, podem ser adicionados a qualquer elemento, tornando-os focáveis
no processo. Os elementos focalizáveis também podem ser focalizados com um mouse ou ponteiro, definindo o atributo autofocus
ou por script, como com element.focus()
.
O atributo tabindex
O atributo global tabindex
, introduzido em atributos, permite que
elementos que, de outra forma, não poderiam receber foco o recebam,
geralmente com a tecla Tab, por isso o nome.
O atributo tabindex
usa um número inteiro como valor. Um valor negativo torna um elemento focalizável, mas não navegável com a tecla Tab. Um valor tabindex
de 0
torna o
elemento focalizável e navegável com a tecla Tab, adicionando o elemento em que ele é aplicado à
ordem de navegação de foco sequencial na ordem do código-fonte. Um valor de 1 ou
maior torna o elemento focalizável e navegável com a tecla Tab, mas o adiciona a uma sequência
de navegação com a tecla Tab priorizada e deve ser evitado.
Nesta página, o botão de compartilhamento, <share-action>
, é um
elemento personalizado. O tabindex="0"
adiciona esse elemento que normalmente não é focalizável à ordem de tabulação padrão do teclado:
<share-action authors="@front-end.social/@estellevw" data-action="click" data-category="web.dev" data-icon="share" data-label="share, mastodon" role="button" tabindex="0">
<svg aria-label="share" role="img" xmlns="http://www.w3.org/2000/svg">
<use href="#shareIcon" />
</svg>
<span>Share</span>
</share-action>
Há outro elemento personalizado nesta página: a navegação local tem um elemento personalizado com um valor tabindex
negativo:
<web-navigation-drawer type="standard" tabindex="-1">
Um atributo tabindex
com um valor negativo torna o elemento focalizável, mas não navegável com a tecla Tab. O elemento pode receber
foco, como usando HTMLElement.focus()
, mas não faz parte
da ordem de navegação por foco sequencial. A convenção para elementos não tabuláveis e focalizáveis é usar tabindex="-1"
. Se você adicionar tabindex="-1"
a um elemento interativo, ele não poderá mais ser selecionado com a tecla Tab.
O método element.focus()
pode ser usado para definir o foco em elementos focalizáveis. Os navegadores rolam os elementos
focalizados para a visualização. Por isso, evite usar element.focus({preventScroll:true})
, já que focar em um elemento não visível é uma experiência ruim para o usuário.
Se você quiser consultar o documento para descobrir qual elemento está em foco, use a propriedade somente leitura Document.activeElement
.
Elementos com um tabindex
de 1
ou maior são incluídos em uma sequência de guias separada. Como você vai notar no Codepen, o uso da tecla Tab começa em uma sequência separada, em ordem do menor para o maior valor, antes de passar pelos valores na sequência regular (nenhum tabindex
definido ou tabindex="0"
) na ordem de origem:
tabindex
com um valor positivo coloca o elemento em uma sequência de foco prioritária, o que pode levar ao caos na ordem de foco.
Evite modificar a ordem do DOM com tabindex
. Além de criar experiências ruins para o usuário, as ordens de tabulação alteradas são difíceis de gerenciar e manter para os desenvolvedores.
O atributo contenteditable
O atributo contenteditable
foi discutido anteriormente. Definir contenteditable="true"
em qualquer elemento o torna editável,
focável e parte da ordem de tabulação. O comportamento de foco é semelhante a definir tabindex="0"
, mas não é igual. Elementos contenteditable
aninhados são focalizáveis, mas não podem ser selecionados com a tecla Tab. Para tornar um elemento contenteditable
aninhado acessível com a tecla Tab, adicione tabindex="0"
,
que o adiciona à ordem de navegação sequencial por foco.
Atribuir autofocus
a elementos interativos
Embora o booleano autofocus
seja um atributo global
que pode ser definido em qualquer elemento, ele não torna um elemento inerte interativo. Quando a página é carregada, o primeiro elemento focalizável
com os atributos autofocus
recebe o foco, desde que esse elemento seja exibido e não esteja aninhado em um <dialog>
.
Definir o foco automaticamente no conteúdo pode ser confuso. Definir autofocus
em um controle de formulário significa que ele
aparece ao rolar a página. Todos os usuários, incluindo aqueles que usam leitores de tela e aqueles com pequenas janelas de visualização, podem não "ver" as instruções do formulário, talvez até rolando além do rótulo normalmente visível do controle do formulário. O atributo autofocus
não altera a ordem de navegação sequencial por foco do documento. Os elementos na sequência que vêm antes do
elemento com foco automático são ignorados. Por esses motivos, não é recomendável incluir o atributo autofocus
.
A exceção à recomendação "não use autofocus
" é incluir o
atributo autofocus
em elementos <dialog>
. Quando uma caixa de diálogo é aberta, o navegador se concentra automaticamente no primeiro elemento interativo focalizável dentro do <dialog>
. Isso significa que não é necessário adicionar autofocus
a um elemento. Se
você quiser garantir que um elemento interativo específico na caixa de diálogo receba
o foco quando ela for aberta, adicione o atributo autofocus
a esse elemento.
<dialog open>
<form method="dialog">
<button type="submit" autofocus>close</button>
</form>
</dialog>
O atributo autofocus
definido no botão de fechar <button>
permite que ele receba o foco
quando a caixa de diálogo é aberta. Como o primeiro elemento na caixa de diálogo, ele teria recebido o foco de qualquer maneira. Por padrão, quando uma caixa de diálogo é aberta, o primeiro elemento
focável dentro dela recebe o foco, a menos que um elemento diferente
tenha o atributo autofocus
definido.
Tornar elementos interativos inertes
Há também atributos HTML que podem remover elementos interativos da sequência de tabulação. Incluir um tabindex
negativo em elementos focalizáveis, adicionar o atributo disabled
a controles de formulário compatíveis e adicionar o atributo global inert
a um contêiner faz com que os elementos não possam ser acessados com a tecla Tab. Esses três atributos NÃO são intercambiáveis.
Valor tabindex
negativo
Um atributo tabindex
com um valor negativo torna um elemento focalizável, mas não
navegável com a tecla Tab. Ao adicionar tabindex="0"
a um elemento que pode ser focado por padrão,
incluindo links, botões, controles de formulário e elementos que são contenteditable
não é necessário. Incluir um tabindex
com um valor negativo remove elementos normalmente
tabuláveis da ordem de navegação de foco sequencial.
Um valor tabindex
negativo impede que os usuários do teclado se concentrem em elementos interativos, mas não desativa o elemento. Os usuários de ponteiro ainda podem se concentrar no elemento. Para desativar um elemento, use o atributo disabled
.
Desativado
O atributo booleano disabled faz com que os controles de formulário em que ele é aplicado e os descendentes deles, se houver, não possam ser focados. Controles de formulário desativados não podem ser focados, não recebem eventos de clique e não são enviados com o formulário.
disabled
não é um atributo global. Ela se aplica a <button>
, <input>
,
<optgroup>
, <option>
, <select>
, <textarea>
, elementos personalizados
associados a formulários e <fieldset>
.
Quando definido como <optgroup>
ou <fieldset>
, todos os controles de formulário filhos são desativados, exceto o conteúdo do primeiro <legend>
de <fieldset>
.
Os mesmos elementos que oferecem suporte a disabled
também podem ser segmentados com as
pseudoclasses :disabled
e :enabled
. Os elementos desativados com o atributo disabled
geralmente são estilizados como cinza claro com a folha de estilo do user agent, mesmo que um accent-color
seja definido.
Como é um atributo booleano, a presença dele desativa o elemento que, de outra forma, estaria ativado. Não é possível definir como false
. Para reativar um elemento desativado,
o atributo precisa ser removido, geralmente com
Element.removeAttribute('disabled')
.
A propriedade HTMLInputElement.disabled
permite verificar se uma entrada está desativada. Como disabled
não é um atributo global, ele não é herdado do HTMLElement, mas todas as interfaces de elementos compatíveis, como HTMLSelectElement
, HTMLTextareaElement
, têm a mesma propriedade somente leitura.
O atributo disabled
não se aplica a elementos normalmente inert
que são
focalizáveis com tabindex
ou contenteditable
, nem ao elemento
<form>
. Para desativar esses elementos, use o atributo global inert
.
O atributo inert
Quando o atributo booleano global inert
é adicionado a um elemento, ele
e todo o conteúdo aninhado são desativados, o que significa que não é possível clicar ou
navegar com a tecla Tab. Eles também são removidos da árvore de acessibilidade. Embora inert
possa ser aplicado a qualquer elemento, ele geralmente é usado para seções de conteúdo,
como conteúdo fora da tela ou oculto.
Ao aplicar disabled
a controles de formulário, o navegador fornece um estilo padrão
que pode ser estilizado usando a pseudoclasse :disabled
. O atributo inert
não fornece indicadores visuais e não tem uma pseudoclasse correspondente (embora o [inert]
seletor de atributo corresponda).
Usar inert
em conteúdo visível sem estilos que indiquem a inércia pode
resultar em uma experiência ruim para o usuário. Como o conteúdo inerte não está disponível para usuários de leitores de tela, isso pode causar confusão quando usuários com visão veem conteúdo na tela que não está disponível para as ferramentas de acessibilidade. Deixe a inércia muito
aparente com CSS.
Verifique se o foco nunca muda para conteúdo não visível. Qualquer coisa renderizada fora da tela que não apareça automaticamente quando focada deve ser tornada inerte. Se o conteúdo estiver oculto, mas aparecer quando estiver em foco, como um link para pular para o conteúdo, ele não precisa ser tornado inerte.
Teste seu conhecimento
Teste seus conhecimentos sobre foco.
Se um elemento não puder ser focado, ele será descrito como o quê?
O que será verdadeiro se o elemento tiver um atributo disabled
?