Wenden Sie CSS-Stile abhängig von den untergeordneten Elementen auf ein Element an

203

Ist es möglich, einen CSS-Stil für ein Element zu definieren, der nur angewendet wird, wenn das übereinstimmende Element ein bestimmtes Element enthält (als direktes untergeordnetes Element)?

Ich denke, das lässt sich am besten anhand eines Beispiels erklären.

Hinweis : Ich versuche, das übergeordnete Element zu formatieren , je nachdem, welche untergeordneten Elemente es enthält.

<style>
  /* note this is invalid syntax. I'm using the non-existing
   ":containing" pseudo-class to show what I want to achieve. */
  div:containing div.a { border: solid 3px red; }
  div:containing div.b { border: solid 3px blue; }
</style>

<!-- the following div should have a red border because
     if contains a div with class="a" -->
<div>
  <div class="a"></div>
</div>

<!-- the following div should have a blue border -->
<div>
  <div class="b"></div>
</div>

Anmerkung 2 : Ich weiß, dass ich dies mit Javascript erreichen kann, aber ich habe mich nur gefragt, ob dies mit einigen unbekannten (für mich) CSS-Funktionen möglich ist.

M4N
quelle
1
Möglicherweise möchten Sie die Frage so aktualisieren, dass sie möglicherweise mit blinkendem Fettdruck angibt, dass Sie versuchen, das PARENT-Div und nicht seine untergeordneten Elemente zu formatieren. Ich weiß, dass Informationen in der Frage selbst enthalten sind, aber wenn Sie nicht eine Menge falscher Antworten erhalten möchten, ist es wahrscheinlich die Mühe wert.
Seth Petry-Johnson
Danke @Seth. Ich habe versucht, den Titel und den Text der Frage zu verbessern. Bitte bearbeiten Sie die Frage, wenn Sie der Meinung sind, dass sie noch unklar ist.
M4N
3
Mögliches Duplikat von Gibt es einen übergeordneten CSS-Selektor?
James Donnelly
Dies ist das perfekte Beispiel dafür, warum diese Art der Unterstützung in CSS ideal wäre: ol < li:nth-child(n+10) { margin-left: 2rem; } ol < li:nth-child(n+100) { margin-left: 3rem; } ol < li:nth-child(n+1000) { margin-left: 4rem; }In einer idealen Welt würde dies die Marge der CSS erhöhenol von der Anzahl der enthaltenen liKinder abhängigen Kinder so dass der Spielraum auf der linken Seite nur so breit wäre wie er musste sein.
Jonmark Weber

Antworten:

124

Soweit mir bekannt ist, ist das Stylen eines übergeordneten Elements basierend auf dem untergeordneten Element keine verfügbare Funktion von CSS. Dafür benötigen Sie wahrscheinlich Skripte.

Es wäre wunderbar, wenn Sie so etwas tun könnten div[div.a]oder div:containing[div.a]wie Sie sagten, aber das ist nicht möglich.

Vielleicht möchten Sie sich jQuery ansehen . Die Selektoren funktionieren sehr gut mit 'enthaltenden' Typen. Sie können das div basierend auf seinem untergeordneten Inhalt auswählen und dann eine CSS-Klasse in einer Zeile auf das übergeordnete Element anwenden.

Wenn Sie jQuery verwenden, könnte etwas in dieser Richtung funktionieren (ungetestet, aber die Theorie ist da):

$('div:has(div.a)').css('border', '1px solid red');

oder

$('div:has(div.a)').addClass('redBorder');

kombiniert mit einer CSS-Klasse:

.redBorder
{
    border: 1px solid red;
}

Hier ist die Dokumentation für den jQuery-Selektor "has" .

KP.
quelle
15
Randnotiz: Für eine bessere Leistung :hasempfiehlt die jQuery-Dokumentseite für den Selektor, die .has()Methode ( api.jquery.com/has ) => zu verwenden, die auf die aktuelle Frage angewendet wird, die sie zum Beispiel geben würde$('div').has('div.a').css('border', '1px solid red');
Frosty Z
Damit dies funktioniert, müsste man einen Mutationsbeobachter verwenden, um zu überprüfen, ob das Kind seinen Zustand geändert hat ...
Legends
Dies beantwortet nicht wirklich die Frage "Gibt es eine Möglichkeit, dies mit CSS zu tun?". Darin heißt es eindeutig: "Ich weiß, dass ich dies mit Javascript erreichen kann, aber ich habe mich nur gefragt, ob dies mit einigen unbekannten (für mich) CSS-Funktionen möglich ist."
SunshinyDoyle
developer.mozilla.org/en-US/docs/Web/CSS/:has , ich denke, dieser :hasSelektor kann funktionieren, aber er ist in der Entwurfsversion und wird von keinem Browser unterstützt.
AliF50
62

Grundsätzlich nein. Das Folgende wäre das, wonach Sie theoretisch gesucht haben:

div.a < div { border: solid 3px red; }

Leider existiert es nicht.

Es gibt ein paar Zuschreibungen nach dem Motto "Warum zum Teufel nicht". Ein gut ausgearbeiteter von Shaun Inman ist ziemlich gut:

http://www.shauninman.com/archive/2008/05/05/css_qualified_selectors

Justin Wignall
quelle
34
Nur ein Update 8 Jahre später: Es gibt immer noch keine Unterstützung für diese Auswahlmethode.
Kraang Prime
1
Es gibt einen Arbeitsentwurf für diese Funktion in Form einer :has()Pseudoklasse, der jedoch nur in CSS4 verwendet werden kann. Bis jetzt (Ende 2019) ist JS immer noch der einzige Weg, um diese Funktionalität zu erreichen.
zepp.lee
Ich glaube, dies wird keine CSS-Stile aktivieren, es wird immer noch Javascript benötigen, um den Selektor zu verwenden. Es sei denn, dies hat sich geändert?
Justin Wignall
3
9 Jahre und denken sie, dass diese Funktion unnötig ist?
Loi Nguyen Huynh
1

Zusätzlich zur Antwort von @ kp:

Ich beschäftige mich damit und in meinem Fall muss ich ein untergeordnetes Element anzeigen und die Höhe des übergeordneten Objekts entsprechend korrigieren (die automatische Größenänderung funktioniert in einem Bootstrap-Header aus irgendeinem Grund nicht, für den ich keine Zeit zum Debuggen habe). .

Aber anstatt Javascript zum Ändern des übergeordneten Elements zu verwenden, werde ich dem übergeordneten Element dynamisch eine CSS-Klasse hinzufügen und die untergeordneten Elemente CSS-selektiv entsprechend anzeigen. Dadurch bleiben die Entscheidungen in der Logik erhalten und basieren nicht auf einem CSS-Status.

tl; dr; Wenden Sie die Stile aund bauf die Eltern an <div>, nicht auf das Kind (natürlich kann dies nicht jeder. Das heißt, Winkelkomponenten, die ihre eigenen Entscheidungen treffen).

<style>
  .parent            { height: 50px; }
  .parent div        { display: none; }
  .with-children     { height: 100px; }
  .with-children div { display: block; }
</style>

<div class="parent">
  <div>child</div>
</div>

<script>
  // to show the children
  $('.parent').addClass('with-children');
</script>
Mauricio Morales
quelle
0

In meinem Fall musste ich das Auffüllen von Zellen eines Elements ändern, das ein Eingabe-Kontrollkästchen für eine Tabelle enthielt, die mit DataTables dynamisch gerendert wird:

<td class="dt-center">
    <input class="a" name="constCheck" type="checkbox" checked="">
</td>

Nachdem ich den folgenden Zeilencode in der initComplete- Funktion implementiert hatte, konnte ich das richtige Auffüllen erzeugen, wodurch die Anzeige der Zeilen mit einer ungewöhnlich großen Höhe behoben wurde

 $('tbody td:has(input.a)').css('padding', '0px');

Jetzt können Sie sehen, dass die richtigen Stile auf das übergeordnete Element angewendet werden:

<td class=" dt-center" style="padding: 0px;">
    <input class="a" name="constCheck" type="checkbox" checked="">
</td>

Im Wesentlichen ist diese Antwort eine Erweiterung der Antwort von @ KP, aber je mehr Zusammenarbeit bei der Implementierung, desto besser. Zusammenfassend hoffe ich, dass dies jemand anderem hilft, weil es funktioniert! Zum Schluss vielen Dank @KP, dass Sie mich in die richtige Richtung geführt haben!

Meilen
quelle