Schleifen in CSS-Präprozessoren

Avatar of Miriam Suzanne
Miriam Suzanne am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Wenn Sie jemals alte Sci-Fi-Streifen gesehen haben, wissen Sie, wie mächtig Schleifen sein können. Füttern Sie Ihren Roboter-Erzfeind mit einer Endlosschleife und – kaboom. Roboterdunst.

Präprozessor-Schleifen führen nicht zu dramatischen Explosionen im Weltraum (hoffentlich), aber sie sind nützlich für das Schreiben von DRY-CSS. Während alle über Pattern-Bibliotheken und modulares Design sprechen, hat sich der Großteil des Fokus auf CSS-Selektoren gerichtet. Egal, welches Akronym Ihre Selektoren antreibt (BEM, OOCSS, SMACSS, ETC), Schleifen können dazu beitragen, Ihre Muster lesbarer und wartbarer zu gestalten, indem sie direkt in Ihren Code eingebettet werden.

Wir werden uns ansehen, was Schleifen leisten können und wie man sie in den wichtigsten CSS-Präprozessoren verwendet: Sass, Less und Stylus. Jede Sprache bietet eine einzigartige Syntax, aber alle erfüllen ihren Zweck. Es gibt mehr als eine Möglichkeit, eine Katze zu schleifen.

Siehe den Pen
Walkcycle mit Musik-Schleife
von CSS-Tricks (@css-tricks)
auf CodePen.

(Animation von Rachel Nabors)

PostCSS ist ebenfalls beliebt, bietet aber keine eigene Syntax. Obwohl es manchmal als Post-Prozessor bezeichnet wird, würde ich es als Meta-Präprozessor bezeichnen. PostCSS ermöglicht es Ihnen, Ihre eigene Präprozessor-Syntax zu schreiben und zu teilen. Wenn Sie wollten, könnten Sie Sass oder Less innerhalb von PostCSS neu schreiben, aber jemand war schneller als Sie.

Schleifenbedingungen

Star Trek lag nicht ganz falsch. Wenn Sie nicht vorsichtig sind, können Endlosschleifen Ihren Compiler verlangsamen oder zum Absturz bringen. Das ist zwar keine gute Methode, um böse Roboter zu verdampfen, aber es wird jeden, der Ihren Code verwendet, verärgern. Deshalb sollten Schleifen immer einem begrenzten Zweck dienen – normalerweise definiert durch eine Anzahl von inkrementellen Wiederholungen oder eine Sammlung von Objekten.

In Programmierbegriffen

  1. While-Schleifen sind generisch und laufen weiter, solange eine Bedingung erfüllt ist. Vorsicht! Hier sind Endlosschleifen am wahrscheinlichsten.
  2. For-Schleifen sind inkrementell und laufen für eine bestimmte Anzahl von Wiederholungen.
  3. For-Each-Schleifen iterieren durch eine Sammlung oder Liste und berücksichtigen jedes Element nacheinander.

Jeder Schleifentyp ist enger gefasst als der vorherige. Eine for-each-Schleife ist nur eine Art von for-Schleife, die wiederum eine Art von while-Schleife ist. Aber die meisten Ihrer Anwendungsfälle werden in die spezifischeren Kategorien fallen. Ich hatte Schwierigkeiten, echte while-Schleifen im echten Leben zu finden – die meisten Beispiele hätten besser mit for oder for-each behandelt werden können. Deshalb bietet Stylus nur Syntax für Letzteres. Sass bietet eine einzigartige Syntax für alle drei, und Less hat technisch gesehen überhaupt keine Schleifensyntax – aber das wird uns nicht aufhalten! Tauchen wir ein.

for-each-Schleifen für Sammlungen

Präprozessor-Schleifen sind am nützlichsten, wenn Sie eine Sammlung (Liste oder Array) von Elementen haben, über die Sie iterieren möchten – wie ein Array von Social-Media-Icons und Farben oder eine Liste von Zustandsmodifikatoren (success, warning, error usw.). Da for-each-Schleifen an eine bekannte Sammlung von Elementen gebunden sind, sind sie tendenziell die konkretesten und verständlichsten Schleifen.

Beginnen wir mit der Iteration über eine einfache Liste von Farben, um zu sehen, wie es funktioniert.

In Sass verwenden wir die Direktive @each (@each $item in $list), um auf die Farben zuzugreifen

Siehe den Pen Sass ForEach Liste von Miriam Suzanne (@mirisuzanne) auf CodePen.

In Stylus übernimmt die for-Syntax (for item in list) Sammlungen

Siehe den Pen Stylus ForEach Liste von Miriam Suzanne (@mirisuzanne) auf CodePen.

Less bietet keine Schleifensyntax, aber wir können sie mit Rekursion simulieren. Rekursion ist das, was passiert, wenn man eine Funktion oder einen Mixin aus sich selbst heraus aufruft. In Less können wir Mixins für Rekursion verwenden

.recursion() {
  /* an infinite recursive loop! */
  .recursion();
}

Nun fügen wir dem Mixin eine when "Guard" hinzu, um eine Endlosschleife zu verhindern.

.recursion() when (@conditions) { 
  /* a conditional recursive "while" loop! */
  .recursion();
}

Wir können daraus eine for-Schleife machen, indem wir einen Zähler (@i) hinzufügen, der bei 1 beginnt und sich bei jeder Wiederholung erhöht (@i + 1), solange unsere Bedingung (@i <= length(@list)) erfüllt ist – wobei length(@list) unsere Schleifeniterationen auf die gleiche Länge wie unsere Sammlung begrenzt. Wenn wir bei jedem Durchgang das nächste Listenelement extrahieren, erhalten wir eine handgemachte for-each-Schleife

Siehe den Pen Less ForEach Liste von Miriam Suzanne (@mirisuzanne) auf CodePen.

In Less muss man alles auf die harte Tour machen. Das bildet Charakter.

Social-Media-Buttons

Das Iterieren über Listen kann nützlich sein, aber öfter möchte man über Objekte iterieren. Ein gängiges Beispiel ist die Zuweisung verschiedener Farben und Icons zu Ihren Social-Media-Buttons. Für jedes Element in der Liste benötigen wir den Namen der Website und die Markenfarbe für dieses soziale Netzwerk

$social: (
  'facebook': #3b5999,
  'twitter': #55acee,
  'linkedin': #0077B5,
  'google': #dd4b39,
);

Mit Sass können wir über die Syntax @each $key, $value in $array auf den Schlüssel (Netzwerknamen) und den Wert (Markenfarbe) jedes Paares zugreifen. Hier ist die vollständige Schleife

Siehe den Pen Sass Social Media Schleife von Miriam Suzanne (@mirisuzanne) auf CodePen.

Stylus hat eine ähnliche Syntax: for key, value in array

Siehe den Pen Stylus Social Media Schleife von Miriam Suzanne (@mirisuzanne) auf CodePen.

In Less müssen wir jedes Element des Paares manuell extrahieren

Siehe den Pen LESS Social Media Schleife von Miriam Suzanne (@mirisuzanne) auf CodePen.

Inkrementelle for-Schleifen

For-Schleifen können für eine beliebige Anzahl von Wiederholungen ausgeführt werden, nicht nur für die Länge eines Objekts. Sie könnten dies verwenden, um ein Rasterlayout zu erstellen (for columns from 1 through 12), den Farbkreis zu durchlaufen (for hue from 1 through 360) oder Ihre Divs mit nth-child und generiertem Inhalt zu nummerieren.

Beginnen wir mit einer Schleife durch 36 div-Elemente, die jedem eine Nummer und eine Hintergrundfarbe über :nth-child zuweisen.

Sass bietet eine spezielle For-Loop-Syntax: @for $count from $start through $finish, wobei $start und $finish ganze Zahlen sind. Wenn der Startwert größer ist, zählt Sass rückwärts.

Siehe den Pen Sass „for“-Schleife von Miriam Suzanne (@mirisuzanne) auf CodePen.

Das Schlüsselwort through bedeutet, dass unsere Schleife die Zahl 36 einschließt. Sie können auch das Schlüsselwort to verwenden, das den letzten Zähler nicht einschließt: @for $i from 1 to 36 würde nur 35 Mal laufen.

Stylus hat eine ähnliche Syntax zum Inkrementieren, aber to und through werden durch ... bzw. .. ersetzt

Siehe den Pen Stylus „for“-Schleife von Miriam Suzanne (@mirisuzanne) auf CodePen.

Stylus bietet auch eine range()-Funktion, mit der Sie die Schrittgröße ändern können. Mit for hue in range(0, 360, 10) würde die Zählung bei jeder Wiederholung um 10 erhöht.

Less muss wieder rekursive Mixins verwenden. Wir können ein Argument für die Anzahl der Iterationen (@i) erstellen, es mit der Bedingung when (@i > 0) schützen und bei jeder Iteration eins abziehen – um es wie eine absteigende for-Schleife zu verhalten

Siehe den Pen Less „for“-Schleife von Miriam Suzanne (@mirisuzanne) auf CodePen.

Es ist erwähnenswert, dass CSS uns auch die nth-child-Nummerierung ohne Präprozessoren geben kann. Während CSS keine Schleifenstrukturen hat, bietet es counter(), das Sie basierend auf einer beliebigen Anzahl von DOM-bezogenen Bedingungen inkrementieren und in generiertem Inhalt verwenden können. Leider kann es (noch) nicht außerhalb der content-Eigenschaft verwendet werden, sodass unsere Hintergrundfarben nicht angewendet werden

Siehe den Pen CSS-Zähler von Miriam Suzanne (@mirisuzanne) auf CodePen.

Grid-Systeme

Ich verwende inkrementelle Schleifen gelegentlich in meinen abstrakten Sass-Toolkits, aber fast nie in tatsächlichen Stylesheets. Die eine häufige Ausnahme ist die Generierung nummerierter Selektoren, entweder mit nth-child (wie oben gezeigt) oder in automatisch generierten Klassen (oft für Grid-Systeme verwendet). Lassen Sie uns ein einfaches flüssiges Grid-System ohne Abstände erstellen, um die Mathematik schwierig zu machen

Siehe den Pen Sass For-Loop Grids von Miriam Suzanne (@mirisuzanne) auf CodePen.

Jede Grid-Spanne ist ein Prozentsatz, der die Mathematik span / context * 100% verwendet – die grundlegende Berechnung, die alle Grid-Systeme durchführen müssen. Hier ist sie noch einmal in Stylus und Less

Siehe den Pen Stylus For-Loop Grids von Miriam Suzanne (@mirisuzanne) auf CodePen.

Siehe den Pen LESS For-Loop Grids von Miriam Suzanne (@mirisuzanne) auf CodePen.

Einzigartige Avatare

Bei OddBird haben wir kürzlich eine Anwendung mit Standard-Benutzeravataren entworfen – aber wir wollten, dass die Standardeinstellungen so einzigartig wie möglich sind. Am Ende entwarfen wir nur neun einzigartige Icons und nutzten Schleifen, um sie in 1296 verschiedene Avatare zu verwandeln, sodass die meisten Benutzer niemals eine Duplikat sehen würden.

Jeder Avatar hat fünf Attribute

<svg class="avatar" data-dark="1" data-light="2" data-reverse="true" data-rotation="3">
  <use xlink:href="#icon-avatar-1" xmlns:xlink="http://www.w3.org/1999/xlink"></use>
</svg>
  1. Die Ausgangssymbolform (9 Optionen)
  2. Drehung um 0, 90, 180 oder 270 Grad (4 Optionen)
  3. Eine dunkle Farbe für die Füllung (6 Optionen)
  4. Eine helle Farbe für den Hintergrund (6 Optionen)
  5. Ein true/false-Attribut, das die Farben umkehrt (2 Optionen)

Der Code hat sechs Farben und drei Schleifen

  1. @for $i from 0 through 3 gibt uns vier Rotationen
  2. @for $i from 1 through length($colors) ermöglicht es uns, die Farb-Liste ($colors) zu durchlaufen und jeder Farbe eine Nummer ($i) zuzuweisen. Normalerweise würde ich die @each-Schleife verwenden, um die Sammlung von Farben zu durchlaufen, aber @for ist einfacher, wenn ich auch eine Nummer für jedes Element benötige.
  3. Die verschachtelte @each $reverse in (true, false) gibt uns die Möglichkeit, Vordergrund und Hintergrund für jede Farbkombination umzukehren.

Hier ist das Endergebnis in Sass

Siehe den Pen 1296 Avatare mit mehreren Schleifen von Miriam Suzanne (@mirisuzanne) auf CodePen.

Die Umwandlung in Less und Stylus kann Ihre Hausaufgabe sein. Ich bin schon müde davon.

Generische while-Schleifen

Echte while-Schleifen sind selten, aber ich benutze sie gelegentlich. Ich finde sie am nützlichsten, wenn ich einem Pfad folge, um zu sehen, wohin er führt. Ich möchte nicht durch eine ganze Sammlung oder eine bestimmte Anzahl von Iterationen laufen – ich möchte weiterlaufen, bis ich gefunden habe, was ich suche. Das ist etwas, das ich in meinen abstrakten Toolkits verwende, aber nichts, was Sie im täglichen Styling sehr oft brauchen werden.

Ich habe ein Toolkit erstellt, das mir hilft, Farben in Sass zu speichern und zu manipulieren. Das Speichern von Farben in Variablen ist wahrscheinlich der häufigste Anwendungsfall für jeden Präprozessor. Die meisten Leute machen etwas Ähnliches

$pink: #E2127A;
$brand-primary: $pink;
$site-background: $brand-primary;

Ich weiß, dass pink wahrscheinlich nicht die einzige Farbe auf Ihrer Website ist, aber es ist die einzige, die wir im Moment brauchen. Ich habe ihr mehrere Namen gegeben, da es nützlich ist, Abstraktionsebenen zu schaffen – von einfachen Farben (pink) über breitere Muster (brand-primary) bis hin zu konkreten Anwendungsfällen (site-background). Ich möchte diese Liste einzelner Farben auch in eine Palette umwandeln, die mein Präprozessor verstehen kann. Ich brauche eine Möglichkeit zu sagen: Diese Werte hängen alle zusammen und sind Teil eines Musters. Um das zu tun, speichere ich alle meine Themenfarben in einer einzigen Sass-Map mit Schlüssel-Wert-Paaren

$colors: (
  'pink': #E2127A,
  'brand-primary': 'pink',
  'site-background': 'brand-primary',
);

Warum der Aufwand? Ich tue es, weil ich meinen Styleguide-Generator auf eine einzelne Variable zeigen kann und automatisch eine Farbpalette erstelle, die auf dem neuesten Stand bleibt. Aber es gibt Kompromisse und es ist nicht die richtige Lösung für jeden. Die Map erlaubt mir keine direkten Zuweisungen zwischen Paaren, wie ich es mit Variablen könnte. Ich benötige eine while-Schleife, um dem Brotkrumenpfad von Schlüsselnamen zu folgen, um den Wert für jede Farbe zu finden

Siehe den Pen Sass „while“-Schleife von Miriam Suzanne (@mirisuzanne) auf CodePen.

Ich mache das ständig, aber wenn Sie meinen Code nach Sass's @while durchsuchen, werden Sie es nicht finden. Das liegt daran, dass Sie dasselbe mit einer rekursiven Funktion erreichen können, wodurch sie wiederverwendbar wird

Siehe den Pen Sass „while“-rekursive Funktion von Miriam Suzanne (@mirisuzanne) auf CodePen.

Jetzt können wir die color()-Funktion überall in unserem Code aufrufen.

Stylus hat keine Syntax für while-Schleifen, aber es erlaubt auch Array-Variablen und rekursive Funktionen

Siehe den Pen Stylus „while“-Schleife von Miriam Suzanne (@mirisuzanne) auf CodePen.

Less hat keine integrierten Array-Variablen, aber wir können denselben Effekt nachahmen, indem wir eine Liste von Paaren erstellen, genau wie wir es für Social-Media-Farben getan haben

@colors:
  'pink' #E2127A,
  'brand-primary' 'pink',
  'site-background' 'brand-primary'
;

Wir müssen unseren eigenen @array-get-Mixin erstellen, um Werte aus dem Array anhand von Schlüsselnamen abzurufen, und dann unsere rekursive While-Schleife erstellen, um dem Pfad zu folgen

Siehe den Pen Less „while“-Listen-Schleife von Miriam Suzanne (@mirisuzanne) auf CodePen.

Das funktioniert zu Demonstrationszwecken, aber es gibt wahrscheinlich einen besseren Weg, dies in Less zu tun, da Sie Variablen aliasen und benennen können, ohne ein Array zu verwenden (im Gegensatz zu Sass oder Stylus)

Siehe den Pen Less-benannte Variablen von Miriam Suzanne (@mirisuzanne) auf CodePen.

Da meine Farben jetzt erfolgreich in einer Variable gespeichert sind, kann ich eine weitere Schleife verwenden, um meine Farbpalette zu generieren. Hier ist ein kurzes Beispiel in Sass

Siehe den Pen Sass-Farbpalette von Miriam Suzanne (@mirisuzanne) auf CodePen.

Ich bin sicher, Sie könnten das schöner gestalten als ich.

Am Loopen

Wenn Sie unsicher sind, wann Sie Schleifen in Ihrem Code verwenden sollen, achten Sie auf Wiederholungen. Haben Sie mehrere Selektoren, die einem ähnlichen Muster folgen, oder eine Berechnung, die Sie immer wieder durchführen? Hier erfahren Sie, welche Schleife am besten geeignet ist

  1. Wenn Sie die Elemente Ihrer Schleife auflisten und benennen können, verwenden Sie for-each, um sie zu durchlaufen.
  2. Wenn die Anzahl der Wiederholungen wichtiger ist als eine Reihe von Quelllementen oder wenn Sie Ihre Elemente nummerieren müssen, verwenden Sie eine for-Schleife.
  3. Wenn Sie auf dieselbe Schleife mit unterschiedlichen Eingaben zugreifen müssen, versuchen Sie stattdessen eine rekursive Funktion.
  4. Für alles andere (fast nie) verwenden Sie eine while-Schleife.
  5. Wenn Sie Less verwenden… Viel Glück!

Viel Spaß beim Loopen!