Popover API: foco, cierre y accesibilidad
Define contratos accesibles para popover=auto y manual: top layer, Escape, clic externo, foco, eventos y alternativa.
BotBrowser Team
Quieres la documentación estructurada de Plataforma?
Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.
BotBrowser puede repetir un fixture autorizado y registrar los resultados visibles de apertura, cierre y foco; no puede garantizar el comportamiento de tecnologías de asistencia ni convertir una alternativa en soporte del navegador. Combina esta guía con las comprobaciones accesibles de Pointer Events y las pruebas de accesibilidad de automatización cuando una tarea mezcla puntero y teclado.
TL;DR
- Elige
popover="auto"para una superficie no modal con light-dismiss; usamanualcuando el código posee cada cierre. - El top layer no crea una trampa de foco, un nombre accesible ni semántica de diálogo por sí solo.
- Prueba
Escape, clic externo, retorno del foco y el fondoinertcomo resultados separados. beforetogglepuede cancelar;toggleinforma de la transición confirmada y la alternativa debe conservar el resultado.
Contenido
- Elegir el modelo de estado
- Top layer y light-dismiss
- El foco y inert son contratos distintos
- Observar beforetoggle y toggle
- Construir una alternativa útil
- Ejecutar una matriz acotada
- Conclusión práctica
Elegir el modelo de estado
La especificación HTML de WHATWG define el atributo popover y los algoritmos que muestran y ocultan la superficie. popover="auto" sirve para menús, ayudas y filtros no modales que pueden descartarse. El navegador gestiona la pila de popovers automáticos. popover="manual" deja la decisión a la aplicación y conviene cuando varias superficies permanecen abiertas o una acción “terminar” es la única salida.
No trates el atributo como sinónimo de <dialog>. Un popover no es modal automáticamente, no atrapa el foco y no recibe un nombre accesible por defecto. Usa un button real, popovertarget y un nombre que describa el contenido. Elige roles de menú solamente cuando también implementes el comportamiento de teclado esperado.
La guía de Popover API de MDN documenta showPopover(), hidePopover() y togglePopover(). Detecta la API antes de escoger el camino imperativo y conserva una decisión visible de producto: qué contiene, cómo se cierra y qué queda disponible detrás.
Top layer y light-dismiss
Al mostrarse, la superficie entra en el top layer. En un popover auto, el navegador ofrece light-dismiss, pero esto no garantiza posición correcta en un viewport visual reducido, zoom, teclado virtual o iframe. Prueba Escape y el clic fuera como rutas distintas. Para manual, ofrece un botón de cierre y una ruta explícita; no dependas de una capa transparente que bloquee clics sin cambiar la semántica.
La introducción de Popover API de Chrome describe estos objetivos. Es una explicación de la plataforma, no una garantía idéntica en cada navegador o vista integrada. Registra versión y viewport, y afirma el resultado visible en vez del orden de pintado.
El foco y inert son contratos distintos
Mostrar no decide dónde va el foco. Según sea una sugerencia, un menú o un editor, conserva el foco en el activador o muévelo al primer control. Guarda el abridor y devuelve el foco a un elemento conectado y habilitado; si desaparece, usa un encabezado o el siguiente control documentado. No enfoques nodos separados ni anuncies cada evento interno.
Comprueba si teclado, puntero y tecnología de asistencia alcanzan los controles previstos. Un popover manual puede dejar activo el fondo por diseño; una tarea modal se expresa mejor con <dialog> y showModal(). Las guías de teclado de WCAG y focus-visible definen la frontera: nombre, rol, estado, indicador de foco y siguiente acción.
Observar beforetoggle y toggle
beforetoggle ocurre antes del cambio y permite rechazarlo o preparar una decisión de foco. toggle llega después del estado confirmado. Los cambios rápidos pueden agruparse; registra una etiqueta acotada como opened o closed-by-escape, no una auditoría de cada clic ni texto de página.
const trigger = document.querySelector('#filters-button');
const panel = document.querySelector('#filters-panel');
let opener = null;
trigger.addEventListener('click', () => {
opener = document.activeElement;
panel.togglePopover();
});
panel.addEventListener('beforetoggle', event => {
if (event.newState === 'open' && !trigger.isConnected) event.preventDefault();
});
panel.addEventListener('toggle', event => {
if (event.newState === 'closed' && opener?.isConnected) opener.focus();
});
Este patrón coordina estados; no promete el mismo orden de eventos. Si se cancela beforetoggle, la superficie y el foco deben seguir siendo utilizables. La alternativa debe exponer un estado equivalente aunque falte el evento.
Construir una alternativa útil
Detecta la API y usa un botón ordinario, una región inicialmente oculta y un cierre con aria-controls. Conserva contenido y orden de foco. Si el objetivo era modal, usa un patrón de diálogo compatible en vez de fingir que manual es modal. Gestiona método ausente, foco rechazado, abridor eliminado y cambios del viewport. BotBrowser puede comparar estados visibles declarados en un contexto autorizado; no certifica el habla de un lector de pantalla ni la implementación nativa de cada build.
Ejecutar una matriz acotada
| Ruta | Resultado esperado | Falla que investigar |
|---|---|---|
Invocación de teclado, auto | Abre, muestra foco y Escape cierra | El foco desaparece |
Clic externo, auto | Cierra una vez y devuelve foco | Limpieza duplicada |
Botón de cierre, manual | La aplicación oculta y restaura el abridor | Nadie posee el cierre |
| API ausente | Contenido y teclado equivalentes | Alternativa inalcanzable |
| Viewport reducido | Salida visible y texto legible | Única salida recortada |
Repite con zoom, movimiento reducido, táctil y viewport estrecho. Comprueba document.activeElement, nombre accesible, indicador y siguiente acción. Mantén el fixture sintético y registra solo etiquetas de estado.
Cuando el popover también debe seguir a un trigger que se mueve, consulta la guía de límites de CSS anchor positioning para probar anchor-name, las alternativas de reserva y el recorte aparte del foco.
Conclusión práctica
Elige auto o manual según quién posee el cierre y prueba top layer, light-dismiss, Escape, foco, inert y la alternativa por separado. WHATWG, MDN y Chrome explican la plataforma; BotBrowser repite un fixture visible autorizado, mientras la aplicación conserva la responsabilidad semántica.
Fuentes
FAQ
¿popover="auto" es un diálogo modal?
No. Es un modelo no modal con cierre gestionado por el navegador. Usa <dialog> y showModal() cuando la tarea sea modal.
¿El top layer mueve el foco?
No. Define el destino, el retorno y la alternativa cuando desaparece el abridor.
¿Todo popover debe cerrar con clic externo?
No. auto ofrece light-dismiss; manual deja la decisión al código. Haz visible la acción de cierre.
Este artículo forma parte de la guía: Superficies de la plataforma web: mapa de revisión
Artículos Relacionados
Pointer Events y accesibilidad con ratón, pantalla táctil y lápiz
Primeros pasosPruebas de accesibilidad con automatización del navegador
PlataformaPosicionamiento anchor CSS: límites de layout y overlays
PlataformaVoces de síntesis de voz y reproducción accesible en el navegador
PlataformaWeb Share API: límites de permisos y respaldos seguros
PlataformaNavigation API, historial y límites de privacidad
Lleva BotBrowser de la investigación a producción
Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.