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.
Wenn Sie nun mit der Maus über eines dieser Elemente fahren, sollte das jeweilige Element wie unten undurchsichtig werden.
4 Antworten
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>
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.
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;
}
Hoffe das hilft.
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.
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.
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);
}