z-index en CSS : le chiffre qui ne sert à rien sans position

z-index règle l'ordre d'empilement des éléments qui se chevauchent, mais reste totalement sans effet tant que l'élément garde sa position par défaut.
4 min de lecture
Believemy logo

Deux éléments se superposent à l'écran, et l'un d'eux reste obstinément derrière l'autre alors qu'on lui a pourtant réglé un z-index de 999. Ce scénario est probablement le bug CSS le plus reproduit sur les forums, et il a presque toujours la même explication.

z-index règle l'ordre d'empilement des éléments qui se chevauchent visuellement, mais il obéit à une condition d'entrée que presque personne ne connaît la première fois qu'il s'en sert.


Définition

z-index détermine quel élément apparaît devant un autre lorsque deux boîtes se superposent visuellement. Sa valeur est un nombre entier, sans unité : plus il est élevé, plus l'élément passe devant ses concurrents placés au même niveau. Une valeur négative est autorisée et fait passer l'élément derrière ses voisins, y compris derrière l'arrière-plan de son propre parent.


Le piège : sans position, z-index ne sert à rien

Bon à savoir

z-index n'a strictement aucun effet sur un élément dont la position vaut static, sa valeur par défaut. La propriété reste ignorée par le navigateur, sans le moindre message d'erreur, ce qui rend le bug particulièrement difficile à repérer pour qui découvre CSS.

CSS
/* Sans effet : position est resté static */
.popup {
  z-index: 999;
}

/* Fonctionne : position sort du défaut */
.popup {
  position: relative;
  z-index: 999;
}

Ajouter position: relative, absolute, fixed ou sticky suffit à débloquer z-index, même quand aucun décalage comme top ou left n'est nécessaire par ailleurs. Notre formation HTML et CSS revient sur ce réflexe dès les premiers exercices de mise en page, pour ne plus jamais tomber dans ce piège.


Le contexte d'empilement

Comparer deux valeurs de z-index ne fonctionne que si les deux éléments appartiennent au même contexte d'empilement, un terme technique qui désigne simplement un groupe d'éléments empilés ensemble, comme une mini-scène de théâtre avec ses propres coulisses. Certaines propriétés, comme une opacity inférieure à 1 ou un transform, créent un nouveau contexte d'empilement à leur insu : un enfant avec un z-index énorme peut alors rester coincé derrière un élément externe portant un z-index pourtant plus faible, simplement parce qu'il appartient à un groupe différent.


Exemple concret : une infobulle qui passe sous le contenu

CSS
.carte {
  position: relative;
  z-index: 1;
}

.infobulle {
  position: absolute;
  top: 100%;
  z-index: 10;
}

Ici, l'infobulle passe devant sa carte parente sans difficulté, parce que les deux éléments partagent le même contexte d'empilement. Le problème n'apparaît que si une autre carte, ailleurs sur la page, porte elle aussi un z-index élevé sur son propre conteneur : la comparaison se joue alors entre les conteneurs, pas entre l'infobulle et le reste de la page.


Bonne pratique : une échelle de valeurs plutôt que des nombres au hasard

Sur un projet qui grossit, empiler des z-index: 9999 les uns après les autres finit toujours par créer une course à l'échalote où plus personne ne sait quel élément doit vraiment passer devant quel autre, ni pourquoi une valeur précise a été choisie plutôt qu'une autre. Une échelle fixée à l'avance, avec des paliers larges entre chaque catégorie, évite ce problème et documente l'intention en même temps que le code.

UsagePalier suggéré
Contenu normal, cartes qui se chevauchent légèrement1 à 10
En-tête ou barre de navigation collée en haut100
Menu déroulant, infobulle500
Fenêtre modale, superposition plein écran1000


Questions fréquentes

Question

J'ai mis z-index: 9999 et ça ne change toujours rien, pourquoi ?

Le premier réflexe est de vérifier la position de l'élément : sans une valeur différente de static, z-index reste inactif quelle que soit son ampleur. Augmenter le chiffre à l'infini ne corrige jamais ce problème précis, seule la propriété position le peut.


Question

Peut-on utiliser un z-index négatif ?

Oui, et c'est une technique courante pour placer un élément décoratif juste derrière son parent, par exemple un dégradé de fond qui déborde légèrement d'une carte. Un z-index négatif fait passer l'élément derrière tout ce qui se trouve dans le même contexte d'empilement, arrière-plan du parent compris.


Question

Pourquoi mon enfant reste-t-il sous un élément qui a un z-index plus petit ?

Parce qu'un ancêtre a probablement créé un nouveau contexte d'empilement sans qu'on l'ait décidé, souvent avec une opacity inférieure à 1, un transform ou un filter. Le z-index de l'enfant ne se compare alors plus qu'aux autres éléments de ce même groupe, jamais directement à des éléments extérieurs.

Termes connexes

Découvrez notre glossaire HTML et CSS

Parcourez les termes et définitions les plus couramment utilisés dans le domaine du développement HTML et CSS.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.