Enfoque

The CSS Podcast - 018: Focus

En tu página web, haces clic en un vínculo que lleva al usuario al contenido principal del sitio web. Por lo general, se denominan vínculos de omisión o vínculos de anclaje. Cuando un teclado activa ese vínculo con las teclas Tab y Intro, el contenedor de contenido principal tiene un anillo de enfoque a su alrededor. ¿A qué se debe?

Esto se debe a que <main> tiene un valor de atributo tabindex="-1", lo que significa que se puede enfocar de manera programática. Cuando se segmenta <main>, ya que el #main-content en la barra de URL del navegador coincide con id, recibe el enfoque programático. Es tentador quitar los estilos de enfoque en estas situaciones, pero controlar el enfoque de forma adecuada y con cuidado ayuda a crear una experiencia del usuario buena y accesible. También puede ser un excelente lugar para agregar algo de interés a las interacciones.

¿Por qué es importante el enfoque?

Como desarrollador web, tu trabajo es hacer que un sitio web sea inclusivo y accesible para todos. Crear estados de enfoque accesibles con CSS es parte de esta responsabilidad.

Los estilos de enfoque ayudan a las personas que usan un dispositivo, como un teclado o un control de interruptor, a navegar e interactuar con un sitio web. Si un elemento recibe el enfoque y no hay una indicación visual, el usuario puede perder el seguimiento de lo que está en foco. Esto puede generar problemas de navegación y provocar un comportamiento no deseado si, por ejemplo, se sigue el vínculo incorrecto.

Cómo se enfocan los elementos

Ciertos elementos se pueden enfocar automáticamente. Estos son elementos que aceptan interacción y entrada, como <a>, <button>, <input> y <select>. En resumen, todos los elementos, botones y vínculos del formulario. Por lo general, puedes navegar por los elementos enfocables de un sitio web con la tecla Tab para avanzar en la página y Mayúsculas + Tab para retroceder.

También hay un atributo HTML llamado tabindex que te permite cambiar el índice de tabulación, que es el orden en el que se enfocan los elementos, cada vez que alguien presiona la tecla Tab o se cambia el enfoque con un cambio de hash en la URL o un evento de JavaScript. Si tabindex en un elemento HTML se establece en 0, puede recibir el enfoque a través de la tecla Tab y respetará el índice de tabulación global, que se define según el orden de la fuente del documento.

Si configuras tabindex en -1, solo puede recibir enfoque de forma programática, lo que significa que solo cuando se produce un evento de JavaScript o un cambio de hash (que coincide con el id del elemento en la URL). Si estableces tabindex en un valor superior a 0, se quitará del índice de pestañas global, definido por el orden de la fuente del documento. El orden de tabulación ahora se definirá según el valor de tabindex, por lo que un elemento con tabindex="1" recibirá el enfoque antes que un elemento con tabindex="2", por ejemplo.

Aplicar estilo al enfoque

El comportamiento predeterminado del navegador cuando un elemento recibe el foco es presentar un anillo de enfoque. Este anillo de enfoque varía entre el navegador y los sistemas operativos.

Este comportamiento se puede cambiar con CSS, mediante las pseudoclases :focus, :focus-within y :focus-visible de las que aprendiste en la lección sobre pseudoclases. Es importante establecer un estilo de enfoque que tenga contraste con el estilo predeterminado de un elemento. Por ejemplo, un enfoque común es utilizar la propiedad outline.

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

La propiedad outline podría aparecer demasiado cerca del texto de un vínculo, pero la propiedad outline-offset puede ayudar con eso, ya que agrega padding visual adicional sin afectar el tamaño geométrico que completa el elemento. Un valor numérico positivo para outline-offset empujará el contorno hacia afuera, mientras que un valor negativo lo tirará hacia adentro.

Actualmente, en algunos navegadores, si tienes un border-radius configurado en tu elemento y usas outline, no coincidirá, ya que el contorno tendrá esquinas definidas. Por este motivo, es tentador usar un box-shadow con un radio de desenfoque pequeño porque box-shadow se recorta a la forma, lo que hace honor a border-radius, pero este estilo no se mostrará en el Modo de contraste alto de Windows. Esto se debe a que el modo de contraste alto de Windows no aplica sombras y, por lo general, ignora las imágenes de fondo para favorecer la configuración preferida del usuario.

En resumen

Crear un estado de enfoque que contraste con el estado predeterminado de un elemento es muy importante. Los estilos predeterminados del navegador ya lo hacen por ti, pero si quieres cambiar este comportamiento, recuerda lo siguiente:

  • Evita usar outline: none en un elemento que pueda recibir el enfoque del teclado.
  • Evita reemplazar los estilos outline por box-shadow. ya que no aparecen en el modo de contraste alto de Windows.
  • Solo establece un valor positivo para tabindex en un elemento HTML si es absolutamente necesario.
  • Asegúrate de que el estado de enfoque sea muy claro en comparación con el estado predeterminado.

Verifica tu comprensión

Pon a prueba tus conocimientos sobre el enfoque

¿Cuáles de los siguientes son elementos enfocables automáticamente?

<a>
🎉
<p>
Vuelve a intentarlo.
<button>
🎉
<input>
🎉
<output>
Vuelve a intentarlo.
<select>
🎉

¿Cuál de los siguientes dispositivos de entrada puede establecer el enfoque?

Controlador de juegos
Los mandos de juegos suelen enviar eventos de teclado cuando se presionan sus botones.
Teclado
Definitivamente, causa enfoque cuando se usa para navegar por la Web.
Ratón
Un mouse requiere visión y ya no enfoca los elementos cuando se usa. Todos los navegadores solían enfocarse en elementos como botones cuando se hacía clic en ellos, pero eso cambió.
Tecnología de accesibilidad (lector de pantalla, interruptor, etcétera)
Definitivamente, causa enfoque cuando se usa para navegar por la Web.
Una papa
Lo siento, aunque se puede usar una papa como puntero en pantallas táctiles, no hace foco después de interactuar con las entradas de la pantalla.