Éléments superposés avec opacité et la gestion du "vol stationnaire" sur ces

il s'agit d'un Q/A sur la façon de gérer l'opacité des éléments se chevauchant et de le rendre cohérent en vol stationnaire, avec une solution JS.

exigence

l'exigence est de développer deux éléments, qui sont transparents et se chevauchent, comme les deux boîtes rouges ci-dessous. Ceux-ci doivent être transparents afin que le contenu de fond soit visible.

enter image description here

Maintenant, pendant qu'il est en vol stationnaire sur l'un de ces éléments, l'élément particulier devrait devenir opaque comme ci-dessous.

enter image description here

2
demandé sur Gibin Ealias 2018-04-18 16:18:38

4 réponses

il y a une solution CSS uniquement, ce qui le rend un peu plus efficace. Comme ceci par exemple:

body {
  background-image: linear-gradient(45deg, transparent 50%, #aaa 75%);
  background-size: 20px 20px;
}

#a {
  position: absolute;
  width: 150px;
  height: 150px;
  top: 50px;
  left: 50px;
  background: rgba(255, 0, 0, 1);
}

#b {
  position: absolute;
  width: 150px;
  height: 150px;
  top: 125px;
  left: 125px;
  background: rgba(255, 0, 0, 1);
}

#wrapper {
  opacity: 0.5;
}

/* instead of changing the classes,  
you can use selectors like this:*/

#wrapper:hover #a:hover,
#wrapper:hover #b:hover {
  opacity: 1;
  z-index: 10;
}

#wrapper:hover {
  opacity: 1;
}

#wrapper:hover #b,
#wrapper:hover #a {
  opacity: 0.5;
  z-index: -1;
}
<div id=wrapper>
  <div id="a">
  </div>
  <div id="b">
  </div>
</div>
9
répondu Julien Grégoire 2018-04-23 17:40:32

j'ai essayé avec des éléments à des positions absolues. Dans ce cas, je suis capable de déplacer chacun d'eux sur le dessus du wrapper sur Entrée de souris, puis de revenir à leur position sur sortie de souris, via pur JavaScript.

j'ai étendu l'exemple à 3 éléments, où votre code montre les artefacts, et ajouté des bordures pour voir réellement le chevauchement.

CODEPEN

the HTML:

<div id=top>
  <div id=wrapper>
    <div class="first" onMouseEnter="hover3b(event)" onMouseLeave="hover3e(event)"></div>
    <div class="second" onMouseEnter="hover3b(event)" onMouseLeave="hover3e(event)"></div>
    <div class="third" onMouseEnter="hover3b(event)" onMouseLeave="hover3e(event)"></div>
  </div>
</div>

The CSS:

body {
  background-image: linear-gradient(45deg, transparent 50%, #aaa 75%);
  background-size: 20px 20px;
}

.first, .second, .third {
  width: 100px;
  height: 100px;
  background-color: red;
  position: absolute;
  border: 3px solid black;
}

#wrapper {
  width: 200px;
  height: 200px;
  background-color: yellow;
  border: 3px solid green;
  opacity: 0.6;
}

.first { left: 0px; top: 0px; }
.second { left: 80px; top: 80px; }
.third { left: 160px; top: 160px; }

Le JavaScript:

var from = null; // remember where to put back the element
function hover3b(e) {
  var t = e.target;
  from = t.nextElementSibling;
  if (!from)
    from = null;
  document.getElementById("top").appendChild(t);
}
function hover3e(e) {
  document.getElementById("wrapper").insertBefore(e.target, from);
}
2
répondu edixon 2018-04-30 12:12:16

Solution

comme décrit dans l'exigence, la solution commence par la création de deux éléments et probablement une enveloppe à ceux-ci.

<div class="wrapper">
  <div class="first"></div>
  <div class="second"></div>
</div>

maintenant, nous les coiffons pour correspondre à la conception.

.first,
.second {
  width: 100px;
  height: 100px;
  background-color: red;
  opacity: 0.6;
}

et les lignes de code ci-dessous pour le chevauchement.

.second {
  margin-left: 50px;
  margin-top: -50px;
}

le problème de La cette approche , c'est que l'opacité ne sera pas uniforme sur le recouvrement des région et il obtient une teinte plus foncée.

enter image description here

notez qu'il ne s'agit pas d'un bug avec les navigateurs et la raison de ce comportement est expliquée ici .


La bonne approche

la meilleure façon de gérer cette situation est d'éviter de rendre les éléments enfants transparent et à la place de mettre "opacité" dans le niveau parent. Et en vol stationnaire, basculer ces niveaux d'opacité entre le parent et les enfants avec JS.

$(".first, .second").hover(function() {
  $(".wrapper, .first, .second").not(this).toggleClass("add-opacity");
});

de plus, le vol stationnaire dans une région chevauchée provoquerait un scintillement dû au changement de l'ordre de la pile, qui peut être traité en réglant z-index à l'élément en vol stationnaire.

.first:hover,
.second:hover {
  z-index: 1;
}

CODEPEN

Espérons que cette aide.

1
répondu Gibin Ealias 2018-04-18 19:58:49

Voici une autre approche utilisant Pointer_events

chaque fois que vous passez en stationnaire sur un élément, vous désactivez le pointer-events sur l'autre:

$('.first').hover(
  () => { $('.second').css({'pointer-events': 'none'})},
  () => { $('.second').css({'pointer-events': 'auto'})
})

$('.second').hover(
  () => {$('.first').css({'pointer-events': 'none'})},
  () => {$('.first').css({'pointer-events': 'auto'})
})
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  border: 0;
}

body {
  background-image: linear-gradient(45deg, transparent 50%, #aaa 75%);
  background-size: 20px 20px;
}

.wrapper {
  margin-top: 10px;
  margin-left: 10px;
}

.first {
  width: 100px;
  height: 100px;
  background: rgba(255, 0, 0, 0.6);
}

.second {
  width: 99px;
  height: 98px;
  margin-top: -49px;
  margin-left: 50px;
  background: -webkit-linear-gradient(transparent 50%, rgb(255, 0, 0) 50%), -webkit-linear-gradient(0deg, transparent 50%, rgb(255, 0, 0) 50%);
  opacity: 0.6;
}

.first:hover,
.second:hover {
  background: rgba(255, 0, 0, 1);
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="first" id="first"></div>
  <div class="second" id="second"></div>
</div>

vérifiez la compatibilité pour cela car il fonctionnera dans la plupart des navigateurs sauf Safari ( à partir de maintenant ).

-1
répondu Taki 2018-04-25 02:02:06