También disponible en Inglés
La afirmación a prueba
El ensayo del martes sostuvo que el anclaje implícito ya resuelve el caso ordinario del popover sin costo alguno. Un popover vinculado a su propio activador (trigger) no necesita nombres, ni scoping, ni nada más. La brecha solo aparece cuando un requisito real sale de ese caso y, aun así, solo en combinación con algo fácil de pasar por alto: la estructura del DOM heredada de antes de que la plataforma resolviera el recorte de superposiciones (overlay clipping), cuando las superposiciones debían vivir separadas de aquello que las activaba.
Esta Nota reproduce exactamente esa combinación —un nombre de anchor compartido y un popover ubicado como hermano en lugar de descendiente— a lo largo de un grid de múltiples filas real, y confirma si aplicar el scope realmente corrige cada fila y no solo la que se probó por casualidad.
Míralo romperse
Cuatro filas, cada una con su propio menú de acciones, construidas de la manera descrita en el ensayo:
<div class="grid">
<div class="grid-row">
Q3 Report <button popovertarget="menu-1">⋮</button>
</div>
<menu id="menu-1" popover>
<button>Rename</button><button>Archive</button><button>Delete</button>
</menu>
<div class="grid-row">
Q4 Report <button popovertarget="menu-2">⋮</button>
</div>
<menu id="menu-2" popover>
<button>Rename</button><button>Archive</button><button>Delete</button>
</menu>
<div class="grid-row">
Annual Summary <button popovertarget="menu-3">⋮</button>
</div>
<menu id="menu-3" popover>
<button>Rename</button><button>Archive</button><button>Delete</button>
</menu>
<div class="grid-row">
Budget Draft <button popovertarget="menu-4">⋮</button>
</div>
<menu id="menu-4" popover>
<button>Rename</button><button>Archive</button><button>Delete</button>
</menu>
</div>
.grid-row {
anchor-name: --row-anchor;
}
[popover] {
position-anchor: --row-anchor;
position-area: right;
}
Haz clic en el : de "Q3 Report". El menú se abre —popovertarget maneja esa parte correctamente sin importar qué suceda— y se posiciona junto a "Budget Draft", la última fila del grid. Haz clic en el : de "Annual Summary". La misma posición. Haz clic en el de "Q4 Report". La misma posición de nuevo. Cada menú, de cada fila, cae exactamente en el mismo lugar: dondequiera que se ubique el último .grid-row.
Por qué nada lo detuvo
Cada <menu popover> se ubica directamente después de su propio .grid-row, como hermano; ambos son hijos de .grid. Ninguno contiene al otro. Cuando el navegador resuelve position-anchor: --row-anchor para cualquiera de los cuatro menús, busca primero el ancestro más cercano que lleve ese nombre y no encuentra ninguno, porque ningún menú está anidado dentro de una fila. Sin un ancestro que preferir, la resolución cae en la única regla que queda en pie: el último elemento del documento que lleve ese nombre de anchor. Las cuatro filas comparten exactamente el mismo nombre, establecido a través de la misma clase que cada fila ya utiliza para su diseño (layout). "Budget Draft" gana siempre, para cada menú, independientemente del botón en el que se haya hecho clic.
La solución
Nada cambia respecto al nombre del anchor, ni tampoco sobre el botón. Cada fila y su propio menú se envuelven juntos, y el nombre del anchor se limita a ese contenedor (wrapper):
<div class="grid">
<div class="row-wrapper">
<div class="grid-row">
Q3 Report <button popovertarget="menu-1">⋮</button>
</div>
<menu id="menu-1" popover>
<button>Rename</button><button>Archive</button><button>Delete</button>
</menu>
</div>
<div class="row-wrapper">
<div class="grid-row">
Q4 Report <button popovertarget="menu-2">⋮</button>
</div>
<menu id="menu-2" popover>
<button>Rename</button><button>Archive</button><button>Delete</button>
</menu>
</div>
<!-- Annual Summary y Budget Draft, mismo patrón -->
</div>
.grid-row {
anchor-name: --row-anchor;
}
.row-wrapper {
anchor-scope: --row-anchor;
}
[popover] {
position-anchor: --row-anchor;
position-area: right;
}
.row-wrapper es ahora el ancestro común que contiene tanto a un .grid-row como a su propio menú, y a nada más. Limitar --row-anchor a este contenedor significa que cada menú solo puede resolver el nombre dentro del subárbol de su propio wrapper. El anchor con nombre idéntico de cualquier otra fila deja de existir en lo que respecta a ese menú.
Haz clic de nuevo en el ⋮ de "Q3 Report". Se posiciona junto a "Q3 Report". Haz clic en el de "Annual Summary". Se posiciona junto a "Annual Summary". La solución no es específica de la fila que se probó primero: cada wrapper lleva la misma regla de scoping, por lo que cada fila obtiene el mismo resultado correcto, de forma independiente.
Si la afirmación se sostuvo
La afirmación del ensayo era que el anclaje implícito ya maneja el caso ordinario sin costo alguno, y que el costo real aparece solo donde un requisito sale de él mientras viejos hábitos estructurales se quedan sin examinar. Ambas mitades se sostuvieron. Anclar a la fila en lugar de al botón nunca fue el error: ese era un requisito real que el anclaje implícito genuinamente no puede cubrir. El error que nadie cometió a propósito fue dejar el menú donde siempre solían vivir las superposiciones de la era de JavaScript: junto a su activador, sin estar dentro de nada, porque esa solía ser la única forma de evitar que fuera recortado. El navegador no falló al buscar un ancestro. No había ninguno que encontrar.
Aplicar scope no requirió tocar el nombre del anchor, ni el botón, ni la relación con el popover. La única pieza que tuvo que cambiar fue exactamente la pieza que nadie tenía motivos para volver a mirar hasta que un grid con más de una fila demostró lo contrario.
Artículo de referencia
Los popovers nativos no reemplazaron a las bibliotecas de JS; reemplazaron al código de unión.
Top comments (0)