Saltar al contenido

CSS, de a poco

Curso de CSS

Anchor positioning

Lección 31 de 37 · 4 min

Un tooltip o un menú tiene que quedar pegado a su botón, y darse vuelta cuando no entra. Durante años eso pidió JavaScript que midiera posiciones; ahora lo resuelve CSS.

Anclar un elemento a otro

Anchor positioning es reciente: anda en Chrome y Edge desde 2024, en Safari 26 y en Firefox 147. Todavía hay navegadores sin soporte, así que usalo como mejora progresiva. Se arma con tres propiedades:

  1. El anclaanchor-nameLe da al ancla un nombre que empieza con dos guiones, como --ancla.
  2. A quién se pegaposition-anchorVa en el elemento posicionado, que tiene que tener position: absolute o fixed: dice a qué ancla se pega.
  3. Dónde caeposition-areaElige una zona de una grilla de 3×3 alrededor del ancla. top es toda la fila de arriba; top span-right es arriba, desde el borde izquierdo del ancla hacia la derecha.

En el lienzo, el pin del comentario es el ancla y su nota es el elemento posicionado. Las líneas naranjas prolongan los bordes del ancla y arman la grilla de 3×3; la zona teñida es la que ocupa la nota. Elegí una posición, mové el pin con el slider y desplazá el lienzo (con la rueda, o con las flechas después de enfocarlo) para llevarlo a un borde.

position-area: top span-rightactiva: arriba, hacia la derecha

bloque contenedor 288 × 208

Desplazá el lienzo hasta un borde

zona
pin.css
.pin {
anchor-name: --pin;
}
.nota {
/* sin soporte, queda en su posición estática */
position: absolute;
margin: 6px;
}
@supports (position-area: top) {
.nota {
position-anchor: --pin;
position-area: top span-right;
position-try-fallbacks: flip-block, flip-inline;
}
}
pin.html
<button class="[anchor-name:--pin]" aria-describedby="comentario-3">
Comentario 3
</button>
<div id="comentario-3" role="tooltip"
class="absolute m-1.5 [position-anchor:--pin] [position-area:top_span-right] [position-try-fallbacks:flip-block,flip-inline]">
Más aire arriba
</div>

También existe la función anchor(), que va en las propiedades de inset: top: anchor(bottom) pone el borde de arriba del tooltip sobre el borde de abajo del ancla. Sirve para ajustes finos, pero para el día a día preferí position-area: es más corta y los fallbacks la dan vuelta sin que tengas que pensar en cada lado.

Darse vuelta en el borde

Si el tooltip no entra en su zona, desborda el contenedor. position-try-fallbacks le da una lista de alternativas: cuando la posición actual desborda, el navegador prueba las opciones en orden y usa la primera que entra. Si ninguna entra, el tooltip desborda igual.

  1. De arriba a abajoflip-blockLo da vuelta en el eje de bloque.
  2. De izquierda a derechaflip-inlineLo da vuelta en el eje inline.
  3. Cambia los ejesflip-startCambia un eje por el otro, así top pasa a left y bottom a right.
Un pin cerca del borde de arriba del lienzo, con su nota pedida arriba. Sin fallbacks la nota se sale del lienzo por arriba; con flip-block el navegador la da vuelta y la pone abajo del pin.

Separadas por coma son opciones distintas; flip-block flip-inline sin coma es una sola opción que da vuelta los dos ejes. Para una alternativa a medida, definila con @position-try. Y anchor-size() mide el ancla: con ella, un menú nunca es más angosto que su botón.

menu.css
@position-try --abajo-a-la-izquierda {
position-area: bottom span-left;
}
@supports (position-area: top) {
.menu {
position-anchor: --boton;
position-area: bottom span-right;
position-try-fallbacks: --abajo-a-la-izquierda, flip-block;
min-width: anchor-size(width);
}
}

El @supports deja afuera a los navegadores sin soporte: ahí el menú queda en su posición estática, donde estaría sin posicionar. Por eso conviene escribirlo justo después del botón en el HTML: así el fallback sigue teniendo sentido.

Con popover, para tooltips y menús

Anchor positioning decide dónde va el elemento, no cuándo aparece. Para eso está el atributo popover, Baseline desde 2025: pone el elemento en el top layer, por encima de todo y sin que lo recorte un overflow: hidden, y lo cierra con Escape o con un clic afuera. Juntos son la combinación recomendada para menús y tooltips.

menu.html
<button popovertarget="opciones" class="boton">Opciones</button>
<div id="opciones" popover class="menu">…</div>

El navegador le da a todo popover margin: auto, que lo centraría dentro de su zona; ponele margin: 0 para que se alinee con el botón.

Anchor positioning es solo visual: no cambia el orden del DOM ni lo que anuncia un lector de pantalla. Dejá el tooltip cerca de su botón en el HTML, con role="tooltip", y conectalos con aria-describedby para que el botón lo lea como descripción. Si animás la entrada, hacelo dentro de @media (prefers-reduced-motion: no-preference).

En Tailwind

Tailwind v4.3 no trae utilidades para anchor positioning, así que van como propiedades arbitrarias: la propiedad y el valor entre corchetes, con guiones bajos en lugar de espacios. Las de inset y tamaño sí aceptan las funciones como valor arbitrario.

CSSTailwind
anchor-name: --ancla[anchor-name:--ancla]
position-area: top span-right[position-area:top_span-right]
position-try-fallbacks: flip-block, flip-inline[position-try-fallbacks:flip-block,flip-inline]
top: anchor(bottom)top-[anchor(bottom)]
min-width: anchor-size(width)min-w-[anchor-size(width)]
@supports (position-area: top)supports-[position-area:top]:
ancla.html
<button class="[anchor-name:--ancla]" aria-describedby="ayuda">Guardar</button>
<div id="ayuda" role="tooltip"
class="absolute m-1 [position-anchor:--ancla] [position-area:top]
[position-try-fallbacks:flip-block,flip-inline]">
Guarda sin cerrar
</div>