Concentración

Los elementos interactivos, incluidos los controles de formulario, los vínculos y los botones, son enfocables y con tabulaciones de forma predeterminada. Los elementos por los que se puede hacer Tab son parte del orden de navegación del enfoque secuencial del documento. Otros elementos son inertes, es decir, no son interactivos. Con los atributos HTML, es posible hacer que los elementos interactivos estén inertes y que los elementos inertes sean interactivos.

De forma predeterminada, el orden del foco de navegación es el mismo que el orden visual, que es el orden del código fuente. Hay atributos HTML que pueden alterar este orden y propiedades de CSS que pueden alterar el orden visual del contenido. Cambiar el orden de tabulación con HTML o el orden de renderización visual con CSS puede perjudicar la experiencia del usuario.

No alteres el orden de tabulación percibido y real con CSS y HTML. Como se muestra en los siguientes dos ejemplos, los pedidos de pestañas que difieren del orden visualmente esperado son confusos para los usuarios y deficientes para su experiencia.

En este ejemplo, el valor del atributo tabindex hizo que el orden de tabulación sea caótico:

En este ejemplo, CSS creó una divergencia entre el orden de tabulación y el orden visual del contenido:

La declaración flex-flow: row-reverse; invirtió el orden visual. Además, se aplicó la propiedad order de CSS a la sexta palabra, "This", que movió visualmente esa palabra. La secuencia de tabulación es el orden del código, que ya no coincide con el orden visual, lo que crea una desconexión para los usuarios de teclado.

Cómo hacer que los elementos inertes sean interactivos

Los atributos contenteditable y tabindex, que son atributos globales, se pueden agregar a cualquier elemento, lo que los hace enfocables en el proceso. Los elementos enfocables también se pueden enfocar con un mouse o un puntero, si se establece el atributo autofocus, o por secuencia de comandos, como con element.focus().

El atributo tabindex

El atributo global tabindex, ingresado en los atributos, permite que elementos que, de lo contrario, no podrían recibir enfoque, lo hagan, generalmente con la tecla Tab (de ahí su nombre).

El atributo tabindex toma como valor un número entero. Un valor negativo hace que un elemento sea enfocable, pero no tabulable. Un valor tabindex de 0 hace que el elemento se pueda enfocar y usar con tabulaciones, lo que agrega el elemento en el que se aplica al orden de navegación del enfoque secuencial en el orden del código fuente. Un valor de 1 o superior permite que el elemento se pueda enfocar y usar con tabulación, pero lo agrega a una secuencia de tabulación priorizada y, como vimos anteriormente, debe evitarse.

En esta página, el botón para compartir, <share-action>, es un elemento personalizado. tabindex="0" agrega este elemento que normalmente no se puede enfocar en el orden de tabulación predeterminado del teclado:

<share-action authors="@front-end.social/@estellevw" data-action="click" data-category="web.dev" data-icon="share" data-label="share, mastodon" role="button" tabindex="0">
  <svg aria-label="share" role="img" xmlns="http://www.w3.org/2000/svg">
    <use href="#shareIcon" />
  </svg>
  <span>Share</span>
</share-action>

Hay otro elemento personalizado en esta página: la navegación local tiene un elemento personalizado con un valor tabindex negativo:

<web-navigation-drawer type="standard" tabindex="-1">

Un atributo tabindex con un valor negativo hace que el elemento sea enfocable, pero no tabulable. El elemento puede recibir el enfoque, por ejemplo, a través de HTMLElement.focus(), pero no forma parte del orden de navegación del enfoque secuencial. La convención de los elementos enfocables y que no admiten pestañas es usar tabindex="-1". Ten en cuenta que, si agregas tabindex="-1" a un elemento interactivo, ya no se podrá usar tabulaciones.

Se puede usar el método element.focus() para establecer el enfoque en elementos enfocables. Ten en cuenta que los navegadores desplazan los elementos enfocados para que se vean. Por este motivo, evita el uso de element.focus({preventScroll:true}), ya que centrarte en un elemento no visible dará una mala experiencia del usuario.

Si quieres consultar el documento para saber qué elemento está enfocado actualmente, usa la propiedad de solo lectura Document.activeElement.

Los elementos con un tabindex de 1 o más se incluyen en una secuencia de tabulaciones independiente. Como observarás en CodePen, la tabulación comienza en una secuencia separada, en orden del valor más bajo al más alto, antes de pasar por los de la secuencia regular (sin tabindex establecido o tabindex="0") en el orden de origen:

tabindex con un valor positivo coloca el elemento en una secuencia de enfoque priorizada, lo que puede generar un caos de orden de enfoque. Evita modificar el orden del DOM con tabindex. Los pedidos de tabulación alterados no solo pueden crear malas experiencias del usuario, sino que también son difíciles de administrar y mantener para los desarrolladores.

El atributo contenteditable

El atributo contenteditable se explicó anteriormente. Si configuras contenteditable="true" en cualquier elemento, será editable y enfocable, y será parte del orden de tabulación. El comportamiento del enfoque es similar a la configuración de tabindex="0", pero no es igual. Los elementos contenteditable anidados son enfocables, pero no tabulables. Para hacer que un elemento contenteditable anidado sea tabulable, agrega tabindex="0", que lo agregará al orden de navegación del foco secuencial.

Enfocarse en elementos interactivos

El atributo autofocus

Si bien el valor booleano autofocus es un atributo global que se puede configurar en cualquier elemento, no hace que un elemento inerte sea interactivo. Cuando se cargue la página, se enfocará el primer elemento enfocable con el atributo autofocus configurado, siempre que ese elemento se muestre y no esté anidado en un <dialog>.

Establecer automáticamente el enfoque en el contenido puede ser confuso. Si configuras autofocus en un control de formulario, el control se desplazará a la vista cuando se cargue la página. Es posible que todos los usuarios, incluidos los de lector de pantalla y con viewports pequeños, no "vean" las instrucciones del formulario y, quizás, incluso se desplazan más allá de la etiqueta normalmente visible del control de formulario. El atributo autofocus no altera el orden de navegación del enfoque secuencial del documento. Los elementos en la secuencia que vienen antes del elemento de enfoque automático simplemente se omiten. Por estos motivos, no se recomienda incluir el atributo autofocus.

La excepción a la recomendación "no usar autofocus" es incluir el atributo autofocus dentro de los elementos <dialog>. Cuando se abre un diálogo, el navegador se enfoca automáticamente en el primer elemento interactivo enfocable dentro de <dialog>, lo que significa que no es necesario usar autofocus para un elemento. Si quieres asegurarte de que un elemento interactivo específico del diálogo reciba el foco cuando este se abra, agrega el atributo autofocus a ese elemento.

<dialog open>
  <form method="dialog">
    <button type="submit" autofocus>close</button>
  </form>
</dialog>

El atributo autofocus configurado en el <button> de cierre garantiza que reciba el foco cuando se abra el diálogo. Como primer elemento en el diálogo, habría recibido el enfoque en cualquier caso. De forma predeterminada, cuando se abre un diálogo, el primer elemento enfocable dentro de él recibirá el enfoque, a menos que un elemento diferente dentro del diálogo tenga configurado el atributo autofocus.

Cómo inertar los elementos interactivos

También hay atributos HTML que pueden quitar elementos interactivos de la secuencia de tabulación. Incluir un tabindex negativo en los elementos enfocables y agregar el atributo disabled a los controles de formularios compatibles y el atributo inert global a un contenedor hace que no se puedan usar tabulaciones en los elementos. Estos tres atributos NO son intercambiables.

Valor tabindex negativo

Como aprendimos más arriba, un atributo tabindex con un valor negativo hace que un elemento sea enfocable, pero no tabulable. Si bien no es necesario agregar tabindex="0" a un elemento enfocable de forma predeterminada, incluidos vínculos, botones, controles de formularios y elementos contenteditable, incluir un tabindex con un valor negativo quita los elementos que suelen ser tabulables del orden de navegación del enfoque secuencial.

Un valor de tabindex negativo impide que los usuarios del teclado se enfoquen en los elementos interactivos, pero no inhabilita el elemento. Los usuarios de punteros aún pueden enfocarse en el elemento. Para inhabilitar un elemento, usa el atributo disabled.

Inhabilitado

El atributo booleano inhabilitado hace que los controles del formulario en los que se aplique y sus elementos subordinados, si los hubiera, no se pueden enfocar. Los controles de formularios inhabilitados no se pueden enfocar, no reciben eventos de clic y no se envían cuando se envía el formulario. Ten en cuenta que disabled no es un atributo global. Se aplica a <button>, <input>, <optgroup>, <option>, <select>, <textarea>, elementos personalizados asociados con formularios y <fieldset>. Cuando se configuran en <optgroup> o <fieldset>, se inhabilitan todos los controles del formulario secundario, excepto el contenido de la primera <legend> de <fieldset>.

Los mismos elementos que admiten disabled también se pueden orientar con las seudoclases :disabled y :enabled. Por lo general, los elementos inhabilitados con el atributo disabled se diseñan de color gris claro mediante la hoja de estilo del usuario-agente, incluso si se establece un accent-color.

Al ser un atributo booleano, la presencia del atributo inhabilita el elemento que se encuentra habilitado; no puedes configurarlo como false. Para volver a habilitar un elemento inhabilitado, se debe quitar el atributo, generalmente mediante Element.removeAttribute('disabled').

La propiedad HTMLInputElement.disabled te permite verificar si una entrada está inhabilitada. Como disabled no es un atributo global, no se hereda del elemento HTMLElement, pero todas las interfaces de elementos complementarios, como HTMLSelectElement, HTMLTextareaElement, tienen la misma propiedad de solo lectura.

El atributo disabled no se aplica a los elementos inert que, por lo general, se hacen enfocables mediante tabindex o contenteditable. Tampoco se aplica al elemento <form>. Para inhabilitarlas, se puede usar el atributo global inert.

El atributo inert

Cuando se agrega el atributo booleano global inert a un elemento, ese elemento y todo el contenido anidado se inhabilitan (no se puede hacer clic ni usar tabulaciones) y se quitan del árbol de accesibilidad. Si bien inert se puede aplicar a cualquier elemento, en general, se usa para secciones de contenido, como contenido fuera de pantalla u otro contenido oculto.

Cuando se aplica disabled a los controles de formularios, el navegador proporciona un estilo predeterminado y se puede diseñar el estilo con la seudoclase :disabled. El atributo inert no proporciona indicadores visuales ni tiene una seudoclase que coincida (aunque el selector de atributos [inert] coincida).

El uso de inert en contenido visible sin estilos que indiquen la inercia puede perjudicar la experiencia del usuario. Como el contenido inerte no está disponible para los usuarios de lectores de pantalla, puede generar confusión cuando los usuarios de lectores de pantalla videntes ven contenido en la pantalla que no está disponible para las herramientas de accesibilidad. Hacer que la inercia sea muy evidente mediante CSS

Asegúrate de que el enfoque nunca se mueva a contenido no visible. Todo lo que se renderiza fuera de la pantalla y que no se ve automáticamente cuando se enfoca debe pasar a ser inerte. Si el contenido está oculto, pero aparece a la vista cuando se enfoca, como en el vínculo del contenido al contenido de esta página, no es necesario que esté inerte.

Verifica tus conocimientos

Verifica tus conocimientos

Pon a prueba tus conocimientos sobre enfoque.

Si un elemento no se puede enfocar, ¿cómo se describe?

Vacío.
Vuelve a intentarlo.
Inerte.
Correcto.
Se ocultó.
Vuelve a intentarlo.

¿Cuál de las siguientes afirmaciones será verdadera si el elemento tiene un atributo disabled?

No se podrá enfocar.
Correcto.
No se mostrará.
Vuelve a intentarlo.
Si es un elemento de formulario, no se enviará.
Correcto.