Kann CSS die Anzahl der untergeordneten Elemente eines Elements ermitteln?


304

Ich beantworte wahrscheinlich meine eigene Frage, bin aber sehr neugierig.

Ich weiß, dass CSS einzelne Kinder eines Elternteils auswählen kann, aber es gibt Unterstützung, um die Kinder eines Containers zu formatieren, wenn sein Elternteil eine bestimmte Anzahl von Kindern hat.

beispielsweise

container:children(8) {
  // style the parent this way if there are 8 children
}

Ich weiß, dass es komisch klingt, aber mein Manager hat mich gebeten, es zu überprüfen. Ich habe selbst nichts gefunden, also habe ich beschlossen, mich vor Beendigung der Suche an SO zu wenden.


Antworten:


695

Klärung:

Aufgrund einer früheren Formulierung in der ursprünglichen Frage haben einige SO-Bürger Bedenken geäußert, dass diese Antwort irreführend sein könnte. Beachten Sie, dass in CSS3 Stile nicht auf einen übergeordneten Knoten angewendet werden können, basierend auf der Anzahl der untergeordneten Knoten . Stile können jedoch basierend auf der Anzahl der Geschwister auf die untergeordneten Knoten angewendet werden.


Ursprüngliche Antwort:

Unglaublicherweise ist dies jetzt nur noch in CSS3 möglich.

/* one item */
li:first-child:nth-last-child(1) {
/* -or- li:only-child { */
    width: 100%;
}

/* two items */
li:first-child:nth-last-child(2),
li:first-child:nth-last-child(2) ~ li {
    width: 50%;
}

/* three items */
li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
    width: 33.3333%;
}

/* four items */
li:first-child:nth-last-child(4),
li:first-child:nth-last-child(4) ~ li {
    width: 25%;
}

Der Trick besteht darin, das erste Kind auszuwählen, wenn es auch das n-te vom letzten Kind ist. Dies wählt effektiv basierend auf der Anzahl der Geschwister aus.

Der Verdienst für diese Technik geht an André Luís (entdeckt) und Lea Verou (verfeinert).

Liebst du nicht einfach CSS3? 😄

CodePen Beispiel:

Quellen:


7
Sehr praktisch. Ich habe ein SASS-Mixin geschrieben, das diese Technik verwendet: codepen.io/anon/pen/pJeLdE?editors=110
SimpleJ

1
@ IanSteffy Ich habe dies gerade auf Chrome 45.0.2454.85 (64-Bit) getestet und es funktioniert gut…?
Matthemattics

2
Wenn es in Codepen funktioniert, aber nicht mit meinem Projekt, dann ist es definitiv meine Schuld. Mein Fehler. Diese Antwort ist richtig! Richtig, sage ich!
Ian S

3
Könnte schön sein, hinzuzufügen, warum dies funktioniert, für Leute, die nicht an mehrere Pseudo-Selektoren gewöhnt sind (wie ich es bisher war;). Was hier passiert, ist, dass dies das Kind auswählt, das gleichzeitig Kind x von Anfang / oben und Kind y von Ende ist. Und so wird nur dann etwas ausgewählt, wenn es genau x + y Kinder gibt.
Legolas

7
Beachten Sie, dass anstelle von :first-child:nth-last-child(1)Sie auch verwenden können :only-child.
Adam Reis

40

Nun, nicht wirklich. Es gibt einige Selektoren, die Sie etwas näher bringen können, aber in Ihrem Beispiel wahrscheinlich nicht funktionieren und nicht die beste Browserkompatibilität aufweisen.

:only-child

Dies :only-childist einer der wenigen echten Zählselektoren in dem Sinne, dass er nur angewendet wird, wenn ein untergeordnetes Element des übergeordneten Elements des Elements vorhanden ist. Anhand Ihres idealisierten Beispiels verhält es sich wie children(1)wahrscheinlich.

:nth-child

Der :nth-childSelektor bringt Sie möglicherweise tatsächlich dahin, wo Sie hin möchten, je nachdem, was Sie wirklich tun möchten. Wenn Sie alle Elemente stylen möchten, wenn 8 Kinder vorhanden sind, haben Sie kein Glück. Wenn Sie jedoch Stile auf das 8. und spätere Element anwenden möchten, versuchen Sie Folgendes:

p:nth-child( n + 8 ){
    /* add styles to make it pretty */
}

Leider sind dies wahrscheinlich nicht die Lösungen, nach denen Sie suchen. Am Ende müssen Sie wahrscheinlich einige Javascript-Assistenten verwenden, um die Stile basierend auf der Anzahl anzuwenden. Selbst wenn Sie einen dieser Stile verwenden würden, müssten Sie sich die Browserkompatibilität genau ansehen, bevor Sie mit einem reinen Stil beginnen CSS-Lösung.

W3 CSS3-Spezifikation für Pseudoklassen

BEARBEITEN Ich habe Ihre Frage etwas anders gelesen - es gibt noch ein paar andere Möglichkeiten, die Eltern zu stylen , nicht die Kinder. Lassen Sie mich ein paar andere Selektoren auf Ihren Weg werfen:

:empty und :not

Dadurch werden Elemente formatiert, die keine untergeordneten Elemente haben. Für sich genommen nicht so nützlich, aber in Verbindung mit dem :notSelektor können Sie nur die Elemente formatieren, die untergeordnete Elemente haben:

div:not(:empty) {
    /* We know it has stuff in it! */
}

Sie können hier nicht zählen, wie viele Kinder mit reinem CSS verfügbar sind, aber es ist ein weiterer interessanter Selektor, mit dem Sie coole Dinge tun können.


Es ist erwähnenswert, dass die ursprüngliche Frage bearbeitet wurde, wodurch das anfängliche "Nein" etwas irreführend wird (nur zu Ihrer Information)
Matthemattics

18

HINWEIS: Diese Lösung gibt die untergeordneten Elemente von Sätzen bestimmter Länge zurück, nicht das von Ihnen angeforderte übergeordnete Element. Hoffentlich ist es immer noch nützlich.

Andre Luis hat eine Methode entwickelt: http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/ Leider funktioniert sie nur in IE9 und höher.

Im Wesentlichen kombinieren Sie: nth-child () mit anderen Pseudoklassen, die sich mit der Position eines Elements befassen. Mit diesem Ansatz können Sie Elemente aus Elementmengen mit bestimmten Längen angeben .

Entspricht beispielsweise :nth-child(1):nth-last-child(3)dem ersten Element in einer Menge und ist gleichzeitig das dritte Element am Ende der Menge. Dies macht zwei Dinge: garantiert, dass die Menge nur drei Elemente hat und dass wir das erste der drei haben. Um das zweite Element des Drei-Elemente-Satzes anzugeben, würden wir verwenden :nth-child(2):nth-last-child(2).


Beispiel 1 - Wählen Sie alle Listenelemente aus, wenn set drei Elemente enthält:

li:nth-child(1):nth-last-child(3),
li:nth-child(2):nth-last-child(2),
li:nth-child(3):nth-last-child(1) {
    width: 33.3333%;
}

Beispiel 1 Alternative von Lea Verou:

li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
    width: 33.3333%;
}


Beispiel 2 - Ziel letztes Element der Menge mit drei Listenelementen:

li:nth-child(3):last-child {
    /* I'm the last of three */
}

Beispiel 2 Alternative:

li:nth-child(3):nth-last-child(1) {
    /* I'm the last of three */
}


Beispiel 3 - zweites Zielelement der Menge mit vier Listenelementen:

li:nth-child(2):nth-last-child(3) {
    /* I'm the second of four */
}

1
Auch dies ist die Anzahl der Geschwister, nicht der Kinder
TMS

@TMS siehe akzeptierte Antwort bearbeiten - die Frage des OP wurde unbeholfen formuliert
ifugu

Dieser Ansatz ist perfekt, wenn jedes Element basierend auf seiner Position in der Liste anders gestaltet werden muss, z. B. um gleichmäßige zirkuläre Transformationen zu erhalten: li:nth-child(3):nth-last-child(1) { transform: rotate(120deg); } li:nth-child(2):nth-last-child(2) { transform: rotate(240deg); }und so weiter ...
Greg Smith

11

Ausgehend von Matts Lösung habe ich die folgende Compass / SCSS-Implementierung verwendet.

@for $i from 1 through 20 {
    li:first-child:nth-last-child( #{$i} ),
    li:first-child:nth-last-child( #{$i} ) ~ li {
      width: calc(100% / #{$i} - 10px);
    }
  }

Auf diese Weise können Sie die Anzahl der Elemente schnell erweitern.


4
Stattdessen könnten Sie leicht Flexbox verwenden…
Michał Miszczyszyn

6

Ja, wir können das mit dem n-ten Kind so machen

div:nth-child(n + 8) {
    background: red;
}

Dadurch wird das Kind der 8. Division rot. Hoffe das hilft...

Auch wenn jemand jemals sagt "Hey, er kann nicht mit CSS gestylt werden, benutze JS !!!" bezweifle sie sofort. CSS ist heutzutage äußerst flexibel

Beispiel :: http://jsfiddle.net/uWrLE/1/

Im Beispiel sind die ersten 7 Kinder blau, dann sind 8 rot ...


1
Vielleicht eine Notiz über den unglücklichen Mangel an Unterstützung hinzufügen ?
Benesch

2
Ich denke nicht, dass dies genau das ist, was Brodie verlangt - dies wird die Kinder nach einer bestimmten Menge stylen, kann aber den Vorfahren / das enthaltende Element nicht basierend auf der Anzahl seiner Kinder auswählen.
Ben Hull

Dies sind tatsächlich einige ziemlich gute Informationen, danke Alan, aber Biene hat Recht. Ich habe versucht zu sagen: "Wenn ein Element so viele Kinder hat, haben wir diesen Stil." Wenn ich mich nicht irre, würde Ihre Methode das 8. Kind stylen, aber das Die ersten 7 wären einsam und nackt.
Brodie

@primatology - Der einzige Browser, der das n-te Kind nicht unterstützt, ist IE <9. Alle anderen haben es zwei Versionen zurück oder mehr unterstützt.
Rob

-1 Dies wird das Div-Kind nicht rot machen, dies wird das Div-Rot basierend auf seiner Anzahl innerhalb seiner Geschwister rot machen ! Ist in keiner Weise mit Divs Kind verwandt!
TMS

5

Wenn Sie dies in reinem CSS (mit scss) tun möchten, aber unterschiedliche Elemente / Klassen in derselben übergeordneten Klasse haben, können Sie diese Version verwenden !!

  &:first-of-type:nth-last-of-type(1) {
    max-width: 100%;
  }

  @for $i from 2 through 10 {
    &:first-of-type:nth-last-of-type(#{$i}),
    &:first-of-type:nth-last-of-type(#{$i}) ~ & {
      max-width: (100% / #{$i});
    }
  }

-1

Nein, so etwas gibt es in CSS nicht. Sie können jedoch JavaScript verwenden, um die Anzahl der untergeordneten Elemente zu berechnen und Stile anzuwenden.


1
@ Lübnah Kannst du erklären warum es nicht stimmt?
Gabriel Santos
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.