anchor-size() y position-area: dimensionar y colocar en la rejilla
Leer el tamaño del ancla para dimensionar el anclado, y la rejilla de nueve celdas que coloca sin escribir un solo desplazamiento.
anchor() resuelve la posición pero no el tamaño, y hay una clase entera de componentes —el desplegable que mide lo mismo que su campo, el panel que no puede ser más ancho que su disparador— donde el tamaño es la mitad del problema. anchor-size() la resuelve. Y position-area ataca la posición desde el otro lado: en vez de escribir cuatro desplazamientos, declaras en cuál de las nueve celdas de una rejilla imaginaria alrededor del ancla quieres que caiga el elemento.
- Dimensionar un elemento anclado con
anchor-size(). - Colocar un elemento con
position-areaen lugar de con desplazamientos. - Leer la rejilla de nueve celdas y sus valores
span. - Decidir entre
position-areayanchor()según el caso.
anchor-size()
Devuelve una de las dimensiones del ancla y se escribe donde quepa una longitud: propiedades de tamaño, de tamaño mínimo y máximo, márgenes y desplazamientos.
.desplegable {
position: absolute;
position-anchor: --campo;
inline-size: anchor-size(width); /* exactamente el ancho del campo */
max-block-size: 20rem;
}
Los argumentos aceptados son las dimensiones físicas width y height, las lógicas block e inline, y las relativas al propio elemento self-block y self-inline. Como en anchor(), puedes anteponer un nombre de ancla y añadir un valor de reserva tras la coma.
.panel {
min-inline-size: anchor-size(--campo width, 12rem);
}
El uso que aparece constantemente es el desplegable de un campo de formulario, que debe medir lo mismo que el campo aunque el campo sea fluido. Antes había que medirlo con ResizeObserver y publicar el valor en una custom property; ahora es una declaración.
Otro uso menos evidente y muy útil: acotar el tamaño máximo de un tooltip al del contenido que describe, para que un texto largo no se convierta en una franja que cruza la pantalla.
.tooltip { max-inline-size: max(anchor-size(width), 16rem); }
anchor-size() está en Chrome 125, Safari 26 y Firefox 147. Su uso dentro de propiedades de inset y margin llegó algo después en Chromium, en Chrome 132, pero en Safari y Firefox vino desde el principio.
position-area y la rejilla de nueve
position-area es la forma declarativa de colocar. Imagina el ancla como la celda central de una rejilla de tres por tres: alrededor hay ocho celdas más, y el valor de la propiedad dice en cuál cae el anclado.
Los valores se escriben en dos partes, una por eje. Puedes usar los términos físicos —top, bottom, left, right, center— o los lógicos —block-start, block-end, inline-start, inline-end, start, end, center—, pero no puedes mezclar los dos sistemas en el mismo valor.
.menu {
position: absolute;
position-anchor: --boton;
position-area: block-end center; /* justo debajo, centrado */
margin-block-start: .5rem;
}
Con un solo término, el otro eje se rellena por simetría: position-area: top equivale a top center.
Los valores span-* permiten ocupar dos celdas del eje, que es como se consigue el clásico “debajo y alineado por la izquierda”:
.menu { position-area: block-end span-inline-end; }
span-inline-end significa: ocupa desde el centro hacia el final del eje en línea, es decir, la celda central y la final. En un documento de izquierda a derecha, el menú queda debajo del botón y alineado con su borde izquierdo, extendiéndose hacia la derecha. span-all ocupa las tres celdas del eje y centra el elemento sobre el ancla en ese eje.
flowchart TB A[La rejilla alrededor del ancla] --> B[block-start inline-start] A --> C[block-start center] A --> D[block-start inline-end] A --> E[center inline-start] A --> F[El ancla ocupa la celda central] A --> G[center inline-end] A --> H[block-end inline-start] A --> I[block-end center] A --> J[block-end inline-end] style A fill:#89b4fa,color:#11111b style F fill:#f9e2af,color:#11111b style C fill:#a6e3a1,color:#11111b style I fill:#a6e3a1,color:#11111b style E fill:#cba6f7,color:#11111b style G fill:#cba6f7,color:#11111b
position-area trae un comportamiento por defecto que ahorra trabajo: dentro de la celda asignada, el elemento se alinea automáticamente hacia el ancla. Un elemento en block-end center se alinea por su borde superior contra el borde inferior del ancla, sin que tú lo pidas. Puedes cambiar esa alineación con justify-self y align-self como en cualquier caja de alineación.
Un detalle a tener en cuenta: cuando declaras position-area, la propiedad desactiva los márgenes automáticos y los desplazamientos que hubieras puesto, porque toma el control de la colocación en los dos ejes. Si necesitas un ajuste fino, usa márgenes normales, que sí se respetan y son la forma correcta de dejar el hueco entre ancla y anclado.
Cuál de los dos usar
position-area cubre bien la gran mayoría de los casos y es mucho más legible: una declaración frente a dos o cuatro, y el nombre dice dónde va a quedar la cosa. Además se combina de forma natural con los fallbacks de la lección siguiente, porque una lista de posiciones alternativas es literalmente una lista de celdas de la rejilla.
anchor() sigue siendo necesaria cuando:
- Necesitas leer anclas distintas en propiedades distintas, como la barra que se estira entre dos elementos.
- Necesitas un porcentaje que no sea uno de los tercios de la rejilla, como
anchor(25%). - Necesitas meter el valor dentro de un
calc()con otra expresión. - Quieres controlar solo un eje y dejar el otro en su posición estática.
La combinación también es válida: puedes usar position-area para la colocación general y anchor-size() para el dimensionado, que es la pareja más habitual en un desplegable de formulario.
.lista-opciones {
position: absolute;
position-anchor: --campo;
position-area: block-end span-inline-end;
inline-size: anchor-size(width);
margin-block-start: .25rem;
}
La decisión de diseño más inteligente de position-area no es la sintaxis, es que expresa la posición en un vocabulario cerrado y simétrico. Con desplazamientos, “encima del ancla” y “debajo del ancla” son dos configuraciones que no tienen nada que ver la una con la otra: cambian de propiedad, de lado y de signo. Con position-area son block-start y block-end, dos valores del mismo tipo. Esa simetría es lo que hace que el sistema de reposicionamiento automático de la lección siguiente pueda existir: cuando el motor descubre que el elemento no cabe abajo, no necesita reescribir tus declaraciones, solo necesita reflejar un valor en su eje, que es una operación bien definida sobre el vocabulario. Por eso position-try-fallbacks: flip-block es una palabra clave de una línea y no un bloque de reglas. La lección general vale más allá de CSS y merece la pena guardarla: cuando eliges un vocabulario cerrado y simétrico en lugar de números libres, obtienes transformaciones automáticas que con números habrías tenido que escribir a mano. Es la misma razón por la que las propiedades lógicas permiten voltear una interfaz a derecha-a-izquierda sin tocar una regla, y por la que row-reverse es una palabra clave y no una reescritura del layout.
- Haz que un desplegable mida exactamente lo mismo que su campo con
anchor-size(width)y comprueba que sigue el ancho al redimensionar. - Coloca el mismo desplegable con
position-area: block-end span-inline-endy compáralo con la versión escrita con dosanchor(). - Prueba las nueve combinaciones de la rejilla sobre un mismo ancla y observa la alineación automática de cada una.
- Añade
span-allen un eje y verifica que el elemento queda centrado sobre el ancla en ese eje. - Declara un desplazamiento manual junto a
position-areay comprueba que se ignora; sustitúyelo por un margen.