Wie wird das übergeordnete Element beim Bewegen des Mauszeigers über ein untergeordnetes Element formatiert?


159

Ich weiß, dass es keinen übergeordneten CSS-Selektor gibt , aber ist es möglich, ein übergeordnetes Element zu formatieren, wenn ein untergeordnetes Element ohne einen solchen Selektor bewegt wird?

Um ein Beispiel zu nennen: Betrachten Sie eine Schaltfläche zum Löschen , die beim Bewegen des Mauszeigers das Element hervorhebt, das gelöscht werden soll:

<div>
    <p>Lorem ipsum ...</p>
    <button>Delete</button>
</div>

Wie kann man mit reinem CSS die Hintergrundfarbe dieses Abschnitts ändern, wenn sich die Maus über der Schaltfläche befindet?



Antworten:


134

Nun, diese Frage wird schon oft gestellt, und die kurze typische Antwort lautet: Sie kann nicht mit reinem CSS durchgeführt werden. Es ist im Namen: Cascading Style Sheets unterstützt das Styling nur in kaskadierender Richtung, nicht nach oben.

Aber in den meisten Fällen , in denen dieser Effekt gewünscht wird, wie in dem gegebenen Beispiel, gibt es immer noch die Möglichkeit , diese Kaskadierung Eigenschaften zu verwenden , um den gewünschten Effekt zu erreichen. Betrachten Sie dieses Pseudo-Markup:

<parent>
    <sibling></sibling>
    <child></child>
</parent>

Der Trick besteht darin, dem Geschwister die gleiche Größe und Position wie dem Elternteil zu geben und das Geschwister anstelle des Elternteils zu stylen. Dies wird so aussehen, als ob die Eltern gestylt sind!

Wie soll man das Geschwister stylen?

Wenn das Kind schwebt, ist es auch der Elternteil, das Geschwister jedoch nicht. Gleiches gilt für die Geschwister. Dies schließt in drei möglichen CSS-Auswahlpfaden für das Styling des Geschwisters:

parent sibling { }
parent sibling:hover { }
parent:hover sibling { }

Diese verschiedenen Wege bieten einige schöne Möglichkeiten. Wenn Sie beispielsweise diesen Trick auf das Beispiel in der Frage loslassen, führt dies zu folgender Geige :

div {position: relative}
div:hover {background: salmon}
div p:hover {background: white}
div p {padding-bottom: 26px}
div button {position: absolute; bottom: 0}

Beispiel für ein übergeordnetes Bild

In den meisten Fällen hängt dieser Trick natürlich von der Verwendung der absoluten Positionierung ab, um dem Geschwister die gleiche Größe wie dem Elternteil zu geben und das Kind dennoch im Elternteil erscheinen zu lassen.

Manchmal ist es erforderlich, einen qualifizierteren Auswahlpfad zu verwenden, um ein bestimmtes Element auszuwählen, wie in dieser Geige gezeigt, die den Trick mehrmals in einem Baummenü implementiert. Wirklich ganz nett.


1
Dies ist gut zum Hervorheben, funktioniert aber nicht, wenn Sie versuchen, die Schriftfarbe zu ändern. Stimmt das?
Jahanzeb Khan

1
@JahanzebKhan Das Ändern der Schriftfarbe ist kein Problem .
NGLN

116

Ich weiß, dass es eine alte Frage ist, aber ich habe es gerade ohne ein Pseudo-Kind (aber einen Pseudo-Wrapper) geschafft.

Wenn Sie die Eltern mit nicht so festgelegt pointer-events, und dann einem Kind divmit pointer-eventsSatz auto, es funktioniert :)
Beachten Sie, dass <img>Tag (zum Beispiel) nicht den Trick.
Denken Sie auch daran zu setzen , pointer-eventsum autofür andere Kinder , die ihre eigenen Ereignis - Listener haben, oder sonst werden sie ihre Klick - Funktionalität verlieren.

div.parent {  
    pointer-events: none;
}

div.child {
    pointer-events: auto;
}

div.parent:hover {
    background: yellow;
}    
<div class="parent">
  parent - you can hover over here and it won't trigger
  <div class="child">hover over the child instead!</div>
</div>

Bearbeiten:
Wie Shadow Wizard freundlicherweise bemerkte: Es ist erwähnenswert, dass dies für IE10 und darunter nicht funktioniert. (Alte Versionen von FF und Chrome auch hier )


3
Erwähnenswert ist, dass dies für IE10 und darunter nicht funktioniert. (Alte Versionen von FF und Chrome, siehe hier )
Shadow Wizard ist Ear For You

2
Das Setzen von Zeigerereignissen auf none bedeutet auch, dass Ereignis-Listener für dieses Element nicht funktionieren.!
Rhazen

1
@rhazen du hast absolut recht. Obwohl diese Verwendung meiner Erfahrung nach normalerweise mit einem einzelnen Klickbereich / Element verbunden ist, können Sie den Klick-Listener dem übergeordneten
guy_m

Wie wäre es, wenn ich zwei Ebenen habe, Eltern, Kind1 und Kind von Kind1. Ich habe Zeigerereignisse keine zu übergeordneten und Zeigerereignisse automatisch zu untergeordneten hinzugefügt. Ich möchte mit Ausnahme des Kindes von Kind 1 zu Kind1 schweben. Demo hier: codepen.io/lion5893/pen/WNQgyVx
Nam Lê Quý

13

Ein anderer, einfacherer Ansatz (für eine alte Frage)
wäre, Elemente als Geschwister zu platzieren und zu verwenden:

Angrenzender Geschwister-Selektor ( +) oder allgemeiner Geschwister-Selektor ( ~)

<div id="parent">
  <!-- control should come before the target... think "cascading" ! -->
  <button id="control">Hover Me!</button>
  <div id="target">I'm hovered too!</div>
</div>
#parent {
  position: relative;
  height: 100px;
}

/* Move button control to bottom. */
#control {
  position: absolute;
  bottom: 0;
}

#control:hover ~ #target {
  background: red;
}

Geben Sie hier die Bildbeschreibung ein

Demo Fiddle hier .


1
Es ist erwähnenswert, dass dies nur funktioniert, wenn #Ziele nach #Kontrolle im DOM kommen (dh Sie können frühere Geschwister nicht beeinflussen, nur nach folgenden Geschwistern)
Gio

10

Es gibt keinen CSS-Selektor zum Auswählen eines Elternteils eines ausgewählten Kindes.

Sie könnten es mit JavaScript tun


3
wahr. so etwas wie $ (child) .hover (function () {$ (this) .closest (parentSelector) .addClass ('hoverClass')}, function () {$ (this) .closest (parentSelector) .removeClass ('hoverClass') )});
Aamir Afridi

8
@AamirAfridi Das ist allerdings kein reines JS, dafür musst du jQuery verwenden.
Ivotje50

6

Wie bereits erwähnt, "gibt es keinen CSS-Selektor zum Auswählen eines Elternteils eines ausgewählten Kindes".

Also Sie entweder:


Hier ist das Beispiel für die Javascript / jQuery- Lösung

Auf der Javascript-Seite:

$('#my-id-selector-00').on('mouseover', function(){
  $(this).parent().addClass('is-hover');
}).on('mouseout', function(){
  $(this).parent().removeClass('is-hover');
})

Und auf der CSS-Seite hätten Sie so etwas:

.is-hover {
  background-color: red;
}

3

Diese Lösung hängt vollständig vom Design ab. Wenn Sie jedoch ein übergeordnetes Div haben, auf dem Sie den Hintergrund ändern möchten, wenn Sie den Mauszeiger über ein Kind bewegen, können Sie versuchen, das übergeordnete Element mit einem ::after/ nachzuahmen ::before.

<div class="item">
    design <span class="icon-cross">x</span>
</div>

CSS:

.item {
    background: blue;
    border-radius: 10px;
    position: relative;
    z-index: 1;
}
.item span.icon-cross:hover::after {
    background: DodgerBlue;
    border-radius: 10px;
    display: block;
    position: absolute;
    z-index: -1;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    content: "";
}

Sehen Sie hier ein vollständiges Geigenbeispiel


-1

Eine einfache Abfragelösung für diejenigen, die keine reine CSS-Lösung benötigen:

    $(".letter").hover(function() {
      $(this).closest("#word").toggleClass("hovered")
    });
.hovered {
  background-color: lightblue;
}

.letter {
  margin: 20px;
  background: lightgray;
}

.letter:hover {
  background: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="word">
  <div class="letter">T</div>
  <div class="letter">E</div>
  <div class="letter">S</div>
  <div class="letter">T</div>
</div>


-8

Dies ist in Sass extrem einfach! Tauchen Sie dafür nicht in JavaScript ein. Der & Selektor in sass macht genau das.

http://thesassway.com/intermediate/referencing-parent-selectors-using-ampersand


6
-1 Sass erweitert CSS nicht um weitere Funktionen, sondern erleichtert lediglich das Schreiben. Alles, was Sie in Sass tun können, kann in CSS und umgekehrt getan werden.
Dastur

3
@Dastur Angesichts von Variablen und Mixins würde ich sagen, dass Sass CSS sehr viel hinzufügt. Sie können alles in CSS erledigen, genauso wie Sie hochentwickelte Software mit einfachem altem C schreiben können. Moderne Sprachen fügen viel hinzu, ohne etwas zu aktivieren, was vorher nicht möglich war. Gleiches gilt für Sass und CSS.
Cobus Kruger

6
@ Cobus Kruger Du hast teilweise recht, aber du kannst diesen Vergleich nicht machen. Während Sprachen wie c ++ c # und Javascript möglicherweise auf C basieren, werden sie vor der Laufzeit nicht zu C. Sass wird vor der Laufzeit in CSS konvertiert, daher laden Sie nie wirklich ein Sass-Stylesheet, sondern nur ein CSS-Stylesheet.
Dastur
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.