Foco

Podcast do CSS - 018: Focus

Na sua página da Web, você clica em um link que direciona o usuário para o conteúdo principal do site. Eles costumam ser chamados de links de salto ou links fixos. Quando esse link é ativado por um teclado usando as teclas tab e Enter, o contêiner de conteúdo principal tem um anel de foco ao redor. Por que isso acontece?

Isso ocorre porque a <main> tem um valor de atributo tabindex="-1", o que significa que ele pode ser focado programaticamente. Quando o <main> é segmentado, como o #main-content na barra de URL do navegador corresponde ao id, ele recebe foco programático. É tentador remover os estilos de foco nessas situações, mas processar o foco de maneira adequada e com cuidado ajuda a criar uma boa experiência do usuário acessível. Também pode ser um ótimo lugar para adicionar algum interesse às interações.

Por que o foco é importante?

Como desenvolvedor da Web, é seu trabalho tornar um site acessível e inclusivo para todos. Criar estados de foco acessíveis com CSS faz parte dessa responsabilidade.

Os estilos de foco ajudam as pessoas que usam um dispositivo, como um teclado ou um controle de interruptor, a navegar e interagir com um site. Se um elemento receber foco e não houver indicação visual, o usuário poderá perder de vista o que está em foco. Isso pode criar problemas de navegação e resultar em comportamento indesejado se, por exemplo, um link errado for seguido.

Como os elementos recebem foco

Alguns elementos são focalizáveis automaticamente. Esses elementos aceitam interação e entrada, como <a>, <button>, <input> e <select>. Resumindo, todos os elementos, botões e links de formulário. Em geral, é possível navegar pelos elementos focalizáveis de um site usando a tecla Tab para avançar na página e Shift + Tab para voltar.

Há também um atributo HTML chamado tabindex, que permite mudar o índice de tabulação, que é a ordem em que os elementos estão focados, toda vez que alguém pressiona a tecla Tab ou o foco é deslocado com uma alteração de hash no URL ou por um evento JavaScript. Se tabindex em um elemento HTML estiver definido como 0, ele poderá receber foco pela chave tab e respeitará o índice de guias globais, que é definido pela ordem da origem do documento.

Se você definir tabindex como -1, ele só poderá receber foco de maneira programática, o que significa que só ocorre quando um evento JavaScript acontece ou uma mudança de hash (correspondente ao id do elemento no URL). Se você definir tabindex como maior que 0, ele será removido do índice de guias globais, definido pela ordem de origem do documento. A ordem de tabulação agora será definida pelo valor de tabindex. Por exemplo, um elemento com tabindex="1" vai receber foco antes de um elemento com tabindex="2".

Foco de estilo

O comportamento padrão do navegador quando um elemento recebe foco é apresentar um anel de foco. Esse anel de foco varia entre o navegador e os sistemas operacionais.

Esse comportamento pode ser mudado com CSS usando as pseudoclasses :focus, :focus-within e :focus-visible que você aprendeu na lição de pseudoclasses. É importante definir um estilo de foco que contraste o estilo padrão de um elemento. Por exemplo, uma abordagem comum é usar a propriedade outline.

a:focus {
  outline: 2px solid slateblue;
}

A propriedade outline pode aparecer muito próxima ao texto de um link, mas a propriedade outline-offset pode ajudar com isso, já que adiciona padding visual extra sem afetar o tamanho geométrico que o elemento preenche. Um valor numérico positivo de outline-offset vai deslocar o contorno para fora, um valor negativo vai puxá-lo para dentro.

Atualmente, em alguns navegadores, se você tiver um border-radius definido no elemento e usar outline, ele não será correspondente: o contorno terá cantos nítidos. Por isso, é tentador usar um box-shadow com um pequeno raio de desfoque, porque box-shadow é recortado na forma, honrando border-radius, mas esse estilo não será exibido no modo de alto contraste do Windows. Isso ocorre porque o modo de alto contraste do Windows não aplica sombras e ignora principalmente imagens de plano de fundo para favorecer as configurações preferidas do usuário.

Em resumo

Criar um estado de foco que contraste com o estado padrão de um elemento é extremamente importante. Os estilos de navegador padrão já fazem isso, mas se você quiser mudar esse comportamento, lembre-se do seguinte:

  • Evite usar outline: none em um elemento que possa receber o foco do teclado.
  • Evite substituir estilos outline por box-shadow. já que eles não aparecem no modo de alto contraste do Windows.
  • Só defina um valor positivo para tabindex em um elemento HTML se for absolutamente necessário.
  • O estado de foco precisa ser muito claro em comparação com o estado padrão.

Teste seu conhecimento

Teste seus conhecimentos sobre foco

Quais das opções abaixo são elementos focalizáveis automaticamente?

<a>
🎉
<p>
Tente de novo.
<button>
🎉
<input>
🎉
<output>
Tente de novo.
<select>
🎉

Qual dos dispositivos de entrada a seguir pode definir o foco?

Gamepad
Geralmente, os gamepads enviam eventos de teclado quando os botões são pressionados.
Teclado
Definitivamente causa foco quando usado para navegar na Web.
Rato
Um mouse exige visão e não coloca mais o foco nos elementos quando usado. Todos os navegadores colocavam o foco em coisas como botões quando clicados, mas isso mudou.
Tecnologia assistiva (leitor de tela, interruptor etc.)
Definitivamente causa foco quando usado para navegar na Web.
Uma batata
Embora uma batata possa ser usada como um ponteiro em touchscreens, ela não causa foco após a interação com as entradas na tela.