O indicador de foco, geralmente representado por um "anel de foco", identifica o elemento em foco na sua página. Para usuários que não podem ou não querem usar um mouse, esse indicador é extremamente importante, porque ele atua como um substituto para um ponteiro do mouse.
Se o indicador de foco padrão do navegador entrar em conflito com seu design, use CSS para mudar o estilo dele. Não se esqueça dos usuários.
Usar :focus para sempre mostrar um indicador de foco
A pseudoclasse :focus
é aplicada a elementos em foco, independente do método de entrada
ou dispositivo (como mouse, teclado ou stylus) em uso.
Por exemplo, o <div> a seguir tem um tabindex que o torna focalizável,
com um estilo personalizado para o estado :focus:
div[tabindex="0"]:focus {
outline: 4px dashed orange;
}
Não importa qual dispositivo você use, o <div> tem a mesma aparência em foco.
Infelizmente, os navegadores podem ser inconsistentes na forma como aplicam o foco. Se um elemento recebe foco ou não pode depender do navegador e do sistema operacional.
Por exemplo, o <button> a seguir tem CSS personalizado para o estado :focus.
button:focus {
outline: 4px dashed orange;
}
Se você clicar no <button> com um mouse no Chrome no macOS, vai aparecer
o estilo de foco personalizado. No entanto, o estilo de foco personalizado não vai aparecer se você
clicar no <button> no Safari no macOS. Isso ocorre porque, no Safari, o elemento não recebe foco quando você clica nele.
O comportamento de foco é inconsistente. Teste sua página em diferentes dispositivos e com entradas diferentes para garantir que os estilos de foco sejam aceitáveis para seus usuários.
Use :focus-visible para mostrar seletivamente um indicador de foco
A pseudoclasse :focus-visible
é aplicada quando um elemento recebe foco e o navegador
determina (com heurísticas) que mostrar um indicador de foco seria
benéfico para o usuário. Em particular, se a interação mais recente do usuário foi com um teclado e o pressionamento de tecla não incluiu uma tecla meta, ALT, OPTION ou CONTROL, :focus-visible vai corresponder.
O botão no exemplo a seguir mostra seletivamente um indicador de foco. Se você usar um mouse para clicar, os resultados serão diferentes de se você usar um teclado para navegar até ele.
button:focus-visible {
outline: 4px dashed orange;
}
Use :focus-within para estilizar o elemento pai de um elemento em foco
A pseudoclasse
:focus-within
é aplicada a um elemento quando ele ou um elemento filho recebe
foco. Ele pode ser usado para destacar uma região da página e chamar a atenção do usuário para essa área.
Por exemplo, um formulário recebe foco quando ele mesmo é selecionado e quando qualquer um dos botões de opção é selecionado.
form:focus-within {
background: #ffecb3;
}
Quando mostrar um indicador de foco
Uma boa pergunta é: "Se você clicar nesse controle ao usar um dispositivo móvel, espera que um teclado seja exibido?"
- Se sim: o controle deve sempre mostrar um indicador de foco, independente do dispositivo de entrada. Por exemplo, isso é quase sempre verdade para o elemento
<input type="text">. O usuário precisa enviar entrada para o elemento com o teclado, independente de como o elemento de entrada fica em foco. - Se não: o controle pode mostrar um indicador de foco de forma seletiva. Por exemplo, quando um usuário clica em um
<button>com um mouse ou em uma tela sensível ao toque, a ação é concluída. Um indicador de foco pode ser desnecessário. No entanto, se o usuário estiver navegando com um teclado, é útil mostrar um indicador de foco para que ele possa decidir se quer ou não ativar o controle com ENTER ou ESPAÇO.
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 dar a um elemento um tabindex faz com que o comportamento padrão do anel de foco do navegador seja ativado.
Às vezes, os desenvolvedores removem o indicador de foco usando CSS:
/* Don't do this!!! */
:focus {
outline: none;
}
Uma maneira melhor de contornar esse problema é combinar :focus e o polyfill :focus-visible. O primeiro bloco de código demonstra como o polyfill funciona, e o app de exemplo abaixo dele mostra como usar o polyfill para mudar o indicador de foco em um botão.
/*
This hides the focus indicator if the element receives focus with a
mouse, but it still shows 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 {
...
}