Dies ist eine Frage / Antwort zum Umgang mit der Deckkraft überlappender Elemente und zur Konsistenz beim Schweben mit einer JS-Lösung.

Anforderung

Die Anforderung besteht darin, zwei Elemente zu entwickeln, die transparent sind und sich überlappen, wie die beiden roten Kästchen unten. Diese müssen transparent sein, damit der Hintergrundinhalt sichtbar ist.

enter image description here

Wenn Sie nun mit der Maus über eines dieser Elemente fahren, sollte das jeweilige Element wie unten undurchsichtig werden.

enter image description here

3
Gibin Ealias 18 Apr. 2018 im 16:18

4 Antworten

Beste Antwort

Es gibt eine reine CSS-Lösung, die es etwas effizienter macht. So zum Beispiel:

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>
11
Julien Grégoire 23 Apr. 2018 im 17:40

Lösung

Wie in der Anforderung beschrieben, beginnt die Lösung mit der Erstellung von zwei Elementen und wahrscheinlich einem Wrapper für diese.

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

Jetzt stylen wir sie passend zum Design.

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

Und die folgenden Codezeilen für die Überlappung.

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

Das Problem bei diesem Ansatz besteht darin, dass die Deckkraft in der überlappenden Region nicht konsistent ist und erhalten wird ein dunklerer Farbton.

enter image description here

Beachten Sie, dass dies kein Fehler in den Browsern ist und der Grund für dieses Verhalten hier erläutert wird >.


Der richtige Ansatz

Der bessere Weg, um mit dieser Situation umzugehen, besteht darin, zu vermeiden, dass die untergeordneten Elemente transparent werden, und stattdessen auf der übergeordneten Ebene die Deckkraft festzulegen. Schalten Sie beim Bewegen des Mauszeigers diese Deckkraft zwischen Eltern und Kindern mit JS um.

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

Außerdem würde das Schweben in einem überlappenden Bereich aufgrund einer Änderung der Stapelreihenfolge ein Flackern verursachen, was durch Setzen von z-index auf das schwebende Element behoben werden kann.

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

CODEPEN

Hoffe das hilft.

1
Gibin Ealias 18 Apr. 2018 im 19:58

Hier ist ein weiterer Ansatz, der Pointer_events verwendet

Wenn Sie mit der Maus über ein Element fahren, deaktivieren Sie das pointer-events auf dem anderen:

$('.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>

Überprüfen Sie die Kompatibilität, da dies in den meisten Browsern außer Safari (ab sofort) funktioniert.

-1
Taki 25 Apr. 2018 im 02:02

Ich habe es mit Elementen an absoluten Positionen versucht. In diesem Fall kann ich jeden von ihnen über die wrapper bei der Mauseingabe nach oben bewegen und dann über reines JavaScript zu ihrer Position beim Verlassen der Maus zurückkehren.

Ich habe das Beispiel auf 3 Elemente erweitert, in denen Ihr Code die Artefakte anzeigt, und Rahmen hinzugefügt, um die Überlappung tatsächlich zu sehen.

CODEPEN

Der 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>

Das 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; }

Das 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
edixon 30 Apr. 2018 im 12:12