Positionner en CSS a souvent été une mission hasardeuse. Flexbox et Grid ont grandement simplifié la tâche, mais il reste des cas où le positionnement précis d'un élément par rapport à un autre demeure un véritable casse-tête. C'est là qu'intervient le positionnement par ancre (anchor positioning), une nouvelle fonctionnalité CSS qui permet de placer visuellement n'importe quel élément par rapport à n'importe quel autre élément, sans avoir à se soucier de la structure du DOM.
Le positionnement par ancre va se révéler particulièrement utile pour :
- Les info-bulles : afficher des informations supplémentaires lorsqu'on survole un élément.
- Les menus contextuels : ouvrir un menu à côté d'un bouton ou d'une zone spécifique.
- Les fenêtres modales : positionner un
dialog
(une modale) par rapport à un élément déclencheur. - Les étiquettes de formulaire : placer des messages d'erreur ou des indications près des champs concernés.
⚠️ Attention : une ancre et un élément positionné éloignés dans le DOM vont poser des problèmes d'accessibilité, avec les lecteurs d'écran en particulier.
Compatibilité navigateurs (et @supports
)
Voici le tableau de compatibilité pour le positionnement par ancre :

Afin de permettre un support progressif, activez anchor-positioning
via une détection de fonctionnalité @supports
et fournissez une alternative simple.
@supports (anchor-name: --a) {
/* ici les styles avec anchor-positioning */
}
Associer un élément à une ancre nommée
Le positionnement par ancre permet de lier un élément (appelé "élément positionné") à un autre élément (appelé "ancre") afin de positionner le premier relativement au second.
Pour définir une ancre, on se sert de la propriété anchor-name
:
.mon-ancre {
anchor-name: --nom-de-mon-ancre;
}
ℹ️ Notez la syntaxe spécifique de la valeur précédée d'un double trait d'union --
, nécessaire pour cette propriété.
Puis, pour associer un élément et le positionner par rapport à cette ancre, on utilise position-anchor
(sur un élément position: absolute|fixed
) :
.element-positionne {
position: absolute; /* ou fixed */
position-anchor: --nom-de-mon-ancre;
}
À présent, l'élément positionné est aligné par rapport à l'ancre définie. Nous allons à présent pouvoir le placer précisément (avec anchor()
ou position-area
), mais aussi gérer les débordements avec position-try
ou ses dimensions avec anchor-size()
.
ℹ️ Il est également possible d'associer un élément à une ancre à l'aide de l’attribut HTML anchor
(voir un peu plus bas).
anchor()
pour placer l'élément
La valeur-fonction anchor()
permet de placer l'élément par rapport aux bords de l'ancre :
.element-positionne {
position: absolute;
position-anchor: --nom-de-mon-ancre; /* association */
top: anchor(bottom); /* bord haut aligné sur le bas de l’ancre */
left: anchor(left); /* bord gauche aligné sur la gauche de l’ancre */
}
Différents types de valeurs peuvent être utilisés avec anchor()
:
- Côtés physiques :
top|right|bottom|left
. Côtés logiques :start|end|self-start|self-end|inside|outside|center
. - Compatible avec
calc()
:top: calc(anchor(bottom) + 10px)
. - Viser une autre ancre :
top: anchor(--autre-ancre bottom, 50%)
(2ᵉ valeur = fallback).
position-area
pour (aussi) placer l'élément
Alternative à anchor()
, la propriété position-area
place l’élément dans une grille 3×3 centrée sur l’ancre.
.infobox {
position: fixed;
position-anchor: --ancre;
position-area: top center; /* au-dessus, centré */
}
.toast {
position-area: bottom span-all;
} /* toute la rangée du bas */
ℹ️ L'excellente ressource en ligne Anchor Tool permet de visualiser et tester facilement les positions d'ancrage.
anchor-size()
pour définir la taille de l'élément
Cette propriété retourne une longueur basée sur la dimension de l’ancre et s'applique directement à l'élément associé.
Exemples :
.box {
width: anchor-size(width);
} /* largeur = largeur de l'ancre */
.tooltip {
margin-block-start: calc(anchor-size(height) / 4);
} /* marge = ¼ hauteur ancre */
position-try
pour gérer les débordements
Propriété raccourcie de position-try-order
et position-try-fallbacks
, la propriété position-try
permet de définir des options de repli appliquées automatiquement quand l’élément déborde (de la fenêtre ou du contenant).
Deux approches complémentaires :
- Mots-clés intégrés (
flip-inline
,flip-block
,top|right|bottom|left
, etc.). - Options personnalisées nommées via
@position-try --nom { … }
pouvant définirposition-area
, desanchor()
d’inset, margins, tailles,*-self: anchor-center
, etc.
Exemple 1 — fallbacks intégrés (sans @position-try
custom)
.tooltip {
/* Essaie d’abord de “miroiter” horizontalement (gauche<->droite) si ça déborde,
sinon tente en bas, puis en haut autour de l’ancre. */
position-try: flip-inline, bottom, top;
}
Exemple 2 — fallbacks custom via @position-try
/* Option custom : place la tooltip sous l’ancre avec un espace de 8px */
@position-try --try-bottom {
top: anchor(bottom);
margin-top: 8px;
}
/* Option custom : place la tooltip à gauche de l’ancre avec un espace de 8px */
@position-try --try-left {
position-area: left;
margin-right: 8px;
}
/* Choisit l’option maximisant la hauteur disponible :
on tente d’abord --try-left, puis --try-bottom si besoin. */
.tooltip {
position-try: most-height --try-left, --try-bottom;
}

Ancres multiples
Il est tout à fait possible d'associer plusieurs ancres à un même élément. Pour ce faire, affectez plusieurs noms d'ancre à l'élément.
.anchor {
anchor-name: --anchor1, --anchor2;
}
.element1 {
position-anchor: --anchor1;
left: anchor(--anchor1 left);
}
.element2 {
position-anchor: --anchor2;
left: anchor(--anchor2 right);
}
Exemple concret : une info-bulle (tooltip)
L’API Popover fournit une méthode simple pour créer un info-bulle et de la positionner à son ancre. Nous allons cette fois les associer via l’attribut HTML anchor
puis la positionner en CSS.
<button id="tooltip-button" popovertarget="tooltip" aria-describedby="tooltip">En savoir plus</button>
<div id="tooltip" popover anchor="tooltip-button" class="info-bulle">Je suis une info-bulle !</div>
.info-bulle[popover] {
margin: 0;
inset: auto;
}
.info-bulle {
position-area: right; /* à droite de l’ancre */
position-try: flip-inline, bottom, top; /* miroirs et repli */
max-inline-size: 28ch;
}
[popover]::backdrop {
background-color: hsl(0 0% 0% / 60%);
}

HTML vs CSS : quelle association choisir ?
Voici un comparatif rapide entre l’attribut HTML anchor
et la paire CSS anchor-name
+ position-anchor
.
Aspect | Attribut HTML anchor |
CSS anchor-name + position-anchor |
---|---|---|
Association | Déclarative dans le markup, sans CSS côté élément positionné | Définie côté CSS, via un nom d’ancre |
Multiples ancres | Une seule « default anchor » par élément | Autant de noms que nécessaire, y compris dynamiquement |
Lisibilité | Intention explicite dans le HTML, idéal avec Popover | Centralisation côté CSS, pratique pour thèmes/variantes |
Portée DOM | Indépendante de la hiérarchie (pas besoin de parent commun) | Idem (pas de contrainte DOM) |
Recommandations rapides :
- Utilisez l’attribut
anchor
quand vous contrôlez le code (ex. composants avec Popover). - Préférez la voie CSS quand vous avez des scénarios multi-ancres, des variantes de thème, ou peu d’accès au HTML.
En résumé global
Pour finir ce (long) tutoriel, voici un petit mémo pour retenir les étapes-clés de ce nouveau mode de positionnement :
- Associez un élément à son ancre via
anchor-name: --nom;
sur l’ancre etposition-anchor: --nom;
sur l’élément positionné (ou via l’attribut HTMLanchor="id-de-l-ancre"
) - Placez-le à votre guise avec
anchor()
ouposition-area
, - En bonus, attribuez des dimensions à l’élément positionné avec
anchor-size()
. - En bonus encore, gérez les débordements avec
position-try
(ou@position-try
pour des scénarios personnalisés)
Ressources
- MDN : CSS Anchor Positioning (overview)
- The Basics of Anchor Positioning (article complet en anglais)
- Anchoreum (jeu pour mieux comprendre ce positionnement)
- anchor-tool.com (pour comprendre les valeurs de
position-area
) - Anchor Positioning Polyfill ( (alternative JavaScript)
Commenter
Vous devez être inscrit et identifié pour utiliser cette fonction.
Connectez-vous (déjà inscrit)
Pas encore inscrit ? C'est très simple et gratuit.