Heim >Web-Frontend >CSS-Tutorial >Wie man auf die Geschwister- () und Geschwister-Index () -Funktionen wartet

Wie man auf die Geschwister- () und Geschwister-Index () -Funktionen wartet

William Shakespeare
William ShakespeareOriginal
2025-03-07 17:13:16240Durchsuche

How to Wait for the sibling-count() and sibling-index() Functions

Die neuen Merkmale von CSS erscheinen nicht aus der Luft, sondern durchlaufen einen langen Prozess: Diskussion, Bewertung, Definition, Schreiben, Prototyping, Testen, Veröffentlichungen, Unterstützung und mehr. Dieser Prozess ist sehr lang, und selbst wenn wir gespannt sind, können wir nur dann warten.

Aber wir können eine andere Wartezeit auswählen: Vermeiden Sie die Schnittstellen oder Demonstrationen mit dieser Funktion vollständig? Oder fordern Sie die Grenzen von CSS heraus und versuchen Sie, es selbst zu implementieren?

Viele unternehmungslustige und neugierige Entwickler haben letztere ausgewählt. Ohne diese Mentalität stagnieren CSS. Also werden wir heute zwei bevorstehende Funktionen untersuchen: sibling-count() und sibling-index(). Wir freuen uns seit vielen Jahren auf sie. Lassen Sie mich meine Neugier fliegen und spüren Sie ihren Charme im Voraus!

Baumzählfunktion

Möglicherweise haben Sie wissen, wo sich ein Element in seinem Geschwisterelement befindet oder wie viele untergeordnete Elemente ein bestimmtes Element hat, um in CSS zu berechnen, z. B. die Implementierung einiger Verschachtelungsanimationen. Jedes Element hat eine längere Verzögerung oder die Änderung der Hintergrundfarbe des Elements basierend auf der Anzahl der Geschwisterelemente. Dies ist seit langem ein seit langem erwartete Projekt auf meiner CSS-Wunschliste. Schauen Sie sich dieses 2017 CSSWG Github -Problem an:

Funktionsanforderung. Es wäre großartig, die calc() -Funktion innerhalb der counter() -Funktion zu verwenden. Dies wird neue Möglichkeiten in das Layout bringen.

Die Funktion counter() verwendet jedoch eine Zeichenfolge, die sie in der calc() -Funktion, die Zahlen übernimmt, nutzlos macht. Wir benötigen einen ähnlichen Satz von Funktionen, die den Index eines Elements und seine Anzahl von Geschwisterelementen in Form eines -Gebars zurückgeben. Dies scheint kein Über nachgefragt zu sein. Derzeit können wir den :nth-child() pseudo-selektor (und seine Varianten) verwenden, um Elemente basierend auf Baumpositionen abzufragen, ganz zu schweigen von der Verwendung des :has() Pseudo-Selektors, um basierend auf der Anzahl der Elemente, die das Element enthält, zu abfragen.

Zum Glück hat CSSWG in diesem Jahr die Implementierung von sibling-count() und sibling-index() Funktionen genehmigt! Einige Inhalte wurden in der Spezifikation geschrieben:

Die Funktion

sibling-count() repräsentiert die Gesamtzahl der untergeordneten Elemente im übergeordneten Element des Elements mit der Funktion, die als <integer></integer> ausgedrückt wird.

Die Funktion

sibling-index() repräsentiert den Index des Elements unter Verwendung der Funktion im untergeordneten Element seines übergeordneten Elements, das durch <integer></integer> dargestellt wird. Ähnlich wie :nth-child() zählt sibling-index() aus 1.

Wie lange dauert es, bis wir sie benutzen? Anfang dieses Jahres sagte Adam Argyle: "Ein Chrom -Ingenieur erwähnte, dass wir dies tun wollten, aber wir haben noch nicht das Logo, um es auszuprobieren. Ich werde es teilen, wenn es Neuigkeiten gibt!" Lassen Sie uns in der Zwischenzeit sehen, was wir jetzt tun können!

Update (5. März 2025): Chrome hat die Absicht eingereicht, diese beiden Funktionen zu prototypisieren.

Originalmethode

In Bezug auf Syntax und Verwendung ist die benutzerdefinierte Eigenschaften am nächsten an einer Baumzählfunktion. Das größte Problem besteht jedoch darin, sie mit den richtigen Indizes und Zählungen zu bevölkern. Der einfachste und längste Weg besteht darin, jeden Wert mit reinem CSS zu harten: Wir können den nth-child() -Alektor verwenden, um jedem Element seinen entsprechenden Index zu geben:

li:nth-child(1) {
  --sibling-index: 1;
}

li:nth-child(2) {
  --sibling-index: 2;
}

li:nth-child(3) {
  --sibling-index: 3;
}

/* 以此类推... */

Einstellung sibling-count() Äquivalente erfordert mehr Feinheiten, da wir die Anzahl der :has() -Sektoren zur Abfrage verwenden müssen. Quantitätsabfrage hat die folgende Syntax:

.container:has(> :last-child:nth-child(m)) { }

… wobei m die Anzahl der Elemente ist, die wir lokalisieren wollen. Es funktioniert, indem es überprüft, ob das letzte Element des Containers auch das n -te Element ist, das wir positionieren. Sie können dieses Tool von Temani AFIF verwenden, um Ihre eigene Menge Abfrage zu erstellen. In diesem Fall sieht unsere Menge Abfrage so aus:

ol:has(> :nth-child(1)) {
  --sibling-count: 1;
}

ol:has(> :last-child:nth-child(2)) {
  --sibling-count: 2;
}

ol:has(> :last-child:nth-child(3)) {
  --sibling-count: 3;
}

/* 以此类推... */

Für die Kürze enthält dieses Beispiel absichtlich nur eine kleine Anzahl von Elementen, aber wenn die Liste wächst, wird es schwierig zu verwalten. Vielleicht können wir Präprozessoren wie Sass verwenden, um sie für uns zu schreiben, aber wir möchten uns hier auf reine CSS -Lösungen konzentrieren. Beispielsweise kann die folgende Demonstration bis zu 12 Elemente unterstützen, und Sie können bereits sehen, wie hässlich der Code ist.

Für diejenigen, die ein Tor erzielen, benötigt es 24 Regeln, um den Index und die Anzahl von 12 Elementen zu verstehen. Wir haben sicherlich das Gefühl, dass wir diese Zahl auf überschaubarere Zahlen reduzieren können, aber wenn wir jeden Index hardcodieren, erhöhen wir die Menge an Code, die wir schreiben. Das Beste, was wir tun können, ist, unser CSS umzuschreiben, damit wir die Eigenschaften --sibling-index und --sibling-count zusammen nisten können. Anstatt jedes Attribut separat zu schreiben:

li:nth-child(2) {
  --sibling-index: 2;
}

ol:has(> :last-child:nth-child(2)) {
  --sibling-count: 2;
}

Wir können die Regeln --sibling-count innerhalb der Regeln --sibling-index nisten.

li:nth-child(2) {
  --sibling-index: 2;

  ol:has(> &:last-child) {
    --sibling-count: 2;
  }
}

Obwohl es seltsam erscheint, das übergeordnete Element in seinem untergeordneten Element zu nisten, ist der folgende CSS -Code vollständig gültig. Welche Syntax ist einfacher zu verwalten? Es hängt von dir ab. li li Aber das ist nur eine kleine Verbesserung. Wenn wir 100 Elemente haben, müssen wir die Eigenschaften ol und

noch 100 Mal hardcodieren. Glücklicherweise fügt die folgende Methode Regeln auf logarithmische Weise hinzu, insbesondere mit Basis 2. Anstatt 100 Regeln für 100 Elemente zu schreiben, müssen wir nur etwa 100 Regeln für etwa 100 Elemente schreiben.

--sibling-index Verbesserungsmethode --sibling-count

Diese Methode wurde erstmals von Roman Komarov im Oktober letzten Jahres beschrieben, wo er die beiden Baumzählfunktionen und die zukünftigen

-Funktionen prototypisierte. Dies ist ein großartiger Beitrag, daher empfehle ich Ihnen dringend, ihn zu lesen.

Diese Methode verwendet auch benutzerdefinierte Eigenschaften. Anstelle von fest codierter Eigenschaft werden wir jedoch zwei benutzerdefinierte Eigenschaften verwenden, um die --sibling-index Eigenschaft jedes Elements zu erstellen. Um mit den Artikeln von Roman übereinzustimmen, nennen wir sie --si1 und --si2, beide ab 0:

li:nth-child(1) {
  --sibling-index: 1;
}

li:nth-child(2) {
  --sibling-index: 2;
}

li:nth-child(3) {
  --sibling-index: 3;
}

/* 以此类推... */

Das reale --sibling-index wird unter Verwendung dieser beiden Eigenschaften und eines -Faktors (f) konstruiert, was eine ganze oder gleiche Zahl darstellt, die uns die Anzahl der Elemente zeigt, die gemäß der Formel sqrt(F) - 1 ausgewählt werden können. Also ...

  • Für Faktor 2 können wir 3 Elemente auswählen.
  • Für Faktor 3 können wir 8 Elemente auswählen.
  • Für Faktor 5 können wir 24 Elemente auswählen.
  • Für Faktor 10 können wir 99 Elemente auswählen.
  • Für Faktor 25 können wir 624 Elemente auswählen.

Wie Sie sehen können, erhöht die Erhöhung des Faktors um 1 die Anzahl der Elemente, die wir exponentiell wählen können. Aber wie übersetzt sich das in CSS?

Das erste, was zu wissen ist, ist, dass die Formel zur Berechnung der Attribute von --sibling-index calc(F * var(--si2) var(--si1)) ist. Wenn unser Faktor 3 ist, sieht es so aus:

.container:has(> :last-child:nth-child(m)) { }

Der Selektor unten mag zufällig sein, aber bitte seien Sie mit mir geduldig zu erklären. Für das Attribut --si1 werden wir eine Regel für Elemente schreiben, die als Vielfache des Faktors ausgewählt wurden, und sie um 1 bis F - 1 ausschalten und dann --si1 als Offset einstellen. Dies bedeutet das folgende CSS:

ol:has(> :nth-child(1)) {
  --sibling-count: 1;
}

ol:has(> :last-child:nth-child(2)) {
  --sibling-count: 2;
}

ol:has(> :last-child:nth-child(3)) {
  --sibling-count: 3;
}

/* 以此类推... */

Wenn unser Faktor 3 ist, schreiben wir die folgenden Regeln, bis wir F-1 erreichen, dh 2 Regeln:

li:nth-child(2) {
  --sibling-index: 2;
}

ol:has(> :last-child:nth-child(2)) {
  --sibling-count: 2;
}

Für das Attribut --si2 werden wir Regeln für die Auswahl von Elementen mit der Anzahl der Elemente in Stapeln als Faktoren schreiben (wenn unser Faktor 3 ist, werden wir 3 Elemente pro Regel auswählen) und bewegt sich nach dem letzten möglichen Index (in diesem Fall 8), bis wir nicht mehr Elemente in Stapeln auswählen können. Dies ist etwas kompliziert, um in CSS zu schreiben:

li:nth-child(2) {
  --sibling-index: 2;

  ol:has(> &:last-child) {
    --sibling-count: 2;
  }
}

In ähnlicher Weise werden wir, wenn unser Faktor 3 ist, die folgenden zwei Regeln schreiben:

li {
  --si1: 0;
  --si2: 0;
}

Das ist es! Indem wir nur die Werte --si1 und --si2 festlegen, können wir bis zu 8 Elemente berechnen. Die mathematischen Berechnungen dahinter sehen auf den ersten Blick seltsam aus, aber sobald Sie es intuitiv verstanden haben, ist alles klar. Ich habe diese interaktive Demo gemacht, in der Sie mit dieser Formel sehen können, wie Sie auf alle Elemente zugreifen können. Bewegen Sie sich über das Code -Snippet, um zu sehen, welche Elemente Sie auswählen können, und klicken Sie auf jeden Code -Snippet, um sie zu einem möglichen Index zu kombinieren.

Wenn Sie Elemente und Faktoren maximal anpassen, werden Sie feststellen, dass wir 48 Elemente mit nur 14 Code -Snippets auswählen können!

usw. fehlt eine Sache: sibling-count() Funktion. Zum Glück werden wir alles wiederverwenden, was wir aus sibling-index() Prototyping gelernt haben. Wir beginnen mit zwei benutzerdefinierten Eigenschaften: --sc1 und --sc1 im Container, und beide beginnen auch mit 0. Die Formel zur Berechnung --sibling-count ist gleich.

li:nth-child(1) {
  --sibling-index: 1;
}

li:nth-child(2) {
  --sibling-index: 2;
}

li:nth-child(3) {
  --sibling-index: 3;
}

/* 以此类推... */

Romans Artikel erklärt auch, wie Sie Selektoren für --sibling-count -attribute separat schreiben, aber wir werden die :has() -Se -Auswahlmethode in unserer ersten Technik verwenden, damit wir keine zusätzlichen Selektoren schreiben müssen. Wir können diese --sc1 und --sc2 Eigenschaften in die Regeln stopfen, die wir sibling-index() Eigenschaften definieren:

.container:has(> :last-child:nth-child(m)) { }

Dies verwendet Faktor 3, sodass wir bis zu acht Elemente mit nur vier Regeln berechnen können. Das folgende Beispiel hat einen Faktor von 7, sodass wir mit nur 14 Regeln bis zu 48 Elemente berechnen können.

Diese Methode ist großartig, aber wahrscheinlich nicht für jedermann, weil sie fast magisch funktioniert oder einfach weil Sie sie nicht ästhetisch ansprechend finden. Dies ist zwar leicht für diejenigen, die gerne mit Feuerstein und Stahl Feuer machen möchten, aber viele Menschen können ihr Feuer nicht entzünden.

JavaScript -Methode

Für diesen Ansatz werden wir erneut benutzerdefinierte Eigenschaften verwenden, um die Baumzählfunktion zu simulieren, und am besten werden wir weniger als 20 Codezeilen schreiben, um es in Unendlichkeit zu berechnen-oder ich würde sagen, 1.7976931348623157e 308, was die Grenze für Doppel-Präzisionsfloat-Punktnummern ist!

Wir werden die Mutationsbeobachter -API verwenden, so dass JavaScript natürlich erforderlich ist. Ich weiß, dass es so ist, als würde man viele Menschen ein Scheitern zugeben, aber ich stimme nicht zu. Wenn die JavaScript -Methode einfacher ist (was in diesem Fall in der Tat der Fall ist), ist dies die am besten geeignete Wahl. Wenn die Leistung Ihr Hauptanliegen ist, halten Sie sich übrigens in CSS oder HTML an Hardcode jeden Index.

Erstens erhalten wir unseren Container aus dem DOM:

ol:has(> :nth-child(1)) {
  --sibling-count: 1;
}

ol:has(> :last-child:nth-child(2)) {
  --sibling-count: 2;
}

ol:has(> :last-child:nth-child(3)) {
  --sibling-count: 3;
}

/* 以此类推... */

Wir erstellen dann eine Funktion, die das Attribut --sibling-index in jedem Element und --sibling-count im Container festlegt (es steht aufgrund der Kaskade für untergeordnete Elemente zur Verfügung). Für --sibling-index müssen wir über elements.children iterieren, und wir können elements.children.length von --sibling-count erhalten.

li:nth-child(2) {
  --sibling-index: 2;
}

ol:has(> :last-child:nth-child(2)) {
  --sibling-count: 2;
}

Sobald wir unsere Funktion haben, denken Sie daran, sie einmal so aufzurufen, damit wir die Eigenschaft der anfänglichen Baumzählungen haben:

li:nth-child(2) {
  --sibling-index: 2;

  ol:has(> &:last-child) {
    --sibling-count: 2;
  }
}

Zuletzt Mutationsbeobachter. Wir müssen einen neuen Beobachter mit dem MutationObserver -Konstruktor initialisieren. Es akzeptiert eine Rückruffunktion, die jedes Mal aufgerufen wird, wenn sich das Element ändert, und wir haben die updateCustomProperties -Funktion geschrieben. Mit dem generierten Observer -Objekt können wir seine observe() -Methode aufrufen, die zwei Parameter akzeptiert:

  1. Die Elemente, die wir beobachten wollen, und
  2. Ein Konfigurationsobjekt, das definiert, was wir durch drei boolesche Eigenschaften beobachten möchten: attributes, childList und subtree. In diesem Fall möchten wir nur nach Änderungen in childList überprüfen, also setzen wir die Eigenschaft auf true:
li:nth-child(1) {
  --sibling-index: 1;
}

li:nth-child(2) {
  --sibling-index: 2;
}

li:nth-child(3) {
  --sibling-index: 3;
}

/* 以此类推... */

Das ist alles, was wir tun müssen! Mit dieser Methode können wir viele Elemente berechnen, in der folgenden Demonstration setze ich den Maximalwert auf 100, erreicht aber leicht zehnmal:

Also ja, das ist unser Flammenwerfer. Es entzündet sicherlich die Flamme, aber für die überwiegende Mehrheit der Anwendungsfälle ist es zu mächtig. Aber das haben wir, wenn wir auf das perfekte Feuerzeug warten.

Was wirst du als nächstes tun?

Ich habe keine Zeitmaschine, also kann ich nicht sagen, wann die Funktionen sibling-index() und sibling-count() veröffentlicht werden. CSSWG hat jedoch etwas in der Spezifikation geschrieben, und der Browser (hauptsächlich Chromium), die Dinge zu veröffentlichen, war in letzter Zeit sehr stark. Ich glaube, wir werden diese beiden Funktionen bald sehen!

Glücklicherweise müssen Sie diese benutzerdefinierten Eigenschaften nur auf denselben Namen wie ihre Funktion festlegen, sobald sie veröffentlicht wurden und die Unterstützung akzeptabel ist. Wenn Sie CSS nicht ändern möchten, um jedes benutzerdefinierte Attribut zu ändern, können Sie dies auch tun:

.container:has(> :last-child:nth-child(m)) { }
Weitere Informationen und Tutorials

    Mögliche zukünftige CSS: Baumzählfunktionen und zufällige Werte (Roman Komarov)
  • Übergänge ansehen, die staffeln (Chris Coyier)
  • Elementindizes (Chris Coyier)
verwandte Fragen

    Aktivieren Sie die Verwendung von counter () in calc () #1026
  • Vorschlag: Fügen Sie Geschwister-count () und Geschwister-Index () #4559
  • hinzu
  • Geschwister-Index () und Geschwister-count () mit einem Selektorargument #9572
  • erweitern
  • Vorschlag: Kinder- und count () Funktion #11068
  • Vorschlag: Nachkommen-count () Funktion #11069
Diese überarbeitete Ausgabe verwaltet das Originalbild und sein Format, setzt Sätze und Absätze auf, um Paraphrasierung zu erreichen, ohne die Kernbedeutung zu ändern, und verwendet eine prägnantere und ansprechende Sprache.

Das obige ist der detaillierte Inhalt vonWie man auf die Geschwister- () und Geschwister-Index () -Funktionen wartet. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn