Optimiser vos tooltips et dropdowns avec Absolute CSS positioning

On a tous déjà vu un tooltip qui disparaît sous un conteneur scrollable, ou un dropdown qui pousse tout le layout au lieu de flotter proprement au-dessus. Le problème vient presque toujours du même endroit : un position: absolute mal ancré dans le DOM. Avant de chercher une librairie JS, on peut résoudre la majorité de ces cas avec quelques règles CSS précises, à condition de comprendre comment le navigateur calcule le positionnement.

Le piège du contexte de positionnement sur les tooltips CSS

Quand on déclare position: absolute sur un tooltip, le navigateur ne le place pas par rapport à son parent direct. Il remonte le DOM jusqu’à trouver le premier ancêtre ayant un position autre que static (relative, absolute, fixed, sticky). C’est ce qu’on appelle le containing block.

A découvrir également : Optimiser son site Web pour devenir une application mobile : conseils et astuces

Si aucun ancêtre n’a de position déclarée, le tooltip se cale sur le viewport. Le résultat : un élément qui apparaît à des centaines de pixels de l’endroit prévu.

La solution opérationnelle est simple. On place position: relative sur l’élément parent direct du tooltip, sans lui donner de décalage (pas de top, left, etc.). Ce parent devient le référentiel de calcul sans bouger d’un pixel dans le flux.

A lire en complément : Astuces clés pour réussir vos paris en ligne sur Counter Strike 2

  • Le parent déclencheur (bouton, lien, icône) reçoit position: relative pour servir d’ancre
  • Le tooltip enfant reçoit position: absolute avec des valeurs bottom: 100% ou top: 100% selon la direction souhaitée
  • Un left: 50% combiné à transform: translateX(-50%) centre le tooltip horizontalement sans recourir à des marges négatives fixes
  • Le z-index du tooltip doit être suffisamment élevé pour passer au-dessus des éléments voisins, mais attention : un nouveau stacking context créé par un ancêtre (via transform, opacity inférieure à 1, ou filter) peut annuler ce z-index

L’erreur fréquente que l’on rencontre sur les forums (Stack Overflow inclus) consiste à utiliser une marge négative fixe, par exemple margin-left: -60px, pour centrer le tooltip. Ça fonctionne uniquement si le tooltip fait exactement 120 px de large. Dès que le texte change, le centrage est cassé. La méthode translate est indépendante de la largeur du contenu.

Designer UX analysant le positionnement absolu CSS pour des menus déroulants sur son laptop en open space

Les dropdowns posent un problème que les tooltips rencontrent moins souvent : ils contiennent une liste d’options parfois longue, et leur conteneur parent a souvent un overflow: hidden ou overflow: auto. Dans ce cas, le dropdown est purement et simplement tronqué par le conteneur.

On a deux stratégies concrètes pour y répondre.

Rester dans le flux avec overflow visible

Si on maîtrise la chaîne de conteneurs, on peut remonter et s’assurer qu’aucun ancêtre entre le dropdown et le body n’a d’overflow: hidden. C’est la solution la plus propre quand c’est possible, mais dans un composant intégré à un layout complexe (modale, sidebar scrollable, widget embarqué), on n’a pas toujours la main.

Passer en position fixed pour les cas critiques

L’alternative consiste à basculer le dropdown en position: fixed et à recalculer ses coordonnées par rapport au viewport via getBoundingClientRect() en JavaScript. C’est d’ailleurs ce que font les librairies comme Popper.js en interne. Fixed sort l’élément de tout contexte de positionnement, y compris des conteneurs avec overflow.

Les retours varient sur ce point : dans des cas simples (un formulaire pleine page, par exemple), rester en absolute avec un conteneur bien configuré suffit largement. Le passage en fixed n’a de sens que quand la hiérarchie DOM impose un clipping impossible à contourner autrement.

Stacking contexts et z-index : pourquoi le dropdown passe sous un autre élément

Un dropdown correctement positionné en absolute peut quand même apparaître sous un composant voisin. Le réflexe est de monter le z-index. Ça ne résout rien si le problème vient d’un stacking context isolé créé par un ancêtre.

Plusieurs propriétés CSS créent un nouveau stacking context sans qu’on s’en rende compte :

  • transform (même transform: none dans certains navigateurs historiques)
  • opacity inférieure à 1
  • filter, backdrop-filter
  • will-change quand il cible transform ou opacity
  • contain: paint ou contain: layout

Dans un stacking context, le z-index ne rivalise qu’avec les autres éléments du même contexte. Un z-index: 9999 sur le dropdown ne vaut rien si son ancêtre a un stacking context avec un z-index de 1, et que l’élément voisin est dans un contexte de niveau supérieur.

Le diagnostic terrain : ouvrir l’inspecteur du navigateur, sélectionner le dropdown, puis remonter chaque ancêtre pour vérifier lequel crée un stacking context. Dans Chrome DevTools, l’onglet « Layers » aide à repérer ces contextes. Une fois identifié, soit on supprime la propriété responsable sur l’ancêtre, soit on déplace le dropdown plus haut dans le DOM (technique du « portal » en React ou Vue).

Mains de développeur sur laptop affichant du code CSS de positionnement absolu pour tooltip dans un café

CSS Anchor Positioning : la piste qui remplace le calcul manuel

Depuis 2023-2024, une nouvelle spécification CSS appelée CSS Anchor Positioning commence à être prise en charge par Chrome et Edge. Le principe : on déclare un élément ancre avec anchor-name, puis on positionne le tooltip ou dropdown via la fonction anchor() directement dans le CSS.

Concrètement, un tooltip peut s’écrire avec quelque chose comme top: anchor(bottom) pour se placer juste sous son ancre, sans JavaScript, sans calcul de getBoundingClientRect, et sans se soucier du containing block. Le navigateur gère le positionnement, le retournement si l’espace manque, et l’ancrage au scroll.

Cette approche supprime la majorité de la logique manuelle décrite plus haut. Anchor Positioning rend le positionnement déclaratif plutôt que calculé. Pour un dropdown dans un conteneur scrollable, le navigateur recalcule automatiquement la position au scroll, ce que position: absolute seul ne fait pas.

La limite actuelle : le support navigateur reste partiel. Firefox et Safari n’implémentent pas encore la spécification de façon stable. Pour un projet en production qui doit tourner partout, on combine un fallback en absolute classique avec une détection de support via @supports. Mais pour des applications internes ou des interfaces ciblant Chromium, on peut déjà l’adopter.

Le positionnement absolu des tooltips et dropdowns reste un socle technique à maîtriser, même avec l’arrivée d’Anchor Positioning. Comprendre le containing block, les stacking contexts et les contraintes d’overflow permet de diagnostiquer rapidement les bugs d’affichage au lieu de empiler des z-index arbitraires. La prochaine fois qu’un tooltip apparaît au mauvais endroit, on inspecte l’ancêtre positionné avant de toucher au CSS du tooltip lui-même.