Modals & Overlays
Modals & Overlays
12 reglasTrap de foco dentro del dialog; devuelve foco al cerrar
Cuando un modal abre, Tab y Shift+Tab deben ciclar solo entre los elementos enfocables del dialog, envolviendo en ambos extremos. Al cerrar, el foco regresa programáticamente al elemento disparador. Requerido por WCAG 2.1.2.
WAI-ARIA APG, Dialog (Modal) Pattern · WCAG 2.1.2Eliminar cuenta
Esta accion es permanente y no puede deshacerse.
Tab cicla: Cancelar → Eliminar → Cancelar
Esc cierra y devuelve foco al boton disparador
Foco inicial segun tipo de contenido, no siempre el primer campo
En dialogs destructivos o inesperados, focaliza el heading o el boton menos destructivo. En dialogs informativos breves, focaliza el boton de cerrar. Solo focaliza el primer input cuando el usuario abrio intencionalmente un formulario corto y familiar.
Adrian Roselli, 'Where to Put Focus When Opening a Modal Dialog' (junio 2025)¿Publicar en produccion?
¿Publicar en produccion?
Boton de cierre visible con target minimo de 44x44 px
Todo dialog debe incluir al menos un boton visible que lo cierre, independiente del soporte de Escape. El area clickeable minima es 44x44 px segun WCAG 2.5.5 y Apple HIG; el icono puede ser de 16 px dentro de ese contenedor.
WAI-ARIA APG Dialog Pattern · WCAG 2.5.5 · Apple HIGConfirmacion enviada
Confirmacion enviada
Ancho maximo de 560 px en desktop; pantalla completa bajo 600 px
Material Design 3 especifica max-width: 560 dp. Por debajo de 600 dp (movil portrait) el dialog debe pasar a presentacion full-screen para mantener margenes de lectura comodos y targets tactiles adecuados.
Material Design 3, Dialogs (m3.material.io/components/dialogs/guidelines)Confirmar pago
Total: $4,500 MXN
Confirmar pago
Total: $4,500 MXN
Usa role='alertdialog' y focaliza el mensaje en prompts urgentes
Cuando el dialog requiere respuesta inmediata (vencimiento de sesion, confirmacion destructiva), usa role='alertdialog' con aria-labelledby apuntando al titulo y aria-describedby al cuerpo. Los lectores de pantalla anuncian el contenido inmediatamente al abrir.
Sesion por expirar
Tu sesion expirara en 5 minutos. Guarda tu trabajo o extiende la sesion.
role="alertdialog" anuncia titulo + cuerpo inmediatamente
Toast: auto-dismiss minimo 4 s; siempre ofrecer cierre manual
Toasts con auto-dismiss deben permanecer visibles al menos 4 segundos. Escala ~1 s por cada 3 palabras adicionales sobre base de 5 palabras. Los toasts de error nunca deben auto-cerrarse. Usa role='status' y aria-live='polite'.
Persiste 5 s · cierre manual disponible
Tu sesion ha expirado. Por favor inicia sesion de nuevo para continuar.
Cerrando en 2 s...
Dialogs de confirmacion solo para acciones irreversibles o de alto costo
Las confirmaciones repetidas para acciones de bajo riesgo producen desensibilizacion tipo "cry wolf": el usuario hace clic sin leer. Reserva el dialog para destruccion de datos, gasto significativo o acciones que no se pueden deshacer. Los labels de botones deben describir el resultado, no "Si / No".
Nielsen Norman Group, 'Confirmation Dialogs Can Prevent User Errors (If Not Overused)'Eliminar espacio de trabajo
Todos los proyectos y miembros seran eliminados permanentemente.
¿Estas seguro?
Scrim de 40-50% de opacidad negra; nunca opacidad total
El overlay detras del modal debe usar negro a 40-50% de opacidad. Mas oscuro del 60% desorienta al quitar contexto espacial; mas claro del 25% falla en indicar que el fondo esta bloqueado. En browsers modernos, backdrop-filter: blur(4px) con 20-30% es una alternativa elegante.
Scrim 45%
Contenido dimmed pero visible
Scrim 90%
Contexto de pagina invisible
No uses modal dialogs para informacion no bloqueante de baja urgencia
El costo de un modal es la interrupcion de la tarea actual. Solo se justifica cuando falta informacion requerida, se va a ejecutar una accion irreversible, o un error bloquea el progreso. Para mensajes informativos usa toast, banner, o panel lateral.
Nielsen Norman Group, 'Modal & Nonmodal Dialogs: When (& When Not) to Use Them'Suscribete al newsletter
Solo las mejores noticias
Aparece 1 s despues de cargar la pagina
Outside-click cierra dialogs transitorios; bloquea en confirmaciones destructivas
Date pickers, menus y selectores deben cerrarse al hacer clic en el scrim. Los dialogs de confirmacion destructiva y formularios con datos sin guardar no deben cerrarse con outside-click; requieren una accion explicita de Cancelar. Radix UI AlertDialog desactiva esto por disenio.
Radix UI, AlertDialog vs Dialog primitives · Nielsen Norman Group modal guidelinesEliminar proyecto
Esta accion no puede deshacerse
Clic exterior cierra
Editar direccion de facturacion
Clic en el fondo = datos perdidos silenciosamente
Usa el elemento nativo <dialog> con showModal() sobre implementaciones ARIA manuales
<dialog> + showModal() provee focus trap, Escape, semantica aria-modal, renderizado en top-layer y ::backdrop de forma nativa. Elimina la necesidad de librerias JS y evita los tres bugs mas comunes: z-index, overflow:hidden y transforms ancestros.
<dialog id="modal">
...contenido...
</dialog>
modal.showModal();
✓ Top-layer nativo, sobre todo
✓ Focus trap integrado
✓ ::backdrop sin DOM extra
<div role="dialog"
aria-modal="true"
style="z-index:9999">
</div>
✗ Clips bajo ancestors con overflow:hidden
✗ Requiere libreria focus-trap
✗ Bugs de z-index con date pickers
Nunca apiles multiples modals; usa un solo dialog con revelacion progresiva
Un segundo modal sobre uno activo crea focus traps anidados, ambiguedad en Escape, y confusion de scrim. Apple HIG y Nielsen Norman Group lo prohiben explicitamente. Si se necesita un sub-paso, reemplaza el contenido del mismo dialog en su lugar con indicador de progreso.
Apple HIG, Modality · Nielsen Norman Group, Bottom SheetsSeleccionar plantilla
Paso 1 de 2, el contenido del dialog se reemplaza, no se apila
Plantilla A
Plantilla B
Agregar miembro
Crear nuevo rol
Usuario no sabe cuantas capas hay
- R-1379 Trap de foco dentro del dialog; devuelve foco al cerrar
- R-1380 Foco inicial segun tipo de contenido, no siempre el primer campo
- R-1381 Boton de cierre visible con target minimo de 44x44 px
- R-1382 Ancho maximo de 560 px en desktop; pantalla completa bajo 600 px
- R-1383 Usa role='alertdialog' y focaliza el mensaje en prompts urgentes
- R-1384 Toast: auto-dismiss minimo 4 s; siempre ofrecer cierre manual
- R-1385 Dialogs de confirmacion solo para acciones irreversibles o de alto costo
- R-1386 Scrim de 40-50% de opacidad negra; nunca opacidad total
- R-1387 No uses modal dialogs para informacion no bloqueante de baja urgencia
- R-1388 Outside-click cierra dialogs transitorios; bloquea en confirmaciones destructivas
- R-1389 Usa el elemento nativo <dialog> con showModal() sobre implementaciones ARIA manuales
- R-1390 Nunca apiles multiples modals; usa un solo dialog con revelacion progresiva