position propose quatre valeurs classiques, mais une cinquième s'est ajoutée plus tard : sticky. Elle promet le meilleur des deux mondes, un élément qui suit la page normalement puis se fige au bon moment, comme un titre de section qui reste visible pendant qu'on lit le contenu qui le suit.
C'est aussi l'une des propriétés CSS les plus frustrantes à déboguer, parce qu'elle semble parfois ne rien faire du tout, sans qu'aucune erreur ne s'affiche nulle part pour expliquer pourquoi.
Définition
position: sticky est un hybride entre relative et fixed. L'élément se comporte normalement, comme en relative, jusqu'à ce que le défilement de la page atteigne le seuil fixé par top, bottom, left ou right. À cet instant précis, il se fige à cette position, comme le ferait un élément en fixed, mais seulement à l'intérieur des limites de son conteneur parent.
Syntaxe minimale
.titre-section {
position: sticky;
top: 0;
background-color: white;
}Le décalage n'est pas optionnel : sans top, bottom, left ou right, le navigateur n'a aucun seuil à surveiller, et l'élément se comporte comme un simple relative, sans jamais se figer. top: 0 est de loin le cas le plus fréquent : l'élément se colle au bord supérieur de la zone de défilement.
Le piège classique : overflow ou une hauteur contrainte sur un parent
sticky ne fonctionne qu'à l'intérieur de son plus proche ancêtre qui défile. Si un seul parent, entre l'élément et cette zone de défilement, porte un overflow en hidden, auto ou scroll, ou une hauteur fixe plus petite que son contenu, le navigateur considère que c'est ce parent la nouvelle zone de référence, et l'effet sticky disparaît, silencieusement, sans avertissement dans la console.
/* Ce parent casse le sticky de son enfant */
.conteneur {
overflow: hidden;
}
.titre-section {
position: sticky;
top: 0;
}Le correctif consiste presque toujours à retirer cet overflow du parent concerné, ou à le déplacer plus haut dans l'arborescence, à un niveau où il ne coupe plus le chemin de l'élément sticky vers sa vraie zone de défilement.
Cas d'usage courants
On retrouve sticky sur un en-tête de tableau qui reste visible pendant le défilement d'une longue liste, sur un sommaire qui accompagne la lecture d'un article, ou sur les titres de groupe d'une liste de contacts classée par lettre, qui se remplacent les uns les autres au fil du défilement. Dans les trois cas, la valeur associée à z-index compte aussi : sans elle, l'élément figé peut se retrouver sous le contenu qui défile par dessus, un défaut discret qui donne l'impression que le texte passe devant le titre au lieu de rester en dessous.
Questions fréquentes
Mon élément sticky ne se fige jamais, que vérifier en premier ?
Trois causes couvrent la majorité des cas : l'absence d'un décalage comme top, un parent avec un overflow différent de visible quelque part entre l'élément et la fenêtre, ou un conteneur dont la hauteur est trop courte pour laisser de la place au défilement à l'intérieur duquel l'élément pourrait se figer.
sticky sort-il l'élément du flux normal comme absolute ?
Non, et c'est justement ce qui le rend pratique. L'élément garde sa place réservée dans la mise en page tant qu'il n'est pas figé, contrairement à un élément en absolute qui quitte le flux dès le départ. C'est ce comportement en deux temps qui fait de sticky un hybride plutôt qu'une simple variante de fixed.
Peut-on utiliser sticky avec top et bottom en même temps ?
Oui, et c'est utile dans un conteneur qui défile lui-même : l'élément se fige alors en haut pendant la descente, puis, si l'espace disponible se réduit, il peut se recoller au bas de son conteneur au lieu de sortir de la zone visible. Ce cas reste rare en pratique, réservé aux zones de défilement internes assez hautes.