Presentamos la API de posicionamiento de anclas de CSS

Una Kravets
Una Kravets

Fecha de publicación: 10 de mayo de 2024

La API de posicionamiento de anclas de CSS cambia las reglas del juego en el desarrollo web, ya que te permite posicionar elementos de forma nativa en relación con otros elementos, conocidos como anclas. Esta API simplifica los requisitos de diseño complejos para muchas funciones de interfaz, como menús y submenús, cuadros de herramientas, selecciones, etiquetas, tarjetas, diálogos de configuración y muchas más. Con el posicionamiento de ancla integrado en el navegador, podrás crear interfaces de usuario en capas sin depender de bibliotecas de terceros, lo que te abrirá un mundo de posibilidades creativas.

El posicionamiento de ancla está disponible a partir de Chrome 125.

Navegadores compatibles

  • Chrome: 125.
  • Edge: 125
  • Firefox: No es compatible.
  • Safari: no es compatible.

Origen

Conceptos básicos: Anclas y elementos posicionados

En el centro de esta API, se encuentra la relación entre las anclas y los elementos posicionados. Un ancla es un elemento designado como punto de referencia con la propiedad anchor-name. Un elemento posicionado es un elemento que se coloca en relación con un ancla mediante la propiedad position-anchor o de forma explícita con anchor-name en su lógica de posicionamiento.

Elementos de anclaje y elementos posicionados.

Cómo configurar anclas

Crear un ancla es sencillo. Aplica la propiedad anchor-name al elemento seleccionado y asígnale un identificador único. Este identificador único debe anteponerse con un guion doble, al igual que una variable CSS.

.anchor-button {
    anchor-name: --anchor-el;
}

Una vez que se le asigna un nombre de ancla, .anchor-button funciona como ancla y está listo para guiar la ubicación de otros elementos. Puedes conectar este ancla a otros elementos de una de las siguientes maneras:

Anclas implícitas

La primera forma de conectar un ancla a otro elemento es con una ancla implícita, como en el siguiente ejemplo de código. La propiedad position-anchor se agrega al elemento que deseas conectar a tu ancla y tiene el nombre de la ancla (en este caso, --anchor-el) como valor.

.positioned-notice {
    position-anchor: --anchor-el;
}

Con una relación de anclaje implícita, puedes posicionar elementos con la función anchor() sin especificar explícitamente el nombre del ancla en su primer argumento.

.positioned-notice {
    position-anchor: --anchor-el;
    top: anchor(bottom);
}

Anclajes explícitos

Como alternativa, puedes usar el nombre del ancla directamente en la función de ancla (por ejemplo, top: anchor(--anchor-el bottom). Esto se denomina anclaje explícito y puede ser útil si deseas anclar a varios elementos (sigue leyendo para ver un ejemplo).

.positioned-notice {
    top: anchor(--anchor-el bottom);
}

Cómo posicionar elementos en relación con las anclas

Diagrama de posicionamiento de anclaje con propiedades físicas.

El posicionamiento de anclaje se basa en el posicionamiento absoluto de CSS. Para usar valores de posicionamiento, debes agregar position: absolute a tu elemento posicionado. Luego, usa la función anchor() para aplicar los valores de posicionamiento. Por ejemplo, para posicionar un elemento fijo en la parte superior izquierda del elemento de anclaje, usa el siguiente posicionamiento:

.positioned-notice {
    position-anchor: --anchor-el;
    /* absolutely position the positioned element */
    position: absolute;
    /* position the right of the positioned element at the right edge of the anchor */
    right: anchor(right);
    /* position the bottom of the positioned element at the top edge of the anchor */
    bottom: anchor(top);
}
Diagrama de bordes de posicionamiento en el elemento posicionado.

Ahora tienes un elemento anclado a otro, como se muestra en la siguiente imagen.

Captura de pantalla de la demostración.

Para usar el posicionamiento lógico para estos valores, los equivalentes son los siguientes:

  • top = inset-block-start
  • left= inset-inline-start
  • bottom = inset-block-end
  • right= inset-inline-end

Centra un elemento posicionado con anchor-center

Para facilitar el centrado del elemento posicionado de la ancla en relación con su ancla, hay un valor nuevo llamado anchor-center que se puede usar con las propiedades justify-self, align-self, justify-items y align-items.

En este ejemplo, se modifica el anterior con justify-self: anchor-center para centrar el elemento posicionado sobre su ancla.

.positioned-notice {
  position: absolute;
  /*  Anchor reference  */
  position-anchor: --anchor-el;
  /*  Position bottom of positioned elem at top of anchor  */
  bottom: anchor(top);
  /*  Center justification to the anchor */
  justify-self: anchor-center;
}

Captura de pantalla de la demostración.

Anclajes múltiples

Los elementos se pueden vincular a más de un ancla. Esto significa que es posible que debas establecer valores de posición que se posicionen en relación con más de un ancla. Para ello, usa la función anchor() y especifica de forma explícita a qu�� ancla a la que haces referencia en el primer argumento. En el siguiente ejemplo, la parte superior izquierda de un elemento posicionado está anclada a la parte inferior derecha de un ancla, y la parte inferior derecha del elemento posicionado está anclada a la parte superior izquierda del segundo ancla:

.anchored {
  position: absolute;
  top: anchor(--one bottom);
  left: anchor(--one right);
  right: anchor(--two left);
  bottom: anchor(--two top);
}

Captura de pantalla de la demostración.

Posición con inset-area

Además del posicionamiento direccional predeterminado del posicionamiento absoluto, hay un nuevo mecanismo de diseño incluido en la API de anclaje llamado área de inserción.

El área de inserción facilita la colocación de los elementos de posicionamiento de los anclas en relación con sus respectivas anclas y funciona en una cuadrícula de 9 celdas con el elemento de anclaje en el centro.

Varias opciones de posicionamiento posibles para el área de inserción, que se muestran en la cuadrícula de 9 celdas

Para usar el área de inserción en lugar del posicionamiento absoluto, usa la propiedad inset-area, con valores físicos o lógicos. Por ejemplo:

  • Centro superior: inset-area: top o inset-area: block-start
  • Parte central izquierda: inset-area: left o inset-area: inline-start
  • Parte inferior central: inset-area: bottom o inset-area: block-end
  • Centro derecho: inset-area: right o inset-area: inline-end

Captura de pantalla de la demostración.

Cómo establecer el tamaño de los elementos con anchor-size()

La función anchor-size(), que también forma parte de la API de posicionamiento de anclas, se puede usar para ajustar el tamaño o la posición de un elemento posicionado con ancla según el tamaño de su ancla (ancho, altura o tamaños intercalados y de bloque).

En el siguiente código CSS, se muestra un ejemplo de cómo usar esto para la altura, con anchor-size(height) dentro de una función calc() para establecer la altura máxima de la herramienta de ayuda en dos veces la altura del ancla.

.positioned-notice {
  position-anchor: --question-mark;

  /*  set max height of the tooltip to 2x height of the anchor  */
  max-height: calc(anchor-size(height) * 2);
}

Captura de pantalla de la demostración.

Usa el ancla con elementos de capa superior, como el cuadro emergente y el diálogo

El posicionamiento de ancla funciona muy bien con elementos de capa superior, como popover. y <dialog>. Si bien estos elementos se colocan en una capa separada del resto del subárbol del DOM, el posicionamiento de ancla te permite volver a conectarlos y desplazarte junto con los elementos que no están en la capa superior. Esto es una gran ventaja para las interfaces en capas.

En el siguiente ejemplo, se activa un conjunto de ventanas emergentes con información sobre la herramienta con un botón. El botón es el ancla y la información sobre herramientas es el elemento posicionado. Puedes aplicar diseño al elemento posicionado como a cualquier otro elemento anclado. Para este ejemplo específico, anchor-name y position-anchor son estilos intercalados en el botón y la información sobre la herramienta. Debido a que cada ancla necesita un nombre único, cuando se genera contenido dinámico, la incorporación es la forma más fácil de hacerlo.

Captura de pantalla de la demostración.

Cómo ajustar las posiciones de las anclas con @position-try

Una vez que tengas la posición de ancla inicial, te recomendamos que la ajustes si llega a los bordes de su bloque contenedor. Para crear posiciones de anclaje alternativas, puedes usar la directiva @position-try junto con la propiedad position-try-options.

En el siguiente ejemplo, aparece un submenú a la derecha de un menú. Los menús y los submenús son un excelente uso de la API de posicionamiento de ancla junto con el atributo de ventana emergente, ya que estos menús suelen estar anclados a un botón de activación.

En el caso de este submenú, si no hay suficiente espacio horizontal, puedes moverlo debajo del menú. Para ello, primero configura la posición inicial:

#submenu {
  position: absolute;
  position-anchor: --submenu;

  /* initial position */
  margin-left: var(--padding);
  inset-area: right span-bottom;
}

Luego, configura tus posiciones de anclaje de resguardo con @position-try:

/* alternate position */
@position-try --bottom {
  margin: var(--padding) 0 0 var(--padding);
  inset-area: bottom;
}

Por último, conecta los dos con position-try-options. Todo junto se ve de la siguiente manera:

#submenu {
  position: absolute;
  position-anchor: --submenu;
  /* initial position */
  margin-left: var(--padding);
  inset-area: right span-bottom;
  */ connect with position-try options */
  position-try-options: --bottom;
}

/* alternate position */
@position-try --bottom {
  margin: var(--padding) 0 0 var(--padding);
  inset-area: bottom;
}

Palabras clave de cambio automático de posición del ancla

Si tienes un ajuste básico, como voltear de arriba abajo o de izquierda a derecha (o ambas), incluso puedes omitir el paso de crear declaraciones @position-try personalizadas y usar las palabras clave de cambio integradas compatibles con el navegador, como flip-block y flip-inline. Estos funcionan como sustitutos de las declaraciones @position-try personalizadas y se pueden usar en combinación entre sí:

position-try-options: flip-block, flip-inline, flip-block flip-inline;

Cambiar las palabras clave puede simplificar significativamente tu código fijo. Con solo unas pocas líneas, puedes crear un ancla completamente funcional con posiciones alternativas:

#my-tooltip {
  position-anchor: --question-mark;
  inset-area: top;
  position-try-options: flip-block;
}

position-visibility para anclas en subpaneles de desplazamiento

En algunos casos, es posible que desees fijar un elemento dentro de un subpanel de desplazamiento de la página. En estos casos, puedes controlar la visibilidad del ancla con position-visibility. ¿Cuándo permanece a la vista el ancla? ¿Cuándo desaparece? Con esta función, tienes control sobre estas opciones. Usas position-visibility: anchors-visible cuando deseas que el elemento posicionado permanezca en la vista hasta que el ancla esté fuera de la vista:

#tooltip {
  position: fixed;
  position-anchor: --anchor-top-anchor;
  position-visibility: anchors-visible;
  bottom: anchor(top);
}

Como alternativa, puedes usar position-visibility: no-overflow para evitar que el ancla sobrepase su contenedor.

#tooltip {
  position: absolute;
  position-anchor: --anchor-top-anchor;
  position-visibility: no-overflow;
  bottom: anchor(top);
}

Detección de funciones y polyfill

Debido a que la compatibilidad con navegadores es limitada en este momento, es probable que quieras usar esta API con algunas precauciones. Primero, puedes verificar la compatibilidad directamente en CSS con la consulta de funciones @supports. Para ello, une tus estilos de ancla en lo siguiente:

@supports (anchor-name: --myanchor) {

  /* Anchor styles here */

}

Además, puedes usar el polyfill de posicionamiento de anclas de CSS de Oddbird para la función de posicionamiento de anclas, que funciona desde Firefox 54, Chrome 51, Edge 79 y Safari 10. Este polyfill admite la mayoría de las funciones básicas de posición de anclajes, aunque la implementación actual no está completa y contiene una sintaxis desactualizada. Puedes usar el vínculo de unpkg o importarlo directamente en un administrador de paquetes.

Nota sobre la accesibilidad

Si bien la API de posicionamiento de anclajes permite que un elemento se posicione relativo a otros, no crea de forma inherente ninguna relación semántica significativa entre ellos. Si realmente hay una relación semántica entre el elemento de anclaje y el elemento posicionado (por ejemplo, el elemento posicionado es un comentario de la barra lateral sobre el texto de anclaje), una forma de hacerlo es usar aria-details para apuntar desde el elemento de anclaje a los elementos posicionados. El software de lector de pantalla aún está aprendiendo a tratar con aria-details, pero la compatibilidad está mejorando.

<div class="anchor" aria-details="sidebar-comment">Main content</div>
<div class="positioned" id="sidebar-comment">Sidebar content</div>
.anchor {
  anchor-name: --anchor;
}

.positioned {
  position: fixed;
  position-anchor: --anchor;
}

Si usas el posicionamiento de ancla con el atributo popover o con un elemento <dialog>, el navegador controlará las correcciones de navegación de enfoque para una accesibilidad adecuada, por lo que no es necesario que tengas tus ventanas emergentes o diálogos en orden DOM. Obtén más información sobre la nota de accesibilidad en la especificación.

Conclusión

Esta es una función completamente nueva y estamos ansiosos por ver lo que crearás con ella. Hasta ahora, vimos algunos casos de uso muy interesantes de la comunidad, como etiquetas dinámicas en gráficos, líneas de conexión, notas al pie y referencias cruzadas visuales. Mientras experimentas con el posicionamiento de los anclajes, nos encantaría recibir tus comentarios. Si encuentras algún error, avísanos.

Lecturas adicionales