So beeinflussen Sie andere Elemente, wenn ein Element bewegt wird

459

Was ich tun möchte, ist, wenn ein bestimmtes divschwebt, würde es die Eigenschaften eines anderen beeinflussen div.

Zum Beispiel in diesem JSFiddle Demo , wenn Sie schweben über #cubees das ändert sich background-coloraber , was ich will , ist , dass , wenn ich schweben über #container, #cubebetroffen ist .

div {
  outline: 1px solid red;
}
#container {
  width: 200px;
  height: 30px;
}
#cube {
  width: 30px;
  height: 100%;
  background-color: red;
}
#cube:hover {
  width: 30px;
  height: 100%;
  background-color: blue;
}
<div id="container">

  <div id="cube">
  </div>

</div>

Trufa
quelle

Antworten:

985

Befindet sich der Würfel direkt im Behälter:

#container:hover > #cube { background-color: yellow; }

Wenn sich der Würfel neben (nach dem Schließen des Tags des Containers) dem Container befindet:

#container:hover + #cube { background-color: yellow; }

Wenn sich der Würfel irgendwo im Behälter befindet:

#container:hover #cube { background-color: yellow; }

Wenn der Würfel ein Geschwister des Containers ist:

#container:hover ~ #cube { background-color: yellow; }
Mike
quelle
107
Vergessen Sie nicht, dass der allgemeine Geschwisterkombinator ~für "Würfel ist irgendwo nach Container im DOM und teilt sich ein Elternteil"
robertc
3
Das ist ziemlich toll. Gibt es eine Quelle, in der ich weitere Informationen dazu finden kann? Wird es von allen Browsern unterstützt, ist es CSS3? Wäre toll, mehr Infos dazu zu haben. Vielen Dank!
Anonym
2
+1 Tolle Antwort @Mike. Was ist, wenn #containerneben #cube, dh #containerfolgt #cube?
PeterKA
4
Was tun, wenn sich das schwebende Element im Container befindet (das wir bewirken möchten) ??? Zum Beispiel: #cube: hover #container {Einige CSS-Effekte}
Hanzallah Afgan
2
Gute Antwort !! Was ist, wenn ich den Elternteil ändern möchte, wenn ich das Kind schwebe? Ich denke, dafür gibt es keinen Selektor.
Mikel
41

In diesem Beispiel können Sie Folgendes verwenden:

#container:hover #cube {
    background-color: yellow;   
}

Dieses Beispiel funktioniert nur, da cubees ein Kind von ist container. Für kompliziertere Szenarien müssten Sie anderes CSS oder JavaScript verwenden.

Emmett
quelle
35

Die Geschwister - Selektor ist die allgemeine Lösung für andere Elemente Styling , wenn sie über einen gegebenen schwebt, aber es funktioniert nur , wenn die anderen Elemente , die die gegebenen in der DOM folgen . Was können wir tun, wenn die anderen Elemente tatsächlich vor dem schwebenden liegen sollten? Angenommen, wir möchten ein Signalbalken-Bewertungs-Widget wie das folgende implementieren:

Widget zur Bewertung der Signalleiste

Dies kann mithilfe des CSS-Flexbox-Modells problemlos durchgeführt werden, indem flex-directionauf eingestellt wird reverse, sodass die Elemente in der entgegengesetzten Reihenfolge angezeigt werden wie im DOM. Der obige Screenshot stammt von einem solchen Widget, das mit reinem CSS implementiert wurde.

Flexbox wird von 95% der modernen Browser sehr gut unterstützt .

Dan Dascalescu
quelle
Könnte dies bearbeitet werden, damit die Hervorhebung nicht verschwindet, wenn Sie die Maus von einem Balken zum anderen bewegen? Das Blinken ist etwas ablenkend.
Cerbrus
@Cerbrus: Es wurde eine Lösung hinzugefügt, die den Schwebeflug nicht verbirgt, wenn sich die Maus zwischen Balken befindet. Der Nachteil ist, dass die Breite der Balken nicht mehr gleich ist.
Dan Dascalescu
1
Versuchen Sie dies in Ihrem ersten Ausschnitt: auf .rating div, entfernen Sie den Rand und fügen border-right: 4px solid white;
Sie
1
Flex-Richtung (für IE nicht gut unterstützt) ODER 1) Standardmäßig schwarz 2) Alle blau auf der Maus über dem Container 3) Schwarz für das nächste Geschwister auf Bar Hover :)
Stephane Mathis
Ich habe diese Geige gemacht, die es (zumindest für mich) ein bisschen aparenter machte, was hier vor sich ging. jsfiddle.net/maxshuty/cj55y33p/3
maxshuty
8

Vielen Dank an Mike und Robertc für ihre hilfreichen Beiträge!

Wenn Sie zwei Elemente in Ihrem HTML-Code haben und :hoverüber eines hinausgehen und eine Stiländerung im anderen anstreben möchten, müssen die beiden Elemente direkt miteinander verbunden sein - Eltern, Kinder oder Geschwister. Dies bedeutet, dass die beiden Elemente entweder ineinander liegen müssen oder beide in demselben größeren Element enthalten sein müssen.

Ich wollte Definitionen in einem Feld auf der rechten Seite des Browsers anzeigen, während meine Benutzer meine Website und :hoverüber hervorgehobene Begriffe lesen . Daher wollte ich nicht, dass das Element 'definition' im Element 'text' angezeigt wird.

Ich hätte fast aufgegeben und gerade Javascript zu meiner Seite hinzugefügt, aber das ist die Zukunft, verdammt! Wir sollten uns nicht mit CSS und HTML abfinden müssen, die uns sagen, wo wir unsere Elemente platzieren müssen, um die gewünschten Effekte zu erzielen! Am Ende haben wir Kompromisse geschlossen.

Während die tatsächlichen HTML-Elemente in der Datei entweder verschachtelt oder in einem einzelnen Element enthalten sein müssen, um gültige :hoverZiele für einander zu sein, kann das CSS- positionAttribut verwendet werden, um jedes Element anzuzeigen, wo immer Sie möchten. Ich habe position: fix verwendet, um das Ziel meiner :hoverAktion an der gewünschten Stelle auf dem Bildschirm des Benutzers zu platzieren, unabhängig von seiner Position im HTML-Dokument.

Das HTML:

<div id="explainBox" class="explainBox"> /*Common parent*/

  <a class="defP" id="light" href="http://en.wikipedia.or/wiki/Light">Light                            /*highlighted term in text*/
  </a> is as ubiquitous as it is mysterious. /*plain text*/

  <div id="definitions"> /*Container for :hover-displayed definitions*/
    <p class="def" id="light"> /*example definition entry*/ Light:
      <br/>Short Answer: The type of energy you see
    </p>
  </div>

</div>

Das CSS:

/*read: "when user hovers over #light somewhere inside #explainBox
    set display to inline-block for #light directly inside of #definitions.*/

#explainBox #light:hover~#definitions>#light {
  display: inline-block;
}

.def {
  display: none;
}

#definitions {
  background-color: black;
  position: fixed;
  /*position attribute*/
  top: 5em;
  /*position attribute*/
  right: 2em;
  /*position attribute*/
  width: 20em;
  height: 30em;
  border: 1px solid orange;
  border-radius: 12px;
  padding: 10px;
}

In diesem Beispiel muss das Ziel eines :hoverBefehls von einem Element innerhalb oder #explainBoxentweder #explainBoxinnerhalb sein #explainBox. Die Positionsattribute, die #definitions zugewiesen sind, erzwingen, dass es an der gewünschten Stelle (außerhalb #explainBox) angezeigt wird, obwohl es sich technisch an einer unerwünschten Position innerhalb des HTML-Dokuments befindet.

Ich verstehe, dass es als schlechte Form angesehen wird, dasselbe #idfür mehr als ein HTML-Element zu verwenden. In diesem Fall können die Instanzen von #lightjedoch aufgrund ihrer jeweiligen Position in eindeutig #idd-Elementen unabhängig beschrieben werden. Gibt es einen Grund, id #lightdies in diesem Fall nicht zu wiederholen ?

Rick
quelle
Ziemlich lange Antwort für einen so kurzen Punkt, aber hier ist eine jsfiddle davon jsfiddle.net/ubershmekel/bWgq6/1
ubershmekel
1
Einige Browers flippen aus, wenn Sie dasselbe IDmehrmals verwenden. Verwenden Sie einfach eine class.
Serj Sagan
6

Nur das hat bei mir funktioniert:

#container:hover .cube { background-color: yellow; }

Wo .cubeist CssClass der #cube.

Getestet in Firefox , Chrome und Edge .

CyberHawk
quelle
4

Hier ist eine weitere Idee, mit der Sie andere Elemente beeinflussen können, ohne einen bestimmten Selektor zu berücksichtigen und nur den :hoverStatus des Hauptelements zu verwenden.

Dafür werde ich mich auf die Verwendung von benutzerdefinierten Eigenschaften (CSS-Variablen) verlassen. Wie wir in der Spezifikation lesen können :

Benutzerdefinierte Eigenschaften sind normale Eigenschaften , daher können sie für jedes Element deklariert und mit den normalen Vererbungs- und Kaskadenregeln aufgelöst werden .

Die Idee ist, benutzerdefinierte Eigenschaften innerhalb des Hauptelements zu definieren und sie zum Formatieren untergeordneter Elemente zu verwenden. Da diese Eigenschaften vererbt werden, müssen sie beim Hover einfach innerhalb des Hauptelements geändert werden.

Hier ist ein Beispiel:

#container {
  width: 200px;
  height: 30px;
  border: 1px solid var(--c);
  --c:red;
}
#container:hover {
  --c:blue;
}
#container > div {
  width: 30px;
  height: 100%;
  background-color: var(--c);
}
<div id="container">
  <div>
  </div>
</div>

Warum kann dies besser sein als die Verwendung eines bestimmten Selektors in Kombination mit einem Schwebeflug?

Ich kann mindestens zwei Gründe nennen, die diese Methode zu einer guten Überlegung machen:

  1. Wenn wir viele verschachtelte Elemente haben, die dieselben Stile verwenden, vermeiden wir eine komplexe Auswahl, um alle beim Hover anzuvisieren. Mit den benutzerdefinierten Eigenschaften ändern wir einfach den Wert, wenn Sie den Mauszeiger über das übergeordnete Element bewegen.
  2. Eine benutzerdefinierte Eigenschaft kann verwendet werden, um einen Wert einer Eigenschaft und auch einen Teilwert davon zu ersetzen. Zum Beispiel können wir eine benutzerdefinierte Eigenschaft für eine Farbe definieren und wir verwenden es in einem border, linear-gradient, background-color, box-shadowusw. Dadurch wird vermieden , uns alle diese Eigenschaften auf schweben Reseting.

Hier ist ein komplexeres Beispiel:

.container {
  --c:red;
  width:400px;
  display:flex;
  border:1px solid var(--c);
  justify-content:space-between;
  padding:5px;
  background:linear-gradient(var(--c),var(--c)) 0 50%/100% 3px no-repeat;
}
.box {
  width:30%;
  background:var(--c);
  box-shadow:0px 0px 5px var(--c);
  position:relative;
}
.box:before {
  content:"A";
  display:block;
  width:15px;
  margin:0 auto;
  height:100%;
  color:var(--c);
  background:#fff;
}

/*Hover*/
.container:hover {
  --c:blue;
}
<div class="container">
<div class="box"></div>
<div class="box"></div>
</div>

Wie wir oben sehen können, benötigen wir nur eine CSS-Deklaration , um viele Eigenschaften verschiedener Elemente zu ändern.

Temani Afif
quelle