Lorsque vous placez un info-bulle ou un menu déroulant, vous souhaitez souvent le positionner par rapport à un autre élément de la page. Bien qu'il existe des méthodes utilisant le positionnement absolu pour obtenir cet effet, les exigences plus complexes ont historiquement recours au positionnement des éléments à l'aide de JavaScript.
Le positionnement d'ancrage CSS permet de positionner de manière déclarative un élément par rapport à un autre.
Éléments d'attache
Pour qu'un élément devienne une ancre, attribuez-lui une valeur anchor-name
correspondant à une chaîne commençant par deux tirets. Il s'agit de l'identifiant que l'élément positionné utilisera pour trouver son ancrage. Il est utile de lui donner un nom descriptif. Vous pouvez même attribuer plusieurs noms d'ancres à un élément s'il doit être utilisé comme ancre de différentes manières.
Vous devrez définir quelques propriétés sur l'élément positionné pour qu'il puisse être rattaché. Tout d'abord, vous devez extraire l'élément du flux du document pour qu'il flotte, en définissant position: absolute
ou position: fixed
.
Ensuite, vous devrez définir l'ancrage auquel vous souhaitez vous attacher en définissant position-anchor
sur le nom d'ancrage que vous avez défini sur l'ancrage.
Enfin, vous devez définir la position de l'ancrage. Vous en saurez plus sur position-area
plus loin dans ce module.
#anchor {
anchor-name: --my-anchor;
}
#positionedElement {
position: absolute;
position-anchor: --my-anchor;
position-area: end;
}
Attaches implicites
Les popovers sont encore plus simples à ancrer. Lorsque vous ouvrez un popover à l'aide d'un bouton avec un popovertarget
ou en définissant un source
avec showPopover({source})
, le popover a déjà une "ancre implicite" définie. Étant donné qu'un pop-over est déjà flottant avec position: fixed
par défaut, il vous suffit de définir la position pour le positionner.
#anchor{}
#positionedElement {
position-area: end;
margin: unset;
}
Définir le champ d'application des ancres potentielles
Vous pouvez implémenter le positionnement d'ancrage dans un composant afin d'utiliser un modèle tel qu'un menu déroulant à plusieurs endroits. Si vous utilisez le même anchor-name
plusieurs fois, comment vous assurez-vous que chaque élément positionné trouve le bon ancrage ?
Les solutions JavaScript consistent à ajouter des ID uniques à chaque ancre, puis à y faire référence à partir de l'élément positionné. Cette méthode devient vite fastidieuse. CSS propose une solution plus simple avec anchor-scope
.
La propriété anchor-scope
définit les noms d'ancres qui ne seront mis en correspondance qu'entre un élément et ses descendants. Il accepte une liste d'un ou plusieurs noms d'ancres ou le mot clé all
pour limiter le champ d'application de tous les noms d'ancres définis.
Un anchor-scope
est idéalement ajouté à un ancêtre de l'élément positionné et de l'élément d'ancrage qui ne contient pas d'autres éléments d'ancrage portant le même nom. Il s'agit souvent de la racine du composant réutilisable.
L'exemple suivant montre la différence que anchor-scope
fait lorsqu'il est appliqué à des éléments répétés avec le même anchor-name
. Dans l'exemple, tous les éléments <img>
et les bannières d'images font référence au nom d'ancrage --image
. Lorsque anchor-scope
est appliqué aux éléments <li>
, position-anchor: --image
ne correspond qu'à l'élément <img>
du même élément <li>
que la bannière. Sinon, il correspond au dernier <img>
affiché.
Positionnement
Maintenant que vous avez ancré l'élément à votre ancre, il est temps de le positionner. Le positionnement d'ancrage propose deux méthodes de positionnement : position-area
et la fonction anchor()
.
position-area
La propriété position-area
vous permet de positionner un élément autour de l'ancrage en spécifiant un ou deux mots clés. Cela couvre de nombreux cas d'utilisation courants et constitue souvent un bon point de départ.
Fonctionnement de position-area
position-area
fonctionne en créant un bloc de contenu pour l'élément positionné dans une zone générée par les bords de l'ancre et le bloc de contenu d'origine de l'élément positionné.
Bien qu'il existe de nombreux mots clés pour position-area
, ils peuvent être répartis en quelques catégories pour les rendre plus compréhensibles. Anchor-tool.com est un excellent outil pour explorer la syntaxe.
Mots clés physiques
Vous pouvez utiliser les mots clés physiques top
, left
, bottom
, right
et center
. Par exemple, position-area: top right
placera l'élément positionné au-dessus et à droite de l'ancrage. Ces mots clés ont également des équivalents pour les axes physiques : y-start
, x-start
, y-end
et x-end
.
Mots clés logiques
Vous pouvez également utiliser les mots clés logiques block-start
, block-end
, inline-start
et inline-end
. Par exemple, position-area: block-end inline-start
placera l'élément positionné sous et à gauche de l'ancrage dans les langues comme l'anglais, ou après l'ancrage sur l'axe de bloc et avant l'ancrage sur l'axe en ligne dans le mode d'écriture du document. center
peut également être utilisé avec un mot clé logique.
Vous pouvez également omettre l'axe si vous spécifiez des mots clés logiques, avec l'axe de bloc en premier et l'axe en ligne en second. position-area: start end
est identique à position-area: block-start inline-end
ou même à position-area: inline-end block-start
.
S'étendre sur plusieurs zones de grille
Jusqu'à présent, vous avez peut-être remarqué que ces options ne vous permettent de placer l'élément positionné que dans un seul espace de grille. L'ajout du préfixe span
aux propriétés physiques ou logiques ajoute l'espace de grille central adjacent. position-area: span-top right
sera positionné à droite de l'ancrage, et du bas de l'ancrage au haut du bloc de contenu d'origine de l'élément positionné.
position-area: block-end span-inline-end
est une zone de position courante pour un menu déroulant.
Le mot clé span-all
s'étend sur trois lignes ou colonnes.
Mot clé unique
Si vous ne définissez qu'un seul mot clé, l'autre axe est défini automatiquement. Cette fonctionnalité fonctionne en grande partie comme vous l'attendez, mais il peut être utile de comprendre comment elle fonctionne.
Si le mot clé fourni est clair concernant son axe, l'autre axe est calculé comme span-all
. Cela signifie que position-area: bottom
équivaut à position-area: bottom span-all
. L'élément positionné se trouvera sous l'ancrage et disposera de toute la largeur du bloc de contenu.
En revanche, si le mot clé n'indique pas clairement un axe, il est répété. position-area: start
équivaut à start start
et est placé en haut à gauche de l'ancrage dans les langues qui se lisent de gauche à droite.
Fonction anchor()
Pour les cas d'utilisation plus avancés, position-area
peut ne pas répondre à vos besoins. La fonction anchor()
vous permet de définir des propriétés d'encart individuelles en fonction de la position d'un autre élément. Cela correspond à une longueur CSS, ce qui signifie que vous pouvez l'utiliser dans des calculs et avec d'autres fonctions CSS. Vous pouvez également attacher différents côtés à différentes ancres.
La fonction anchor()
prend un nom d'ancrage et un côté d'ancrage. Si votre élément possède une ancre par défaut, définie avec position-anchor
ou implicitement, par exemple avec un pop-up, vous pouvez omettre le nom de l'ancre.
.positionedElement {
block-start: anchor(--my-anchor start);
/* OR */
position-anchor: --my-anchor;
block-start: anchor(start);
}
Valeurs de remplacement
Si aucune ancre n'est trouvée pour une fonction anchor()
, l'intégralité de la déclaration ne sera pas valide. Cela peut se produire si l'ancrage est affiché après l'élément positionné ou s'il n'existe pas d'élément avec un anchor-name
correspondant. Pour gérer ce problème, vous pouvez définir une durée ou un pourcentage de remplacement.
.positionedElement {
block-start: anchor(--my-anchor, 100px)
}
Dans l'exemple précédent, la valeur de gauche de l'élément positionné est ancrée à --focused-anchor
, mais ce anchor-name
n'existe que lorsque le premier bouton est pointé ou sélectionné. Étant donné qu'une fonction anchor()
est résolue en longueur, vous pouvez utiliser une autre ancre comme solution de repli. Si nous n'avions pas fourni de remplacement, l'élément positionné ne le serait pas.
Mots clés côté ancre
La valeur du côté d'ancrage choisit le bord de l'ancrage à positionner. Comme pour position-area
, la valeur du côté d'ancrage accepte plusieurs types de syntaxe.
Type | Valeurs | Description |
---|---|---|
Physique | top , left , bottom , right |
Les mots clés physiques correspondent à un côté spécifique de l'ancrage, mais ne peuvent être utilisés que sur le même axe que l'encart de l'élément positionné que vous définissez. Par exemple, |
Côté | inside , outside |
Le mot clé Par exemple, |
Logique | start , end , self-start , self-end |
Les mots clés logiques font référence aux côtés de l'ancrage en fonction du mode d'écriture de l'élément positionné avec |
Pourcentage | 0 % à 100 % |
Une valeur de pourcentage place l'élément positionné le long de l'axe, du début à la fin de l'ancrage sur l'axe spécifié. |
Cet exemple montre comment une valeur de pourcentage va toujours du début à la fin sur l'axe spécifié :
Utiliser anchor()
Comme anchor()
est une longueur, il est très flexible. Vous pouvez manipuler la valeur avec des fonctions CSS telles que max()
et calc()
.
Une limite est que vous ne pouvez utiliser les fonctions anchor()
que sur les propriétés d'encart.
L'exemple précédent ajoute un arrière-plan derrière le panneau de détails ouvert, qui s'anime en douceur lorsqu'un autre panneau est ouvert et s'étend pour inclure un panneau de détails sur lequel le curseur est placé. Pour ce faire, il utilise min()
pour choisir la longueur la plus petite entre deux ancres.
#indicator{
/* Use the smaller of the 2 values: */
inset-block-start: min(
/* 1. The start side of the default anchor, which is the open `<details>` element */
anchor(start),
/* 2. The start side of the hovered `<details>` element. */
anchor(--hovered start,
/* If no `<details>` element is hovered, this falls back to infinity px, so that the other value is smaller, and therefore used. */
var(calc(1px * infinity)))
);
}
L'exemple utilise également calc()
pour ajouter un espace intégré autour du panneau ouvert.
Utiliser la taille de l'ancrage
Vous pouvez également utiliser la fonction anchor-size()
pour utiliser les dimensions de l'ancrage pour la taille, la position ou la marge de votre élément positionné.
anchor-size()
accepte un nom d'ancrage ou utilise l'ancrage par défaut. Par défaut, il utilise la taille de l'ancrage sur l'axe sur lequel il est utilisé. Par conséquent, width: anchor-size()
renvoie la largeur de l'ancrage. Vous pouvez également utiliser l'autre axe en spécifiant la longueur souhaitée, avec les mots clés physiques width
et height
ou les mots clés logiques block
, inline
, self-block
et self-inline
.
Gérer le dépassement
Vous avez créé un composant de menu déroulant et utilisé le positionnement d'ancrage pour le placer où vous le souhaitez. Mais ensuite, vous déplacez le menu de l'autre côté de l'écran ou vous l'utilisez pour un menu utilisateur, et le nom de l'utilisateur est très long. Soudain, votre menu déroulant disparaît de l'écran. Et maintenant ?
Le positionnement d'ancres CSS dispose d'un système intégré qui vous permet de créer rapidement un ensemble robuste de solutions de secours lorsque votre élément positionné se retrouve en dehors de son bloc de conteneur.
Options de remplacement
La règle position-try-fallbacks
accepte une liste d'options de remplacement. Lorsque la position par défaut déborde, chaque option est essayée dans l'ordre jusqu'à ce qu'une position ne déborde pas.
Vous pouvez utiliser n'importe quelle valeur position-area
comme option de remplacement. Dans cet exemple, dans les modes d'écriture de gauche à droite comme l'anglais, l'élément positionné tentera d'être positionné en bas de l'ancrage, en s'étendant sur les colonnes du centre et de droite. Si le contenu dépasse, il tentera de se positionner en bas de l'ancrage, en s'étendant sur les colonnes de gauche et du centre. Si le contenu déborde également, la position revient à la position par défaut, même si elle déborde.
.positioned-element {
position-area: block-end span-inline-end;
position-try-fallbacks: block-end span-inline-start;
}
Il existe également plusieurs mots clés flip-
qui gèrent les cas de remplacement courants. flip-block
et flip-inline
essaient d'inverser l'élément sur les axes de bloc et en ligne. Ils peuvent également être combinés avec flip-block flip-inline
pour inverser les deux axes. La valeur flip-start
inverse l'élément positionné par rapport à une ligne diagonale allant des coins de début à ceux de fin de l'ancrage.
Vous pouvez également créer une option de secours personnalisée avec @position-try
. Cela vous permet de définir les marges et l'alignement, et même de modifier l'ancrage.
@position-try --menu-below {
position-area: bottom span-right;
margin-top: 1em;
}
#positioned-element {
position-try: --menu-below;
}
flip-block
et flip-inline
peuvent être ajoutés aux options de remplacement @position-try
pour créer une variante.
#positioned-element {
position-try: --menu-below, flip-inline --menu-below;
}
Dans l'exemple précédent, le navigateur suit ces étapes et s'arrête dès qu'il trouve une solution qui ne provoque pas de dépassement.
- L'élément est placé avec
position-area: end
, en bas à droite de l'ancrage. - Si le contenu dépasse la taille de l'élément, celui-ci est placé avec l'option de remplacement personnalisée nommée
--bottom-span-right
, qui le place avecposition-area: bottom span-right
, avec une marge supplémentaire en dessous. - Si le contenu dépasse la taille de l'élément, celui-ci est placé avec
flip-inline --bottom-span-right
, qui combine l'option de remplacement personnalisée avecflip-inline
, qui est essentiellementposition-area: bottom span-left
. - Si le contenu dépasse la limite, l'élément est placé à l'aide de l'option de remplacement personnalisée
--use-alternate
, qui le place sous une ancre complètement différente. - Si le contenu déborde, l'élément revient à son emplacement d'origine, avec
position-area: end
, même si l'on sait que le contenu déborde.
Ordre de remplacement
Par défaut, lorsque la position initiale déborde, le navigateur essaie chaque option de position-try-fallbacks
jusqu'à ce qu'il trouve une position qui ne déborde pas. Vous pouvez ignorer ce comportement avec position-try-order
pour tester chaque option de remplacement et utiliser celle qui offre le plus d'espace sur un axe spécifié.
Vous pouvez spécifier l'axe à l'aide des mots clés logiques most-block-size
et most-inline-size
, ou des mots clés physiques most-height
et most-width
.
position-try-order
et position-try-fallbacks
peuvent être combinés avec le raccourci position-try
, en commençant par l'ordre.
Défilement
Lorsqu'un utilisateur fait défiler une page, il s'attend à ce qu'elle se déplace de manière fluide. Pour ce faire, les navigateurs limitent l'utilisation du positionnement d'ancrage lors du défilement.
Bien que vous puissiez associer un élément positionné à des ancres dans différents conteneurs de défilement, l'élément ne se déplacera qu'en réponse au défilement de l'une des ancres. Il s'agit de l'ancrage par défaut, qui est soit l'ancrage implicite d'un pop-over, soit la valeur de position-anchor
.
Vous remarquerez que l'élément positionné reste visible même lorsque l'ancrage n'est plus visible. Pour masquer l'élément positionné lorsque l'ancrage est masqué, définissez position-visibility: anchors-visible
. Cela s'applique non seulement lorsque l'ancrage est défilé au-delà de la limite, mais aussi s'il est masqué d'une autre manière, par exemple avec visibility: hidden
.
Vérifier que vous avez bien compris
Quelles sont les valeurs valides pour le côté dans anchor()
?
inside
25%
25px
25px
puisse être utilisée comme valeur de remplacement, seuls les pourcentages peuvent être utilisés pour le côté.block-start
start
Quelles sont les valeurs valides pour position-area
?
top
block-end inline-end
block-start block-end
Quelles propriétés sont compatibles avec la fonction anchor()
?
top
margin-left
inset-block-start
transform
Que se passe-t-il si plusieurs ancres ont le même anchor-name
?