Le merdier du “stacking context” en CSS (aka “pourquoi mon z-index marche pas bordel de merde” ?)

C’est une règle en CSS que beaucoup de designers connaissent, mais la première fois qu’on s’y frotte on se sent très con: on ne peut pas appliquer z-index à un élément dont le parent possède déjà un “stacking context”.

Ce n’est pas un bug, c’est comme ça que c’est supposé fonctionner.

Qu’est-ce qu’un “stacking context” ?

On appelle “stacking context” l’état d’un élément que le navigateur garde en mémoire pour effectuer le rendu de cet élément dans la page. Le “stacking context” dit si l’élément doit être devant ou derrière chaque autre élément se superposant à l’écran avec lui.

Chaque fois que vous utilisez une propriété comme z-index, opacity ou transform sur un élément dans un fichier CSS, le navigateur recalcule le “stacking context” pour savoir si il met maintenant cet élément devant ou derrière les autres à la même position que lui.

Et du coup, j’ai pas compris le début, c’est quoi déjà le problème ?

Si vous faites un truc qui change le “stacking context” d’un élément, vous ne pouvez appliquer z-index sur aucun de ses enfants.

Ainsi si vous avez un HTML comme ça:

<p class="parent">
    <span class="child">Truc</span>
</p>

Et que vous faites ça dans votre CSS:

.parent {
    z-index: 1;
    opacity: 0.5;
    transform: rotate(5deg);
}
 
.child {
    z-index: -1;
}

La dernière règle n’aura aucun effet.

Donc si vous vous acharnez sur F5 parce qu’un z-index semble ne pas marcher quelque part, vous savez maintenant qu’il faut juste remonter la chaîne de tous les parents de cet élément pour voir si vous avez pas à un moment changé le “stacking context” de l’un d’entre eux.

No related posts.

flattr this!

10 comments

  1. Moi je préfère le viol de toutes conventions établies a coup de “!important”

    Si toutes mes règles sont importantes, je me sens important.
    Vive le CSS

  2. C’est très clair en effet… et finalement très logique ^^
    @anon: +1

  3. Toujours bon à savoir o/

  4. MatTheCat

    Dans l’exemple la règle n’aura aucun effet parce que z-index n’agit que sur les éléments positionnés (dont la propriété position vaut autre chose que static).
    Et sur un élément positionné, z-index est relatif à la pile établie par le premier parent positionné : http://www.w3.org/TR/CSS2/visuren.html#z-index

    Donc si, z-index a un effet même sur un élément dont le parent a aussi un z-index.

  5. Ok mon exemple est tout pourri. Celui-ci est mieux foutu: http://css-discuss.incutio.com/wiki/Overlapping_And_ZIndex

  6. MatTheCat

    Ah en fait ce que vous voulez mettre en avant c’est le fait que z-index n’a d’effet sur l’élément que dans la pile à laquelle il appartient (sauf exception !) ?
    Honnêtement je n’ai pas compris ça en lisant l’article =/

  7. Ouai, on sent que mon expertise est bien moindre en front end, mes articles sont beaucoup plus approximatif. Bah, c’est pas grâve, y toujours quelqu’un pour donner tous les détails en comment.

  8. @MatTheCat +0.5

    Si ton .child est en position:relative (ou absolute, fixed), alors ça marche (suffit de tester avec des background semi-transparents).

    Donc si, z-index a un effet même sur un élément dont le parent a aussi un z-index.

    Tout dépend : si .child et .parent ont chacun des position:relative, alors là le .child ne pourra pas se placer sous le .parent.

    Donc en gros, si le .parent a un position:relative, alors le z-index du .child n’a d’effets que sur les autres .child (donc les éléments frères et sœurs, si vous voulez).

    z-index n’a d’effet sur l’élément que dans la pile à laquelle il appartient

    C’est bien ça, si la pile possède un position différent de static.

  9. Merci pour ces compléments d’information à tous les deux. C’est très utile.

  10. En fait c’est un sacre bordel et j’y vais aussi de mon lien, qui m’avait aide a mieux comprendre (mais en anglais):
    https://developer.mozilla.org/en-US/docs/CSS/Understanding_z-index

Flux RSS des commentaires

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">

Jouer à mario en attendant que les autres répondent