28111 sujets

CSS et mise en forme, CSS3

Bonsoir
J'avais oublié le fait que "opacity" a une influence sur le comportement de z-index
J'ai le code suivant (simplifié)

<li class="past">
    <div class="poster">
        <img ....>
    </div>
</li>
<li>.....;</li>


.past {opacity:0.75;}
.poster {position:relative;}
.poster img {
    position:absolute;
    top:0;
   left:0;
   z-index:10;
}

Le résultat c'est que l'image passe au dessous des <li> qui suivent;
Si je supprime .past [opacity:0.75;} tout se passe normalement.

J'ai vérifier que mettre .poster et/ou .poster img à opacity:1 !important n'a aucun effet.

Quelle est la solution pour que tout rentre dans l'ordre ?
Merci de votre aide
Avant toute chose, ne jamais, jamais utiliser opacity.

Utiliser des couleurs rgba (background-color: rgba(255, 255, 255, 0.75) ou hsla (background-color: hsla(70, 95%, 70%, 0.75).

Bonne continuation.
Modérateur
Salut,

https://jsfiddle.net/undless/2zg9pdfe/4/
pour moi l'image est bien dessus. Je n'ai jamais entendu parler de ce soucis de z-index avec opacity

thierry a écrit :
Avant toute chose, ne jamais, jamais utiliser opacity.
Utiliser des couleurs rgba (background-color: rgba(255, 255, 255, 0.75) ou hsla (background-color: hsla(70, 95%, 70%, 0.75).

Sur une image ou pour du texte il va falloir hein. Pourquoi ne jamais utiliser opacity ?
Administrateur
Bonjour,

opacity crée en effet un contexte de formatage : MDN en anglais (FR a pas l'air complètement à jour)

a écrit :
Using opacity with a value other than 1 places the element in a new stacking context.


Le plus "connu" est le BFC - Block Formatting Context créé par overflow: hidden, display: table, float: left, etc et c'est un concept bien avancé Smiley smile (déjà que z-index quand on creuse un peu…)
Plus récent transform en crée un également, et Flexbox + Grid Layout créent le leur.

edit : j'ai pas de solution simple, j'avais mal mémorisé le code avant de répondre…
Modifié par Felipe (13 May 2019 - 10:07)
Administrateur
Pourquoi il y a des images superposées ? Est-ce une galerie avec un effet 3D ?
EDIT : et pourquoi naturellement il n'y a pas déjà superposition ? Un élément situé après dans le code HTML s'affiche par dessus les précédentS si on lui en donne l'occasion (si positionné par exemple absolute/relative/fixed/sticky)

Piste de solution : ajouter opacity sur .poster mais je pense pas que ça empêche la superposition.
Pour une liste dont je connaissais la longueur max (fil d'Ariane), j'ai ajouté à la main un z-index:10 sur le 1er LI, 9 sur le 2e etc jusqu'au 6e à cause de Flexbox : chaque LI était un flex container donc créait un contexte de formatage et il y avait un Smiley langue seudo sur le LI par dessus le LI suivant, bref pas d'autre solution. Je n'ai pas tenté d'ajouter un div/span dans chaque LI comme ici avec .poster…
Modifié par Felipe (13 May 2019 - 10:16)
Modérateur
Hello, il doit y avoir autre chose qui pose problème, car selon ce code, l'image est bien au-dessus des puces?
Bonjour à tous, merci pour vos réponses, et désolé de n'avoir pas pu répondre plus tôt
L'adresse de la page qui pose problème est https://tests.alma-musica.net/html/calendar.php
L'idée était de faire en sorte que les activités passées soient estompées.
Mettre ces lignes avec opacity:0.75 me semblait une bonne idée, ne nécessitant pas de définir un jeu complet de couleurs pour les activités passées.
C'est là que je me suis aperçu de ce qui se passait quand on clique sur le minature d'image, par exemple ) la date du 14 février: ces miniatures sont faites de telle façon que quand on clique sur elles on fait apparaitre la même image en plus grand.
J'espère que cela répond à la plupart de vos questions.

Dans la pratique, je peux me passer de cette commande, c'était pour savoir s'il y avait une solution que j'ai posé la question.

Je déduis de vos réponses que le f... des z-index n'a sans doute pas de solution simple.
Ça ressemble beaucoup à un design mal conçu à l'origine, mais je ne vais pas jeter la pierre aux concepteurs de ce truc, j'en ai fait moi même pas mal de semblables dans mes 52 ans d'activités informatiques Smiley cligne
Modifié par PapyJP (14 May 2019 - 12:08)
Modérateur
Ok je vois mieux le truc, en effet c'est limité dans la norme:

a écrit :
Since an element with opacity less than 1 is composited from a single offscreen image, content outside of it cannot be layered in z-order between pieces of content inside of it. For the same reason, implementations must create a new stacking context for any element with opacity less than 1


Après de toute façon même si c'était possible l'image serait partiellement transparente (ce qui reste pas terrible).

Sinon tu peux facilement contourner le problème en ciblant en-dessous et en évitant l'image:


li.event.past .eventData > * {
    opacity: 0.7;
}
li.event.past .eventData .poster {
    opacity: 1;
}
Modérateur
p.s. : ces limitations ne sont pas totalement absurdes et ne sont pas causées par un design mal pensé. L'idée est d'économiser sur les performances, l'opacité étant une mécanique gourmande en ressources, il est plus simple de pré-rendre un block avant de lui appliquer de l'opacité plutôt que de gérer l'opacité sur chaque élément individuel (ce qui aurait de plus un autre effet visuel).
@_laurent :

a écrit :
Sur une image ou pour du texte il va falloir hein. Pourquoi ne jamais utiliser opacity ?


On peut tout aussi bien définir le degré de transparence du texte en RGBA ou HSLA.

@Bongota :

Merci, je ne connaissais pas ces articles.
Modifié par thierry (14 May 2019 - 17:43)
kustolovic a écrit :

Sinon tu peux facilement contourner le problème en ciblant en-dessous et en évitant l'image:


li.event.past .eventData > * {
    opacity: 0.7;
}
li.event.past .eventData .poster {
    opacity: 1;
}

C’est bien ce que j’ai voulu faire, mais ça ne marchait pas. Je vais essayer à nouveau demain.
J'ai modifié le css comme suit:

li.event.past {opacity:0.75;}
li.event.past .poster {opacity: 1;}

puis

li.event.past {opacity:0.75;}
li.event.past .poster, li.event.past .poster > * {opacity: 1;}

Le résultat est le même. J'ai laissé le code en ligne pour que vous puissiez le constater et éventuellement faire des modifications avec les outils de debugging des navigateurs. Il y a peut être une solution ???

Remarques:

1) bien entendu, on peut utiliser rgba, mais c'est ce que je voulais éviter de faire, car il faut définir le jeu de couleurs en double. Pour moi dire "opacity:0.75" ça devrait être la même chose que remplacer rgb(x, y, z) par rgba(x ,y, z, 0.75)

2) dire qu'il ne faut pas utiliser opacity est une autre façon de dire que c'est mal conçu

3) en tant qu'ancien concepteur et réalisateur de systèmes, je me permets de vous faire part de mon expérience:
Un produit quelconque (fonctionnalité informatique, avion, maison, moulin à café...) doit être conçu à partir des BESOINS DES UTILISATEURS.
Les "utilisateurs" appartiennent à diverses catégories. Pour une fonctionnalité comme opacity, on a au moins
- les utilisateur finaux: des centaines de millions de personnes qui accèdent à Internet
- les développeurs de sites : quelques millions de personnes, dont nous faisons partie
- les développeur du produit: quelques centaines de personnes sui développent les moteurs CSS
Le problème, c'est que la dernière catégorie est également celle qui décide ce qu'on va implémenter, alors que la deuxième catégorie est un ensemble flou qui n'est représenté par personne lors de la définition. Les préoccupations des développeurs ont donc une tendance à l'emporter sur les besoins des développeurs de sites, qui doivent se comporter en "utilisateurs finauds" pour contourner les insuffisances du produit.

Par ailleurs les développeurs de sites n'ont aucun impact sur le marché: ils ne sont que des intermédiaires par rapport aux utilisateurs finaux, et même ceux là n'ont pas d'impact réel sur le marché.

Pendant des années, c'était IBM qui décidait quelle était la norme, tout le monde devait s'y plier, puis ça a été Microsoft, maintenant c'est Google. Quoi que l'acteur dominant décide, tout le monde doit s'y plier... jusqu'à la prochaine révolution qui amène un nouvel acteur dominant.

Ce qu'il est également intéressant de noter, c'est de constater que plus c'est mal fichu, plus les personnes qui comprennent un peu comment ça marche et surtout ce qu'on peut faire pour contourner les problèmes prennent de l'importance en tant qu'experts et se convainquent que c'est très bien qu'il en soit ainsi....
Une fois de plus, ce n'est pas pour jeter la première pierre: j'ai moi aussi fait partie des "experts" dans d'autres domaines
Modérateur
Salut,

Attention tu n'a pas vraiment appliqué ce que kustolovic proposait :

li.event.past .eventData > * {
    opacity: 0.7;
}
li.event.past .eventData .poster {
    opacity: 1;
}


Il propose de mettre tout les élément au même niveau que .poster à opacity 0.75 sauf .poster.

Ici, si je ne me trompe pas tu met encore le parent a 0.75. Et ca ne changera rien pour les enfants :

li.event.past {opacity:0.75;}
_laurent a écrit :
Salut,

Attention tu n'a pas vraiment appliqué ce que kustolovic proposait :

li.event.past .eventData &gt; * {
    opacity: 0.7;
}
li.event.past .eventData .poster {
    opacity: 1;
}


Il propose de mettre tout les élément au même niveau que .poster à opacity 0.75 sauf .poster.

Ici, si je ne me trompe pas tu met encore le parent a 0.75. Et ca ne changera rien pour les enfants :

li.event.past {opacity:0.75;}

Mon code met à la fois .poster ET ses enfants avec opacity:1
ça ne change rien
SI je laisse .poster à 0.75 et mets ses enfants à 1, c'est la même chose.
Je rappelle l'adresse de la page pour que vous puissiez jouer avec:
https://tests.alma-musica.net/html/calendar.php
Modérateur
PapyJP a écrit :
Mon code met à la fois .poster ET ses enfants avec opacity:1
ça ne change rien

Oui, si le parent est a 0.75 ca ne change rien pour poster ou ses enfant..

PapyJP a écrit :
SI je laisse .poster à 0.75 et mets ses enfants à 1, c'est la même chose.

C'est pas ca que j'ai dit ni que kusto propose

PapyJP a écrit :
Je rappelle l'adresse de la page pour que vous puissiez jouer avec:
https://tests.alma-musica.net/html/calendar.php

Oui oui je joue déjà avec t'en fait pas.

Bon je vais tenter de mieux expliquer.

Tu as cette structure :

<li class="event past concert friends" data-eventid="C20181215">
    <button class="date">
        [...]
    </button>
    <div class="eventData">
        <h4 class="handle">
                [...]
        </h4>
        <div class="date">
                [...]
        </div>
        <div class="poster">
                [...]
        </div>
        <div class="subject">
                [...]
        </div>
        <div class="address" title="11 Esplanade des Droits de l'Homme - 77185 Lognes">
                [...]
        </div>
        <div class="prog">
                [...]
        </div>
    </div>
</li>


Si tu met un opacity 0.75 sur le <li> ca impactera tout les enfants peut importe si tu leur redonne un opacity 1.

Kusto te propose de mettre el opacity 0.75 sur tout les éléments frere de poster plutot que sur le li. De cette facon poster ne sera pas impacté :

li.event.past .eventData > * {
    opacity: 0.7;
}
li.event.past .eventData .poster {
    opacity: 1;
}

Modifié par _laurent (15 May 2019 - 10:43)
Meilleure solution
Merci de ta réponse.
J'avais mal compris en effet.
Je ne comprends pas pourquoi ça marche, et pourquoi ce que j'avais fait ne marche pas, mais ça marche, c'est le principal !
Je vais essayer de mettre ça dans un coin de ma mémoire, quoi que ma mémoire, à mon âge, n'est plus tout à fait ce qu'elle a été !!!
Modérateur
Très bien,

ce qui n'a pas été bien compris je pense, c'est qu'opacity ne se propage pas à ses enfants.
Opacity s'applique sur un bloc, vu comme un tout graphique (dont tous les enfants ont une opacity par défaut de 1).

Voir ici:

https://codepen.io/anon/pen/RmpBWY

Et oui dire qu'opacity ne doit pas être utilisé est absurde.
Modérateur
PapyJP a écrit :
Je ne comprends pas pourquoi ça marche, et pourquoi ce que j'avais fait ne marche pas, mais ça marche, c'est le principal !

Alors, opacity est un peu spécial.

<parent>
    <enfant></enfant>
    <enfant></enfant>
</parent>

Si on réduit opacity sur le parent, lui et tout ses enfants seront transparent.
Si, en plus, on met opacity 1 sur un enfant, cela ne changera absolument rien ! L'enfant est déjà à 1 mais est transparent car son parent l'est.
Si on met un opacity inférieur a 1 sur l'enfant, il cumulera sa propre transparence à celle donnée par son parent.

Mais ici il ne s'agit même pas de ca : On essaie d'éviter de contexte de formatage donné par opacity à poster. Mais si on le met sur le parent (pour éviter de le mettre sur chaque enfant) les enfant en hériteront forcément... la solution consiste donc a mettre l'opacity sur chacun des enfant sauf celui dont on ne veut pas qu'il soit formaté.

Bonne journée
Merci, c'est très clair.
Je ne connaissais pas ce mécanisme de combinaison des opacités en cascade, qui est effectivement parfaitement logique.
Grâce à toi je me sens un peu moins stupide Smiley ravi