Présentation de l'API de positionnement de l'ancrage CSS

Publié le 10 mai 2024

L'API CSS Anchor Positioning est un outil révolutionnaire dans le développement Web, car elle vous permet de positionner nativement des éléments par rapport à d'autres éléments, appelés ancres. Cette API simplifie les exigences de mise en page complexes pour de nombreuses fonctionnalités d'interface, telles que les menus et sous-menus, les info-bulles, les sélecteurs, les libellés, les fiches, les boîtes de dialogue de paramètres, etc. Grâce au positionnement des ancres intégré au navigateur, vous pouvez créer des interfaces utilisateur multicouches sans avoir à vous appuyer sur des bibliothèques tierces, ce qui ouvre un monde de possibilités créatives.

Le positionnement de l'ancre est disponible à partir de Chrome 125.

Navigateurs pris en charge

  • Chrome : 125.
  • Edge: 125
  • Firefox : non compatible.
  • Safari: non compatible.

Source

Concepts fondamentaux: ancrages et éléments positionnés

Au cœur de cette API se trouve la relation entre les ancrages et les éléments positionnés. Une ancre est un élément désigné comme point de référence à l'aide de la propriété anchor-name. Un élément positionné est un élément placé par rapport à un ancrage à l'aide de la propriété position-anchor ou à l'aide d'anchor-name explicitement dans sa logique de positionnement.

Éléments ancrés et éléments positionnés

Configurer des ancres

La création d'une ancre est simple. Appliquez la propriété du nom de l'ancre à l'élément sélectionné et attribuez-lui un identifiant unique. Cet identifiant unique doit être précédé d'un double tiret, comme pour une variable CSS.

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

Une fois le nom d'ancrage attribué, .anchor-button sert d'ancre et est prêt à guider le positionnement d'autres éléments. Vous pouvez connecter cette ancre à d'autres éléments de deux manières:

Ancres implicites

La première façon de connecter une ancre à un autre élément consiste à utiliser une ancre implicite, comme dans l'exemple de code suivant. La propriété position-anchor est ajoutée à l'élément que vous souhaitez connecter à votre ancre. Le nom de l'ancre (dans ce cas, --anchor-el) est utilisé comme valeur.

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

Avec une relation d'ancrage implicite, vous pouvez positionner des éléments à l'aide de la fonction anchor() sans spécifier explicitement le nom de l'ancre dans son premier argument.

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

Ancres explicites

Vous pouvez également utiliser le nom de l'ancre directement dans la fonction d'ancrage (par exemple, top: anchor(--anchor-el bottom). Il s'agit d'un ancrage explicite, qui peut être utile si vous souhaitez ancrer à plusieurs éléments (pour en savoir plus, lisez la suite).

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

Positionner des éléments par rapport à des ancrages

Diagramme de positionnement des ancres avec des propriétés physiques.

Le positionnement des ancres s'appuie sur le positionnement absolu CSS. Pour utiliser des valeurs de positionnement, vous devez ajouter position: absolute à votre élément positionné. Utilisez ensuite la fonction anchor() pour appliquer les valeurs de positionnement. Par exemple, pour positionner un élément ancré en haut à gauche de l'élément d'ancrage, utilisez le positionnement suivant:

.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);
}
Diagramme des bords de positionnement sur l'élément positionné.

Vous avez maintenant un élément ancré à un autre, comme illustré dans l'image suivante.

Capture d'écran de la démonstration

Pour utiliser un positionnement logique pour ces valeurs, les équivalents sont les suivants:

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

Centrer un élément positionné avec anchor-center

Pour centrer plus facilement votre élément positionné par ancrage par rapport à son ancrage, une nouvelle valeur appelée anchor-center peut être utilisée avec les propriétés justify-self, align-self, justify-items et align-items.

Cet exemple modifie l'exemple précédent en utilisant justify-self: anchor-center pour centrer l'élément positionné au-dessus de son ancrage.

.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;
}

Capture d'écran de la démonstration

Plusieurs ancres

Les éléments peuvent être rattachés à plusieurs ancrages. Vous devrez peut-être définir des valeurs de position par rapport à plusieurs ancres. Pour ce faire, utilisez la fonction anchor() et indiquez explicitement l'ancre à laquelle vous faites référence dans le premier argument. Dans l'exemple suivant, l'angle supérieur gauche d'un élément positionné est ancré à l'angle inférieur droit d'un ancrage, et l'angle inférieur droit de l'élément positionné est ancré à l'angle supérieur gauche du deuxième ancrage:

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

Capture d'écran de la démonstration.

Position avec inset-area

En plus du positionnement directionnel par défaut du positionnement absolu, un nouveau mécanisme de mise en page est inclus dans l'API d'ancrage, appelé zone intérieure.

La zone d'encart permet de placer facilement des éléments positionnés par ancrage par rapport à leurs ancrages respectifs. Elle fonctionne sur une grille à 9 cellules, avec l'élément d'ancrage au centre.

Différentes options de positionnement possibles pour la zone en retrait, illustrées sur la grille à 9 cellules

Pour utiliser une zone en retrait plutôt qu'un positionnement absolu, utilisez la propriété inset-area, avec des valeurs physiques ou logiques. Exemple :

  • En haut au centre: inset-area: top ou inset-area: block-start
  • Centre gauche: inset-area: left ou inset-area: inline-start
  • En bas au centre: inset-area: bottom ou inset-area: block-end
  • Centrer à droite: inset-area: right ou inset-area: inline-end

Capture d'écran de la démonstration.

Redimensionner des éléments avec anchor-size()

La fonction anchor-size(), qui fait également partie de l'API de positionnement d'ancre, permet de dimensionner ou de positionner un élément positionné par ancre en fonction de la taille de son ancre (largeur, hauteur ou tailles en ligne et en bloc).

Le code CSS suivant montre comment utiliser cette méthode pour la hauteur,en utilisant anchor-size(height) dans une fonction calc() pour définir la hauteur maximale de l'info-bulle sur deux fois la hauteur de l'ancre.

.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);
}

Capture d'écran de la démonstration

Utiliser une ancre avec des éléments de couche supérieure tels que les pop-ups et les boîtes de dialogue

Le positionnement de l'ancrage fonctionne très bien avec des éléments de couche supérieure tels que popover. et <dialog>. Bien que ces éléments soient placés dans une couche distincte du reste du sous-arbre DOM, le positionnement des ancres vous permet de les rattacher à des éléments qui ne se trouvent pas dans la couche supérieure et de faire défiler la page avec eux. C'est un avantage considérable pour les interfaces multicouches.

Dans l'exemple suivant, un ensemble de pop-ups d'info-bulle est déclenché à l'aide d'un bouton. Le bouton est l'ancre et la bulle d'info est l'élément positionné. Vous pouvez appliquer un style à l'élément positionné comme à n'importe quel autre élément ancré. Dans cet exemple, anchor-name et position-anchor sont des styles intégrés au bouton et à la bulle d'aide. Étant donné que chaque ancre doit avoir un nom unique, l'intégration est le moyen le plus simple de procéder lors de la génération de contenu dynamique.

Capture d&#39;écran de la démonstration.

Ajuster la position des ancres avec @position-try

Une fois que vous avez défini la position initiale de l'ancre, vous pouvez l'ajuster si elle atteint les bords de son bloc contenant. Pour créer d'autres positions d'ancrage, vous pouvez utiliser la directive @position-try avec la propriété position-try-options.

Dans l'exemple suivant, un sous-menu s'affiche à droite d'un menu. Les menus et sous-menus sont un excellent moyen d'utiliser l'API de positionnement d'ancrage avec l'attribut popover, car ces menus ont tendance à être ancrés à un bouton de déclencheur.

Pour ce sous-menu, si l'espace horizontal est insuffisant, vous pouvez le déplacer sous le menu à la place. Pour ce faire, commencez par configurer la position initiale:

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

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

Ensuite, configurez vos positions d'ancrage de remplacement à l'aide de @position-try:

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

Enfin, associez les deux avec position-try-options. En résumé, cela se présente comme suit:

#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;
}

Inversion automatique des mots clés en fonction de la position de l'ancrage

Si vous effectuez un ajustement de base, comme un retournement de haut en bas ou de gauche à droite (ou les deux), vous pouvez même ignorer l'étape de création de déclarations @position-try personnalisées et utiliser les mots clés de retournement intégrés compatibles avec le navigateur, tels que flip-block et flip-inline. Ils servent de substituts aux déclarations @position-try personnalisées et peuvent être combinés:

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

Les mots clés inversés peuvent simplifier considérablement votre code d'ancrage. En quelques lignes, vous pouvez créer une ancre entièrement fonctionnelle avec des positions alternatives:

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

position-visibility pour les ancrages dans les sous-sélecteurs

Dans certains cas, vous pouvez souhaiter ancrer un élément dans un sous-sélecteur de la page. Dans ce cas, vous pouvez contrôler la visibilité de l'ancre à l'aide de position-visibility. Quand l'ancre reste-t-elle visible ? Quand disparaît-il ? Cette fonctionnalité vous permet de contrôler ces options. Vous utilisez position-visibility: anchors-visible lorsque vous souhaitez que l'élément positionné reste visible jusqu'à ce que l'ancre ne soit plus visible:

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

Vous pouvez également utiliser position-visibility: no-overflow pour empêcher l'ancrage de déborder de son conteneur.

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

Détection de caractéristiques et polyfilling

La prise en charge des navigateurs étant limitée pour le moment, vous souhaiterez probablement utiliser cette API en prenant quelques précautions. Tout d'abord, vous pouvez vérifier la compatibilité directement dans CSS à l'aide de la requête de fonctionnalité @supports. Pour ce faire, procédez comme suit:

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

  /* Anchor styles here */

}

Vous pouvez également utiliser le polyfill de positionnement des ancres CSS d'Oddbird, qui fonctionne à partir de Firefox 54, Chrome 51, Edge 79 et Safari 10. Ce polyfill est compatible avec la plupart des fonctionnalités de base de la position des ancres, mais l'implémentation actuelle n'est pas complète et contient une syntaxe obsolète. Vous pouvez utiliser le lien unpkg ou l'importer directement dans un gestionnaire de paquets.

Remarque sur l'accessibilité

Bien que l'API de positionnement des ancres permette de positionner un élément par rapport à d'autres, elle ne crée pas intrinsèquement de relation sémantique significative entre eux. S'il existe une relation sémantique entre l'élément d'ancrage et l'élément positionné (par exemple, l'élément positionné est un commentaire dans la barre latérale concernant le texte d'ancrage), vous pouvez utiliser aria-details pour pointer de l'élément d'ancrage vers les éléments positionnés. Les logiciels de lecteur d'écran apprennent encore à gérer aria-details, mais la compatibilité s'améliore.

<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 vous utilisez le positionnement de l'ancre avec l'attribut popover ou un élément <dialog>, le navigateur gère les corrections de navigation du focus pour une accessibilité correcte. Vous n'avez donc pas besoin d'organiser vos pop-ups ou boîtes de dialogue dans l'ordre DOM. Pour en savoir plus, consultez la note sur l'accessibilité dans la spécification.

Conclusion

Il s'agit d'une toute nouvelle fonctionnalité, et nous avons hâte de découvrir ce que vous allez créer avec elle. Jusqu'à présent, la communauté nous a proposé des cas d'utilisation très intéressants, comme les libellés dynamiques dans les graphiques, les lignes de connexion, les notes de bas de page et les renvois visuels. Nous serions ravis de recevoir vos commentaires pendant que vous testez le positionnement des ancres. Si vous rencontrez des bugs, n'hésitez pas à nous en faire part.

Documentation complémentaire