web-dev-qa-db-fra.com

Qu'est-ce qui a la plus grande priorité: l'opacité ou l'indice z dans les navigateurs?

Je suis en train de coder une "fenêtre popup" en JavaScript et je suis tombé sur une chose intéressante:

Cropped screenshot demonstrating strange stacking behavior

Le carré bleu sous la fenêtre contextuelle est visible même si je pense qu'il sera caché. Le popup a été ajouté après le carré, il devrait donc être en haut.

La propriété CSS opacity du navy square est 0.3. D'après ce que j'ai essayé, il semble que chaque nombre de l'intervalle (0,1) donnerait le même résultat. Si je le change en 1, alors il se comporte comme prévu (c’est-à-dire que la partie du carré sous la fenêtre est masquée). 

J'ai essayé de définir la propriété z-index sur 10 pour le carré et 100 pour le popup, mais cela ne change rien.

Qu'est-ce que je rate? Pourquoi une partie de la place est-elle affichée?

Navigateurs testés:

  • Firefox 3.6.x
  • Chrome 4
41
Martin Vseticka

Ce n'est pas un bug et c'est en fait comment cela est supposé fonctionner. C'est un peu déroutant car le description élaborée de Stacking Contexts ne mentionne rien à ce sujet. Cependant, le module de formatage visuel _ est lié au module de couleur où cet objet obtenu peut être trouvé (l'emphase est mise):

Puisqu'un élément avec une opacité inférieure à 1 est composé à partir d'un seul image hors écran, le contenu situé à l'extérieur ne peut pas être superposé dans l'ordre z entre les éléments de contenu à l'intérieur de celui-ci. Pour la même raison, les implémentations doivent créer un nouveau contexte d'empilement pour tout élément avec une opacité inférieure à 1. Si un élément avec une opacité inférieure à 1 est non positionné, les mises en œuvre doivent peindre le calque qu'il crée, dans son contexte d'empilement parent, dans le même ordre d'empilement que serait utilisé s’il s’agissait d’un élément positionné avec ‘z-index: 0’ et «Opacité: 1». Si un élément d'opacité inférieure à 1 est positionné, la propriété ‘z-index’ s’applique comme décrit dans [CSS21], sauf que "Auto" est traité comme "0" puisqu'un nouveau contexte d'empilement est toujours créé. Voir la section 9.9 et l'annexe E de [CSS21] pour plus d'informations informations sur les contextes d'empilement. Les règles de ce paragraphe ne le font pas s'applique aux éléments SVG, car SVG a son propre modèle de rendu ([SVG11], Chapitre 3).

50
0b10011

Ce n'est pas un problème de opacity étant plus important que z-index, plutôt que z-index étant relatif à leur contexte d'empilement (voir z-index dans la spécification CSS2).

En d'autres termes, z-index ne sont significatifs que dans le contexte d'un ancêtre positionné (qu'il soit relatif, absolu ou fixe). Ce que vous devez faire pour résoudre votre problème est d’ajouter un position: relative; à l’élément contenant à la fois votre popup et votre carré marine, et probablement de lui ajouter un z-index: 1;. En voyant votre capture d'écran, il s'agira probablement d'un élément supérieur tel qu'un div en wrapper.

20

Solution de contournement pour deux éléments, tels que divs: ajoutez une opacité 0.99 à votre élément supérieur et l'ordre des deux est restauré.

opacity: 0.99;
5
Enzo DB

Exemple de code peut être nécessaire pour déboguer ce problème.

Vous pouvez mettre overflow: hidden et éventuellement position: relative dans une DIV qui entoure tous les objets de l'éditeur pour essayer de forcer les éléments à être dessinés uniquement dans cette DIV, par exemple:

<div style="overflow: hidden; position: relative">
    (Editor object buttons go here)
</div>

En dernier recours, vous pouvez également essayer une iframe entre les deux éléments pour tenter de les en empêcher.

1
cryo

Vous pouvez essayer de définir la DIV de la fenêtre contextuelle comme ceci en utilisant !important afin que le style ne change pas lors de l'application d'un nouveau style ou d'une nouvelle classe:

background-color: white !important;
z-index: 100 !important;
opacity: 1.0 !important;

Ensuite, créez une nouvelle classe CSS:

.PopupElement
{
 z-index: inherited;
 opacity: inherited;
}

Et ajoutez une classe à tous les éléments de la fenêtre, comme ceci par exemple:

<input value="posx" class="some_class PopupElement"/>

Mon hypothèse est que cela fonctionnerait, car il n'y a pas de priorité dans l'application d'attributs CSS ... pour autant que je sache. =)

0
Cipi

Bien que @Guillaume Esquevin ait déjà donné une bonne réponse, je vais essayer de la développer au cas où quelqu'un ignorerait ce qu'est un contexte d'empilement (comme je l'ai fait).

Comme vous pouvez le lire ici , il existe quelque chose appelé "contexte d'empilement", qui fait référence à un groupe d'éléments partageant un parent qui se déplacent ensemble dans la pile. Un exemple pourrait être une div et tous ses enfants.

Il existe trois façons de créer un contexte d'empilement: à la racine du document (l'élément html), en positionnant l'élément parent et en modifiant l'opacité du parent en une valeur inférieure à 1.

Ensuite, si vous avez une div d'opacité inférieure à 1 et que vous voulez qu'un élément frère de cette div apparaisse derrière lui (et ses enfants), vous pouvez créer un nouveau contexte d'empilement sur ce frère en définissant sa position par rapport ou en modifiant son opacité aussi.

0
Mr. Duhart