Elementos interativos, incluindo controles de formulário, links e botões, são focalizáveis e tabulares por padrão. Os elementos com tabulação fazem parte da ordem de navegação de foco sequencial do documento. Outros elementos são inertes, o que significa que não são interativos. Com os atributos HTML, é possível tornar os elementos interativos inerentes e tornar os elementos inertes interativos.
Por padrão, a ordem do foco da navegação é a mesma que a visual, que é a ordem do código-fonte. Há atributos HTML que podem alterar essa ordem, e propriedades CSS que podem alterar 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 mostrado nos dois exemplos a seguir, as ordens de tabulação diferentes da ordem visualmente esperada são confusas para os usuários e ruins para a experiência deles.
Neste exemplo, o valor do atributo tabindex
tornou a ordem da tabulação caótica:
Neste exemplo, o CSS criou uma divergência entre a ordem da 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 CSS order era 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.
Como tornar elementos inertes interativos
Os atributos contenteditable
e tabindex
, sendo atributos globais, podem ser adicionados a qualquer elemento, tornando-os focalizáveis no processo. Os elementos focalizáveis também podem ser focados com um mouse ou ponteiro, definindo o atributo autofocus
ou por um script, como element.focus()
.
O atributo tabindex
O atributo tabindex
global, introduzido em
atributos, ativa elementos que, de outra forma, não poderiam receber foco,
geralmente com a tecla Tab. Por isso esse nome vem por aí.
O atributo tabindex
assume como valor um número inteiro. Um valor negativo torna um elemento focalizável, mas não tabulável. Um
valor tabindex
de 0
torna o elemento focalizável e com tabulação, 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 compatível com tabulação,
mas o adiciona a uma sequência de tabulação priorizada e, como vimos acima, precisa 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 nessa 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 com tabulação. O elemento é capaz de receber
foco, por exemplo, via HTMLElement.focus()
, mas não faz parte
da ordem de navegação de foco sequencial. A convenção para elementos focalizáveis e não tabulares é usar tabindex="-1"
. Se você
adicionar um tabindex="-1"
a um elemento interativo, ele não poderá mais ser usado 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 focados para serem vistos. Por isso, evite usar
element.focus({preventScroll:true})
, já que focar em um elemento não visível resulta em 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 tabulação separada. Como você notará no Codepen,
a tabulação começa em uma sequência separada, do menor para o maior valor, antes de passar pelos itens na sequência normal
(sem tabindex
definido ou tabindex="0"
) na ordem de origem:
tabindex
com um valor positivo coloca o elemento em uma sequência de foco priorizada, o que pode levar ao caos da ordem de foco.
Evite modificar a ordem do DOM com tabindex
. Além de criarem más experiências do usuário, os pedidos
de tabulação alterados também são difíceis de gerenciar e manter.
O atributo contenteditable
O atributo contenteditable
já foi discutido. Definir contenteditable="true"
em qualquer elemento o torna editável,
focável e parte da ordem da tabulação. O comportamento do foco é semelhante à configuração de tabindex="0"
, mas não é o mesmo. Os elementos
contenteditable
aninhados são focalizáveis, mas não tabuláveis. Para permitir a tabulação de um elemento contenteditable
aninhado, adicione tabindex="0"
,
que vai adicioná-lo à ordem de navegação de foco sequencial.
Focar elementos interativos
O atributo autofocus
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 o atributo autofocus
definido recebe foco, desde que esse elemento seja exibido e não aninhado em um <dialog>
.
Definir automaticamente o foco no conteúdo pode ser confuso. Definir autofocus
em um controle de formulário significa que ele será exibido na tela quando a página for carregada. Todos os seus usuários, incluindo usuários de leitores de tela e usuários com janelas de visualização pequenas, podem não
"ver" as instruções do formulário, possivelmente rolando a página além do marcador normalmente visível do controle. O atributo autofocus
não muda a ordem de navegação de foco sequencial do documento. Os elementos na sequência que vêm antes do
elemento com foco automático são simplesmente ignorados. Por esses motivos, não é aconselhável incluir o atributo autofocus
.
A exceção à recomendação "não usar autofocus
" é incluir o atributo autofocus
nos elementos <dialog>
.
Quando uma caixa de diálogo é aberta, o navegador foca automaticamente no primeiro elemento interativo focalizável dentro da <dialog>
,
o que significa que autofocus
não é necessário para um elemento. Para garantir que um elemento interativo específico da caixa de diálogo receba
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 <button>
de fechamento garante que ele receba foco quando a caixa de diálogo é aberta. Como o primeiro elemento
na caixa de diálogo, ele teria recebido foco em qualquer caso. Por padrão, quando uma caixa de diálogo é aberta, o primeiro elemento focalizável da
caixa de diálogo recebe o foco, a menos que outro elemento tenha o atributo autofocus
definido.
Como inerte elementos interativos
Há também atributos HTML que podem remover elementos interativos da sequência de tabulação. Incluir um tabindex
negativo
a elementos focalizáveis, adicionar o atributo disabled
aos controles de formulário compatíveis e adicionar o atributo inert
global
a um contêiner torna os elementos não tabuláveis. Esses três atributos NÃO são intercambiáveis.
Valor tabindex
negativo
Como aprendemos acima, um atributo tabindex
com um valor negativo torna um elemento focalizável, mas não com tabulação. Embora não seja necessário adicionar
tabindex="0"
a um elemento focalizável por padrão, incluindo links, botões, controles de formulários e elementos que são contenteditable
,
não é necessário incluir um tabindex
com um valor negativo, que remove os elementos normalmente tabuláveis da ordem de navegação do foco
sequencial.
Um valor negativo de tabindex
impede que os usuários do teclado se concentrem em elementos interativos, mas não desativa o elemento. Os usuários
do ponteiro ainda podem focar no elemento. Para desativar um elemento, use o atributo disabled
.
Desativado
O atributo booleano desativado torna os controles do formulário em que ele é aplicado e os descendentes, se houver, fora de foco. Os controles de formulário desativados não podem ser focados, não recebem eventos de clique
e não são enviados após o envio do formulário. Observe que 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 em <optgroup>
ou <fieldset>
, todos os controles de formulários filhos são desativados, exceto o conteúdo do primeiro <legend>
da <fieldset>
.
Os mesmos elementos com 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 em cinza claro pela folha de estilo do user agent, mesmo que um accent-color
esteja definido.
Por ser um atributo booleano, a presença do atributo desativa o elemento ativado. Ele não pode ser definido como false
.
Para reativar um elemento desativado, o atributo precisa ser removido, geralmente usando 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 cada interface de
elemento de suporte, como HTMLSelectElement
e
HTMLTextareaElement
, tem a mesma propriedade somente leitura.
O atributo disabled
não se aplica a elementos normalmente inert
que são focalizáveis usando tabindex
ou contenteditable
.
Ele também não se aplica ao próprio elemento <form>
. Para desativá-los, use o atributo global inert
.
O atributo inert
Quando o atributo booleano global inert
é adicionado a um elemento, esse elemento e todo o conteúdo aninhado são desativados, não
clicáveis nem com tabulação, e 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
aos controles de formulários, o navegador oferece o estilo padrão e pode ser estilizado usando a pseudoclasse
:disabled
. O atributo inert
não fornece indicadores visuais e não tem pseudoclasse correspondente, embora o seletor de atributo [inert]
seja correspondente.
O uso de inert
em conteúdo visível sem estilos indicando a inércia pode levar a uma experiência do usuário ruim. Como o conteúdo inerte
não está disponível para usuários de leitores de tela, pode causar confusão quando eles veem um conteúdo na tela
indisponível para as ferramentas de acessibilidade. Torne a inércia muito aparente por meio de CSS.
O foco nunca pode se mover para conteúdo não visível. Qualquer item renderizado fora da tela que não apareça automaticamente quando o foco estiver em foco precisa ser inerte. Se o conteúdo estiver oculto, mas aparecer na visualização em foco, como o link skip to content nesta página, ele não precisa ser inerte.
Teste seu conhecimento
Teste seu conhecimento
Teste seus conhecimentos sobre foco.
Se um elemento não puder ser focado, ele é descrito como?
O que acontecerá se o elemento tiver um atributo disabled
?