Enfoque de estilo

El indicador de enfoque (a menudo, significa "anillo de enfoque") identifica el elemento enfocado actualmente en tu página. Para los usuarios que no pueden usar un mouse, este indicador es muy importante porque actúa como sustituto del puntero del mouse.

Si el indicador de enfoque predeterminado del navegador entra en conflicto con tu diseño, puedes usar CSS para cambiar su diseño. Solo recuerda tener en cuenta a los usuarios del teclado.

La pseudoclase :focus se aplica cada vez que se enfoca un elemento, independientemente del dispositivo de entrada (mouse, teclado, pluma stylus, etc.) o del método que se use para enfocarlo. Por ejemplo, el <div> que aparece a continuación tiene un tabindex que lo hace enfocable. También tiene un estilo personalizado para su estado :focus:

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

Independientemente de si usas un mouse para hacer clic en él o un teclado para desplazarte hasta él, el <div> siempre se verá igual.

Desafortunadamente, los navegadores pueden ser inconsistentes con la forma en que aplican el foco. Es posible que el hecho de que un elemento reciba enfoque dependa del navegador y del sistema operativo.

Por ejemplo, el <button> que aparece a continuación también tiene un estilo personalizado para su estado :focus.

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

Si haces clic en <button> con el mouse en Chrome para macOS, deberías ver su estilo de enfoque personalizado. Sin embargo, no verás el estilo de enfoque personalizado si haces clic en <button> en Safari en macOS. Esto se debe a que, en Safari, el elemento no recibe el foco cuando haces clic en él.

Debido a que el comportamiento del enfoque es incoherente, es posible que debas realizar algunas pruebas en diferentes dispositivos para asegurarte de que tus usuarios acepten tus estilos de enfoque.

Usa :focus-visible para mostrar de forma selectiva un indicador de enfoque

La nueva pseudoclase :focus-visible se aplica cada vez que un elemento recibe el foco y el navegador determina a través de heurísticas que mostrar un indicador de foco sería beneficioso para el usuario. En particular, si la interacción más reciente del usuario fue a través del teclado y al presionar la tecla no se incluyó una tecla meta, ALT / OPTION o CONTROL, entonces :focus-visible coincidirá.

El botón del siguiente ejemplo mostrará de forma selectiva un indicador de enfoque. Si usas un mouse para hacer clic en él, los resultados son diferentes a los que se obtienen si primero usas un teclado para desplazarte hasta él.

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

Usa :focus-within para aplicar diseño al elemento superior de un elemento enfocado

La pseudoclase :focus-within se aplica a un elemento cuando el elemento en sí recibe el foco o cuando otro elemento dentro de ese elemento recibe el foco.

Se puede usar para destacar una región de la página y llamar la atención del usuario sobre esa área. Por ejemplo, el siguiente formulario recibe el foco cuando se selecciona el formulario en sí y también cuando se selecciona cualquiera de sus botones de selección.

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

Cuándo mostrar un indicador de enfoque

Una buena regla general es preguntarte lo siguiente: "Si hicieras clic en este control mientras usara un dispositivo móvil, ¿esperarías que se muestre un teclado?".

Si la respuesta es "sí", es probable que el control deba siempre mostrar un indicador de enfoque, independientemente del dispositivo de entrada que se use para enfocarlo. Un buen ejemplo es el elemento <input type="text">. El usuario deberá enviar entradas al elemento a través del teclado, independientemente de cómo el elemento de entrada haya recibido el enfoque originalmente, por lo que es útil mostrar siempre un indicador de enfoque.

Si la respuesta es "no", el control puede elegir mostrar de forma selectiva un indicador de enfoque. Un buen ejemplo es el elemento <button>. Si un usuario hace clic en él con un mouse o una pantalla táctil, se completa la acción y es posible que no sea necesario un indicador de enfoque. Sin embargo, si el usuario navega con un teclado, es útil mostrar un indicador de enfoque para que el usuario pueda decidir si quiere hacer clic en el control con las teclas ENTER o SPACE.

Evita outline: none

La forma en que los navegadores deciden cuándo dibujar un indicador de enfoque es, francamente, muy desordenada. Si cambias el aspecto de un elemento <button> con CSS o le asignas un tabindex, se activará el comportamiento predeterminado del anillo de enfoque del navegador.

Un antipatrón muy común es quitar el indicador de enfoque con CSS, como el siguiente:

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

Una mejor manera de solucionar este problema es usar una combinación de :focus y el polyfill :focus-visible. El primer bloque de código que aparece a continuación demuestra cómo funciona el polyfill, y la app de ejemplo que aparece debajo proporciona un ejemplo de cómo usar el polyfill para cambiar el indicador de enfoque de un botón.

/*
  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 {
  
}