Tema representativo de entrevista

Entrevista Frontend: ¿Cómo usarías inert para un modal accesible?

FrontendIntermedio
Equipo editorial de Offer.ccPublicado Actualizado

Pregunta

Un editor modal se abre sobre un dashboard. ¿Cómo evitas que los usuarios de teclado, puntero y tecnologías de asistencia interactúen con la página que está detrás sin romper la restauración del foco?

Planteamiento y contexto

El modal debe comportarse como la superficie activa mientras el fondo permanece visible pero no disponible. La implementación debe preservar el elemento activador (opener), admitir los controles de escape y de cierre, y evitar depender de un laberinto de tabindex positivos.

Qué evalúa el entrevistador

  • Comprensión de lo que el atributo inert bloquea y lo que no configura.
  • Combinación de la semántica nativa de diálogos, la gestión del foco y el etiquetado accesible.
  • Manejo de portales anidados, tiempos de animación, soporte de navegadores y movimiento reducido.

Preguntas para aclarar antes de responder

  • ¿Es este un diálogo modal o un popover no modal que permite la interacción con el fondo?
  • ¿Qué elemento es el propietario del diálogo y dónde está montado el portal?
  • ¿Qué debería ocurrir con el foco al abrir, cancelar, enviar y cerrar?
  • ¿Existe una línea base de navegadores disponible o se requiere una alternativa de respaldo (fallback) para clientes más antiguos?

Estructura de respuesta de 30 segundos

Usaría un diálogo modal nativo donde sea posible, movería el foco a su encabezado etiquetado o al primer control significativo, y marcaría únicamente el shell exterior de la aplicación como inert mientras el diálogo esté abierto. Restauraría el foco al activador si aún existe, proporcionaría Escape y un botón de cierre explícito, y probaría las rutas de teclado y lectores de pantalla. inert evita la interacción con el fondo; no reemplaza el nombrado del diálogo, la restauración del foco ni la gestión del estado.

Análisis detallado paso a paso

1. Elegir la superficie semántica correcta

Usa el elemento dialog nativo con showModal() para un modal verdadero cuando la línea base del navegador lo permita, y proporciona un nombre accesible mediante un encabezado visible o aria-labelledby. Una revelación (disclosure) no modal no debe hacer que toda la página sea inerte porque se espera que los usuarios se desplacen entre superficies.

2. Aislar el fondo

Aplica inert al contenedor de la aplicación que está fuera del diálogo, no a un ancestro común que también contenga el portal del diálogo. El navegador elimina el subárbol inerte de la navegación por foco y evita los eventos de foco; también previene la interacción normal del usuario. No disperses aria-hidden en ancestros que contengan el diálogo enfocado.

3. Gestionar el ciclo de vida del foco

Captura el activador antes de abrir. Al abrir, enfoca un encabezado estable o el primer control de la tarea en lugar de un icono de cierre arbitrario. Al cancelar o enviar con éxito, cierra el diálogo, elimina inert y restaura el foco si el activador sigue visible y habilitado. Si el activador fue eliminado, elige un objetivo lógico cercano y anuncia el resultado.

4. Manejar portales y transiciones

Renderiza el diálogo en una capa de nivel superior para que el recorte (clipping) y los contextos de apilamiento no lo atrapen. Establece inert antes de exponer el estado del modal a la interacción y retrasa el foco hasta que el diálogo esté montado. Coordina la animación de entrada y salida con las preferencias de movimiento reducido; nunca dejes el fondo inerte después de una transición interrumpida.

5. Probar las rutas de fallo

Prueba Tab y Shift+Tab, Escape, la activación del botón de cierre, los errores de validación, los diálogos anidados, los cambios de ruta y los anuncios del lector de pantalla. Verifica que los clics, el foco programático, el comportamiento de búsqueda en la página y los eventos de puntero coincidan con el comportamiento inerte del navegador. Añade un fallback solo cuando el conjunto de navegadores compatibles lo requiera, y elimínalo cuando el comportamiento nativo sea confiable.

Ejemplo de respuesta de alta calidad

“Para un modal verdadero usaría un diálogo nativo, enfocaría su encabezado etiquetado o el primer control de la tarea, y establecería inert en el shell exterior de la aplicación en lugar de en un ancestro del portal que contenga el diálogo. Capturaría el activador, restauraría el foco después de cerrar, admitiría Escape y un botón de cierre explícito, y mantendría la semántica de nombrado y validación separada del estado inerte. Probaría las rutas de teclado, lector de pantalla, portal, animación y cambio de ruta, incluyendo la limpieza del estado inerte después de una transición interrumpida”.

Errores comunes

  • Establecer inert en la raíz de la app que contiene el portal → el diálogo también se vuelve inerte → monta el diálogo fuera del subárbol inerte.
  • Usar inert como sistema de gestión de foco → el foco aún puede caer en el lugar equivocado al abrir o cerrar → define un ciclo de vida de foco completo.
  • Ocultar el fondo con aria-hidden mientras contiene el foco → la tecnología de asistencia ve un estado inconsistente → mueve el foco primero y usa inert en el fondo.
  • Olvidar las transiciones interrumpidas → la página permanece bloqueada → limpia el estado inerte en cada ruta de cierre y desmontaje.

Preguntas de seguimiento y respuestas

¿Reemplaza inert a una trampa de foco (focus trap)?

Evita que el fondo sea enfocable, por lo que un modal a menudo puede prescindir de una trampa implementada manualmente. Aún necesitas colocar el foco inicial, restaurarlo, nombrar el diálogo y manejar fallbacks de navegadores o componentes.

¿Puede un panel lateral (drawer) no modal usar inert?

Solo cuando el producto hace intencionalmente que el fondo no esté disponible. Para un drawer no modal que permite la interacción con el fondo, no marques la página como inerte; usa la semántica de revelación apropiada en su lugar.

¿Qué ocurre si el elemento activador desaparece?

Restaura el foco al control lógico más cercano, como la fila actualizada o el encabezado de la página, y anuncia el resultado cuando sea necesario. Nunca intentes enfocar un elemento desvinculado o deshabilitado.

Fuentes públicas

Preguntas relacionadas