Site icon Blog ARC Optimizer

Gestion de ZIndex dans une application Web basée sur des composants


À propos de l'auteur

Pavel Pomerantsev s'occupe de l'écriture de code et n'a que la compréhension la plus superficielle de la vie au-delà de la plate-forme Web. Vous pouvez trouver plus…
Pour en savoir plus sur Pavel

La propriété z-index malgré tout ce qui est écrit à ce sujet, est encore largement mal comprise et mal gérée. Les problèmes d'empilement dans une application Web complexe d'une seule page peuvent devenir un problème majeur. En adhérant à certains principes, cependant, nous pouvons facilement éviter ces problèmes.

Si vous avez déjà développé une interface utilisateur Web complexe, vous devez au moins avoir essayé de conduire avec fureur le [z-indexde] d'un élément jusqu'à des milliers, seulement pour voir que cela n'aide pas à le positionner au-dessus d'un autre élément, dont le z-index est inférieur ou même pas défini du tout.

Pourquoi cela se produit-il? Et plus important encore, comment éviter de tels problèmes?

Dans cet article, je vais récapituler ce que z-index est réellement et comment vous pouvez arrêter de deviner si cela pourrait fonctionner dans un cas spécifique et commencer à traiter

La ​​hiérarchie des contextes d'empilement

Si vous imaginez que la page Web a trois dimensions, alors z-index est une propriété qui définit le z [index]. coordonnée d'un élément (également appelée son "ordre d'empilement"): plus la valeur est grande, plus l'élément est proche de l'observateur. Vous pouvez également le considérer comme une propriété affectant l'ordre de la peinture. Ce sera en fait plus correct car l'écran est une grille bidimensionnelle de pixels. Ainsi, plus la valeur de z-index est grande, plus l'élément est peint ultérieurement sur la page.

Il existe toutefois une complication majeure. L’espace de valeurs z-index n’est pas plat, c’est hiérarchique. Un élément peut créer un contexte d'empilement qui devient la racine des valeurs de z-index de ses descendants. Il serait préférable d'expliquer le concept de contextes d'empilement à l'aide d'un exemple

Le corps du document compte cinq div descendants: div1 div2 div3 div1-1 et div2-1 . Ils sont tous parfaitement positionnés et se chevauchent. div1-1 est un enfant de div1 et div2-1 est un enfant de div2 .

Voir le stylo [] empilement-contextes de Pavel Pomerantsev .

Essayons de comprendre pourquoi nous voyons ce que nous voyons. Il existe des règles assez élaborées pour déterminer l'ordre de peinture mais il suffit ici de comparer deux choses:

  • z-index Valeurs
    Si un élément a une valeur plus élevée z- index il est peint plus tard.
  • Ordre de la source
    Si les valeurs de z-index sont identiques, alors plus tard elles sont dans la source, plus tard elles sont peintes.

Donc, si nous ne prenons pas en compte les contextes d'empilement, l'ordre devrait être le suivant:

Notez que div2-1 est en fait chevauché par div3 .

Si un élément crée un contexte d'empilement il crée une base pour les valeurs de son z-index pour enfants, de sorte qu'il n'est jamais comparé à quoi que ce soit hors du contexte d’empilement lors de la détermination de l’ordre de peinture. En d'autres termes, lorsqu'un élément créant un contexte d'empilement est peint, tous ses enfants sont peints juste après et avant l'un de ses frères et soeurs.

Pour revenir à l'exemple, l'ordre de peinture réel de body [Ledescendantdivsde est:

Remarquez l'absence de div2-1 dans la liste – il s'agit d'un enfant de div2 ce qui crée un contexte de superposition (parce que c'est un positionnement absolu). élément avec un z-index autre que la valeur par défaut de auto ), il est donc peint après div2 mais avant div3 . [19659005] div1 ne crée pas de contexte d'empilement, car sa valeur z-index implicite est auto donc div1-1 (donc son enfant) est peint après div2 et div3 (depuis son z-index 10, est plus grand que celui de div2 et div3 ).

Ne vous inquiétez pas si vous ne comprenez pas cela en première lecture. Il existe de nombreuses ressources en ligne qui expliquent ces concepts plus en détail:

Note : Il est également agréable de connaître les règles générales relatives à l'ordre des peintures . (qui sont en fait assez complexes).

Cependant, le point principal de cette pièce est de savoir comment traiter z-index lorsque votre page est composée de dizaines et de centaines de composants, chacun Avoir potentiellement des enfants avec z-index défini

L'un des articles les plus populaires sur z-index propose regroupant toutes les valeurs de z-index à un endroit mais comparer ces valeurs n'a pas de sens si elles n'appartiennent pas au même contexte d'empilement (ce qui peut ne pas être facile à obtenir dans une application volumineuse).

Voici un exemple. Disons que nous avons une page avec en-tête et sections principales. La section principale pour une raison quelconque doit avoir la position : relative et z-index: 1 .

Nous utilisons ici une architecture de composant, donc CSS pour le composant racine et chaque composant enfant est défini dans des sections dédiées. En pratique, les composants vivraient dans des fichiers séparés et le balisage serait généré à l'aide d'une bibliothèque JavaScript de votre choix, telle que React, mais à des fins de démonstration, il est correct de tout avoir ensemble.

Imaginez maintenant que nous sommes chargés de créer un menu déroulant dans l'en-tête. Bien sûr, il doit être empilé au-dessus de la section principale. Nous allons donc lui attribuer un index-z de 10 :

quelques mois plus tard, afin de rendre quelque chose de meilleur fonctionne mieux, nous appliquons le hack translateZ à l'en-tête.

Comme vous pouvez le constater, la présentation est maintenant brisée. Un élément avec z-index: 1 repose sur un élément avec z-index: 10 en l'absence de toute autre règle z-index . La raison en est que l'en-tête crée maintenant un contexte d'empilement – c'est un élément avec une propriété transform dont la valeur est autre que none ( voir règles complètes ) et son propre z-index ( 0 par défaut) est inférieur à celui de la section principale ( 1 ).

La solution est simple: donnez le header a La valeur z-index de 2 est corrigée et le problème sera résolu.

La question est de savoir comment pouvons-nous arriver à cette solution si nous avons des composants dans des composants au sein de composants, chacun ayant des éléments avec différents indices z? Comment pouvons-nous être sûrs que changer z-index de l'en-tête ne casse rien d'autre?

La réponse est une convention qui élimine le besoin de devinettes, et c'est la suivante: changer de z-indices dans un composant ne devrait affecter que ce composant et rien d'autre. En d'autres termes, lorsque nous traitons des valeurs de z-index dans un certain fichier CSS, nous ne devrions idéalement nous préoccuper que des autres valeurs de ce même fichier.

Il est facile de l'atteindre. Nous devons simplement nous assurer que la racine de chaque composant crée un contexte d'empilement. La façon la plus simple de le faire est de lui donner les valeurs de position et de z-index autres que les valeurs par défaut (qui sont static et auto respectivement).

Voici l’un des moyens de structurer l’application. Il utilise plus d'éléments que le précédent, mais le calcul associé aux éléments supplémentaires du DOM est peu coûteux, alors que le temps nécessaire au développeur (dont une grande partie peut parfois être utilisée pour le débogage) ne l'est certainement pas.

  • header__container et principal__container les deux ont la position: relative et l'indice z: 0 ;
  • header__overlay a maintenant l'indice z: 1 pas besoin d'une grande valeur car il ne concurrencera que l'ordre d'empilement avec d'autres éléments dans l'en-tête);
  • root__header a maintenant z-index: 2 alors que root__main conserve son z-index: 1 et c'est ce qui permet aux deux frères et sœurs de s'empiler correctement.

(Notez également qu'ils ont tous deux la position: relative depuis L'indice z ne s'applique pas aux éléments positionnés de manière statique .)

Si nous examinons le code d'en-tête Maintenant, nous remarquerons que nous pouvons supprimer la propriété z-index du conteneur et de la superposition, parce que la superposition est le seul élément positionné . De même, le z-index n'est pas requis sur le conteneur principal. C’est le principal avantage de l’approche proposée: lorsqu’on examine les indices z, c’est uniquement le composant qui compte, et non son contexte.

Une telle architecture n’est pas dépourvue d’inconvénients. Cela rend l'application plus prévisible au détriment d'une certaine souplesse. Par exemple, vous ne pourrez pas créer de telles superpositions à la fois dans l'en-tête et dans la section principale:

D'après mon expérience, toutefois, c'est rarement un problème. Vous pouvez faire en sorte que la superposition de la section principale soit réduite au lieu d'être augmentée, afin de ne pas croiser l'en-tête. Ou, si vous en aviez vraiment besoin, vous pouvez injecter le code HTML superposé à la fin du corps et lui attribuer un grand z-index ("grand" étant tout ce qui est plus grand que ceux des autres le niveau supérieur). Quoi qu'il en soit, si vous ne participez pas à une compétition pour construire la mise en page la plus compliquée, tout va bien.

Pour récapituler:

  • Isoler les composants en termes de z-index valeurs d'éléments en faisant de la racine de chaque composant un contexte d'empilement;
  • Vous n'avez pas à le faire si aucun élément dans un composant n'a besoin d'une valeur z-index autre que auto ;
  • Dans le fichier CSS d'un composant, maintient la valeur de z-index à votre guise . Il peut s’agir de valeurs consécutives, ou vous pouvez leur attribuer une valeur de 10, ou vous pouvez utiliser des variables. Tout dépend des conventions de votre projet et de la taille du composant (bien que réduire les composants soit une bonne chose). De préférence, n'attribuez que z-index aux éléments frères. Sinon, vous risquez d’introduire par inadvertance davantage de contextes d’empilement dans un composant et de faire face au même problème, heureusement à une plus petite échelle;
  • Le débogage devient facile . Trouvez le premier composant ancêtre des deux éléments qui ne sont pas empilés correctement et modifiez les indices z dans ce composant si nécessaire.

Nous espérons que cette approche ramènera un peu de bon sens à votre processus de développement.

(dm, ra, il)




Source link
Quitter la version mobile