Modifications d'empilement à venir dans position:fixed éléments

Tom Wiltzius
Tom Wiltzius

Dans Chrome 22, le comportement de mise en page des éléments position:fixed est légèrement différent de celui des versions précédentes. Tous les éléments position:fixed forment désormais de nouveaux contextes d'empilement. Cela modifiera l'ordre d'empilement de certaines pages, ce qui peut entraîner des problèmes de mise en page. Ce nouveau comportement correspond à celui des navigateurs WebKit sur les appareils mobiles (Safari iOS et Chrome pour Android).

Stacking Whats?

Tout le monde connaît et aime la z-index pour déterminer l'ordre de profondeur des éléments sur une page. Toutefois, tous les z-indexes ne sont pas égaux: la valeur z-index d'un élément ne détermine que son ordre par rapport aux autres éléments du même contexte d'empilement. La plupart des éléments d'une page se trouvent dans un seul contexte de superposition racine, mais les éléments positionnés de manière absolue ou relative avec des valeurs z-index non automatiques forment leurs propres contextes de superposition (c'est-à-dire que tous leurs enfants seront ordonnés selon l'axe Z dans le parent et ne seront pas entrelacés avec du contenu en dehors du parent). À partir de Chrome 22, les éléments position:fixed créeront également leurs propres contextes d'empilement.

Pour obtenir une présentation générale des contextes de superposition, consultez cet article MDN.

Comparez position:fixed à l'attribut new position:sticky: pour information, position:sticky crée toujours un nouveau contexte d'empilement.

Motivation

Les navigateurs mobiles (Safari mobile, navigateur Android, navigateurs basés sur Qt) placent les éléments position:fixed dans leurs propres contextes d'empilement depuis un certain temps (depuis iOS 5, Android Gingerbread, etc.), car cela permet certaines optimisations de défilement, ce qui rend les pages Web beaucoup plus réactives au toucher. Cette modification est appliquée sur ordinateur pour trois raisons:

  1. Un comportement de rendu différent sur les navigateurs "mobile" et "ordinateur" est un obstacle pour les auteurs Web. Le CSS doit fonctionner de la même manière partout, dans la mesure du possible.
  2. Avec les tablettes, il n'est pas clair lequel des algorithmes de création de contexte d'empilement "mobile" ou "ordinateur" est le plus approprié.
  3. L'optimisation des performances de défilement sur mobile pour le bureau est bénéfique pour les utilisateurs et les auteurs.

Détails de la modification

Voici un exemple illustrant les différents comportements de mise en page: https://codepen.io/paulirish/pen/CgAof

Avec ce changement, les deux versions s'afficheront comme la version de droite.

Dans cet exemple, le cadre vert contient un z-index: 1, le cadre rose un z-index: 3 et le cadre orange un z-index: 2. Le rectangle bleu est un ancêtre du rectangle orange et possède position:fixed.

Si le cadre bleu reçoit son propre contexte de superposition, la valeur z-index du cadre orange est calculée par rapport au contexte de superposition du cadre bleu. Étant donné que la zone bleue a un z-index de auto, ce qui lui donne un niveau d'empilement de zéro dans le contexte d'empilement racine, cela signifie que la zone orange se retrouve derrière les zones verte et rose, qui ont des indices Z de 1 et 3 (respectivement) dans le contexte racine.

Si le cadre bleu ne reçoit pas son propre contexte d'empilement, la valeur z-index du cadre orange est calculée par rapport au contexte d'empilement racine (avec les cadres vert et rose). Par conséquent, le rectangle orange se retrouve entrelacé avec les rectangles rose et vert.

Pour en savoir plus sur les critères de création de contextes empilables (et sur le comportement des contextes empilables en général), consultez à nouveau cet article MDN. Dans l'exemple, la version de droite a toujours attribué au cadre bleu son propre contexte d'empilement, car son opacité est inférieure à 1. Le changement de comportement apporté ajoute en fait un autre critère pour créer un contexte de superposition distinct, à savoir un élément position:fixed.

Tests et avenir

Pour tester si votre page va changer, accédez à about:flags dans Chrome et activez/désactivez "Les éléments en position fixe créent des contextes d'empilement". Si votre mise en page se comporte de la même manière dans les deux cas, vous êtes prêt. Si ce n'est pas le cas, assurez-vous que vous êtes satisfait de l'affichage avec ce flag activé, car il sera défini par défaut dans Chrome 22.

Cette modification supprime une fonctionnalité : la possibilité d'intercaler du contenu dans un sous-arbre position:fixed avec du contenu non déroulant de l'extérieur. Il est peu probable qu'un développeur Web fasse cela intentionnellement. Le même effet peut être obtenu en attribuant à plusieurs éléments position:fixed les différentes parties du DOM. Prenons deux exemples:

https://codepen.io/wiltzius/pen/gcjCk

Cette page tente de prendre deux divs enfants (overlayA et overlayB) d'un élément position:fixed et de placer l'un au-dessus d'une div de contenu distincte et l'autre en dessous de cette même div de contenu distincte. Il est désormais impossible de procéder de cette manière, car l'élément position:fixed est son propre contexte d'empilement, et il (ainsi que tous ses enfants) se trouvera entièrement au-dessus ou entièrement en dessous de la div de contenu. Notez que cet exemple fonctionne dans Chrome 21 et versions antérieures, mais plus dans Chrome 22.

Pour résoudre ce problème, vous pouvez diviser les deux superpositions en éléments position:fixed. Chacun d'eux est son propre contexte d'empilement, l'un pouvant se trouver au-dessus de la div de contenu et l'autre en dessous. Consultez l'exemple corrigé, qui fonctionne dans Chrome 21 et 22:

https://codepen.io/wiltzius/pen/vhFzG

La genèse de cet exemple revient à l'inimitable hixie.

Chrome est le premier navigateur pour ordinateur de bureau à permettre aux éléments position:fixed de créer leurs propres contextes d'empilement. La norme applicable est la spécification CSS de l'indice de zénith (voir par exemple https://www.w3.org/TR/CSS21/zindex.html). Il n'existe pas encore de consensus sur la façon de gérer la différence entre les navigateurs mobiles et les navigateurs de bureau. Toutefois, compte tenu de la confusion que génèrent deux comportements différents sur mobile et sur ordinateur, Chrome a choisi d'adopter ce comportement unique sur les deux plates-formes pour le moment.

Mise à jour le 1er octobre 2012:la version d'origine de cet article suggérait que la spécification CSS z-index avait déjà été modifiée pour refléter le nouveau comportement des éléments position: fixed. Cette information est inexacte. Elle a été discutée sur la liste de styles www, mais aucune modification n'a encore été apportée à la spécification.