Foco de estilo

O indicador de foco (geralmente representado por um "anel de foco") identifica o elemento em foco em sua página. Para usuários que não conseguem usar um mouse, este é extremamente importante porque atua como um substituto ponteiro do mouse.

Se o indicador de foco padrão do navegador estiver em conflito com seu design, você pode usar CSS para mudar o estilo. Lembre-se apenas dos usuários de teclado.

Use :focus para sempre mostrar um indicador de foco

O :focus Uma pseudoclasse é aplicada sempre que um elemento está em foco, independentemente da entrada dispositivo (mouse, teclado, stylus etc.) ou método usado para focalizar. Por exemplo: o <div> abaixo tem um tabindex que o torna focalizável. Ele também tem estilo personalizado para o estado :focus:

div[tabindex="0"]:focus {
  outline: 4px dashed orange;
}

Não importa se você usa um mouse para clicar nele ou um teclado para usar a tecla Tab, o <div> sempre terá a mesma aparência.

Infelizmente, os navegadores podem ser inconsistentes com a forma como aplicam foco. Se ou se um elemento recebe foco pode depender do navegador e do sistema sistema.

Por exemplo, a <button> abaixo também tem um estilo personalizado para o :focus. estado.

button:focus {
  outline: 4px dashed orange;
}

Se você clicar no <button> com um mouse no Chrome no macOS, vai encontrar o estilo de foco personalizado. No entanto, você não verá o estilo de foco personalizado Clique no <button> no Safari no macOS. Isso ocorre porque, Safari, o elemento não recebe foco quando você clica nele.

Como o comportamento do foco é inconsistente, isso pode exigir alguns testes em dispositivos diferentes para garantir que os estilos de foco sejam aceitáveis para os usuários.

Usar :focus-visible para mostrar um indicador de foco seletivamente

A nova :focus-visible é aplicada sempre que um elemento recebe foco e a navegador determina, por meio da heurística, que exibir um indicador de foco seria benéfico para o usuário. Em particular, se a interação mais recente do usuário foi pelo teclado e o pressionamento de tecla não incluiu uma meta, ALT / OPTION, ou CONTROL, então :focus-visible corresponderá.

O botão no exemplo abaixo vai mostrar seletivamente um indicador de foco. Se você usa um mouse para clicar nele, os resultados serão diferentes do que se você usasse primeiro um teclado para usar a tecla Tab.

button:focus-visible {
  outline: 4px dashed orange;
}

Usar :focus-within para definir o estilo do pai de um elemento em foco

A :focus-within pseudoclasse é aplicada a um elemento quando o próprio elemento recebe ou quando outro elemento dentro dele recebe foco.

Ele pode ser usado para destacar uma região da página para desenhar a a atenção do usuário nessa área. Por exemplo, o formulário abaixo recebe foco tanto quando o próprio formulário é selecionado e também quando qualquer um de seus botões de opção está selecionados.

form:focus-within {
  background: #ffecb3;
}

Quando mostrar um indicador de foco

Uma boa regra é se perguntar: "Se você clicou nesse controle enquanto usando um dispositivo móvel, você esperaria que ele mostrasse um teclado?"

Se a resposta for "sim", o controle provavelmente sempre deve mostrar um foco independentemente do dispositivo de entrada usado para focalizá-lo. Um bom exemplo é o elemento <input type="text">. O usuário precisará enviar entradas para o pelo teclado, independentemente de como o elemento de entrada recebeu originalmente foco, por isso é útil sempre mostrar um indicador de foco.

Se a resposta for "não", o controle poderá mostrar seletivamente um foco indicador. Um bom exemplo é o elemento <button>. Se um usuário clicar nele com em um mouse ou tela sensível ao toque, a ação foi concluída e um indicador de foco pode não necessário. No entanto, caso o usuário esteja navegando com um teclado, é útil para mostrar um indicador de foco para que o usuário possa decidir se quer ou não clique no controle usando as teclas ENTER ou SPACE.

Evite outline: none

A maneira como os navegadores decidem quando desenhar um indicador de foco é, francamente, muito confusa. Mudar a aparência de um elemento <button> com CSS ou fornecer um elemento tabindex fará com que o comportamento padrão do anel de foco do navegador seja em ação.

Um antipadrão muito comum é remover o indicador de foco usando CSS, como:

/* Don't do this!!! */
:focus {
  outline: none;
}

Uma maneira melhor de contornar esse problema é usar uma combinação de :focus e o polyfill :focus-visible. O primeiro bloco de código abaixo demonstra como o polyfill funciona, e o app de exemplo abaixo dele mostra um exemplo de uso o polyfill para mudar o indicador de foco em um botão.

/*
  This will hide the focus indicator if the element receives focus via the
  mouse, but it will still show up on keyboard focus.
*/
.js-focus-visible :focus:not(.focus-visible) {
  outline: none;
}

/*
  Optionally: Define a strong focus indicator for keyboard focus.
  If you choose to skip this step, then the browser's default focus
  indicator will be displayed instead.
*/
.js-focus-visible .focus-visible {
  
}