Streifen-Hintergründe mit Farbverläufen (und einem Sass Mixin) erstellen

Avatar of Kitty Giraudel
Kitty Giraudel am

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

Der folgende Beitrag ist ein Gastbeitrag von Kitty Giraudel. Hugo hat bereits mehrfach für CSS-Tricks geschrieben, unter anderem über einen ziemlich cleveren Pie Timer und mehrere Einträge für das Almanac. Ich freue mich, ihn wieder begrüßen zu dürfen, diesmal erklärt er einige ziemlich tiefgreifende Sass-Themen mit einer wirklich praktischen Anwendung.

Hallo Leute! Ich freue mich, wieder für CSS-Tricks schreiben zu können und einige coole Tricks über Sass zu teilen! In den letzten Wochen habe ich intensiv mit Sass-Listen experimentiert. Ich habe viele Dinge herausgefunden, die wahrscheinlich die meisten Leute nicht wissen.

Ich habe kürzlich ein @mixin erstellt, um Streifen zu erzeugen. Die Idee ist, dem Mixin einen normalen Farbverlauf zu geben, und es verwandelt ihn in einen gestreiften. Da es sich als ziemlich komplizierte Angelegenheit herausstellte, dachte ich, es wäre eine gute Idee, das aufzuschreiben.

Beginnen wir mit einigen Erinnerungen daran, wie Farbverläufe funktionieren.

Gestreifte Farbverläufe

Wenn Sie einem Farbverlauf zwei aufeinanderfolgende Farbstopps mit demselben Stoppwert geben, ist der Übergang zwischen diesen beiden abrupt statt sanft. Es ist technisch gesehen ein Farbverlauf, aber es gibt keinen sanften Übergang von einer Farbe zur anderen. Betrachten Sie den folgenden Code

.el {
  /* This is smooth */
  background: linear-gradient(deepskyblue, tomato);

  /* This is striped */
  background: linear-gradient(deepskyblue 50%, tomato 50%);
}

Sie können beliebig viele Farbstopps hinzufügen, solange Sie daran denken, jedem Farbstopp den gleichen Stoppwert wie dem vorherigen (außer dem ersten) zu geben.

.french-flag {
  height: 10em;
  width: 15em;
  background: linear-gradient(
    to right, 
    blue 33.33%, white 33.33%, 
    white 66.66%, red 66.66%
  );
}

Das ist im Grunde alles, was Sie für diesen Artikel über Farbverläufe wissen müssen. Wenn Sie sich jemals mit Farbverläufen tiefgehend beschäftigen möchten, hat Ana Tudor einen wunderbaren Artikel dazu geschrieben.

Sass-Listen

Fangen wir ganz von vorne an. Listen in Sass sind sehr ähnlich zu Arrays in JavaScript. Um eine Liste zu initialisieren: $list: ();.

Beachten Sie, dass Sie sie auch mit $list: null; (oder sogar $list: unquote("");) initialisieren können, wenn Sie möchten, aber seien Sie vorsichtig, sie sind unterschiedlich. Jedenfalls, hier ist eine sehr einfache Sass-Liste

$css-tricks-is: (#b4d455, 42, "awesome");

Das wird etwas komplizierter, weil die Sass-Syntax bei Listen sehr permissiv ist. Sie können eine Menge Dinge tun, von denen einige nicht beabsichtigt sind. Nehmen wir sie einzeln.

Sie können Klammern weglassen.

Sie müssen Ihre Listen nicht mit Klammern umschließen und können sie ruhig weglassen, wenn Sie möchten. Wir lassen sie ehrlich gesagt oft weg.

$css-tricks-is: #b4d455, 42, "awesome";

Der erste Index ist 1

Nicht 0 wie bei Arrays. Das ist bedauerlich, da es unseren zukünftigen Beispielcode komplizierter macht. Dies ist eine wichtige Sache, die man wissen muss, wenn man Indizes mit der nth() Funktion bearbeitet.

$item-1: nth($css-tricks-is, 1); // #b4d455

Sie können Werte mit Leerzeichen oder Kommas trennen.

Beides ist vollkommen gültig. Ich bin ziemlich sicher, dass Sie Kommas bevorzugen werden, da dies der Standardtrenner für Array-Werte ist (JS, PHP…), aber Sie können durchaus Leerzeichen verwenden, wenn Sie möchten.

$css-tricks-is: #b4d455 42 "awesome";

Sie können Leerzeichen und Kommas mischen.

Sie können die Liste auf der ersten Ebene mit Kommas trennen und die verschachtelte Liste mit Leerzeichen in verschachtelten Listen. Im folgenden Beispiel ist der 3. Wert eine mit Leerzeichen getrennte Liste.

$css-tricks-is: #b4d455, 42, "awesome" "interesting" "free";

Sie können Anführungszeichen um Zeichenketten weglassen.

Das stimmt, Zeichenketten müssen in Sass nicht zwingend in Anführungszeichen gesetzt werden. Fragen Sie mich nicht, warum.

$css-tricks-is: #b4d455, 42, awesome;

Auf jeden Fall empfehle ich Ihnen dringend

  • die Klammern beizubehalten
  • Kommas zu verwenden
  • Ihre Zeichenketten in Anführungszeichen zu setzen

Das spart Ihnen Zeit, vertrauen Sie mir.

Das Streifen-Mixin

Kommen wir zum Punkt des Artikels: unserem Streifen-Mixin! Die Hauptidee ist, die Tatsache auszunutzen, dass Sass-Listen kommagetrennt sein können, genau wie Farbstopps in Farbverläufen. Einfach ausgedrückt könnte eine Liste wie $list: red 20%, blue 55% in einer linear-gradient() Funktion so verwendet werden: linear-gradient($list), was linear-gradient(red 20%, blue 55%) erzeugt.

Weil wir Badasses sind, wollen wir es so flexibel wie möglich gestalten. Also

  • wir können eine Sammlung von Farbstopps definieren
  • wir können eine Liste von Farben definieren, wenn wir möchten, dass alle Streifen die gleiche Größe haben
  • wir definieren eine Richtung als Standard, damit wir sie in einigen Fällen weglassen können

Somit benötigen wir zwei Dinge, um einen normalen Farbverlauf in einen gestreiften umzuwandeln: die Liste der Farben / Farbstopps (z. B. deepskyblue, tomato, lightgreen oder deepskyblue 20%, tomato 35%, lightgreen 62%) und eine optionale Richtung. Beginnen wir mit dem Skelett

@mixin stripes($colors, $direction: "to bottom") { 
    /* Core */
}

Bei $colors gibt es 3 verschiedene Szenarien

  • Der Benutzer übergibt eine kommagetrennte Liste von Farbstopps: (deepskyblue 20%, tomato 35%, lightgreen 62%),
  • Der Benutzer übergibt eine kommagetrennte oder leerzeichengetrennte Liste von Farben: (deepskyblue, tomato, lightgreen),
  • Der Benutzer übergibt eine einzelne Farbe: deepskyblue oder (deepskyblue).

Alles andere wird entweder ungültige Ausgaben erzeugen oder einen Sass-Fehler auslösen. Das Mixin ist für informierte Entwickler in einer Entwicklungsumgebung gedacht, daher ist es kein großes Problem, wenn wir nicht jeden einzelnen Randfall abdecken.

Das Allerwichtigste, was wir herausfinden müssen, ist, ob wir es mit einer Liste von Farben oder einer Liste von Farbstopps zu tun haben. Der einfachste Weg, dies herauszufinden, ist die Überprüfung des ersten Elements in der $color-Liste (mit type-of()). Wenn es eine Liste ist, dann haben wir es mit Farbstopps zu tun, ansonsten möchte der Benutzer, dass alle Streifen die gleiche Breite haben, und das ist für uns ziemlich einfach.

Leider können wir nicht $auto : !(type-of($first-item) == list) verwenden, da Sass dies nicht als gültige Syntax erkennt. Um zu prüfen, können wir also die Sass-Funktion if() verwenden, die der Anweisung var = condition ? true : false in anderen Sprachen nahekommt.

$auto: if( type-of(nth($colors, 1)) == list, false, true );

Zusammenfassend lässt sich sagen, wenn $auto true ist, bedeutet dies, dass alle Streifen die gleiche Größe haben werden, sodass die Berechnungen von Sass gehandhabt werden. Wenn es false ist, bedeutet dies, dass wir uns mit benutzerdefinierten Stopps befassen müssen. Wir benötigen immer noch zwei Variablen, bevor wir durch die Farben iterieren: eine für den Fall, dass wir im Auto-Modus arbeiten, um die Größe eines Streifens zu definieren; und eine, um unsere Farbstopps während der Iteration zu speichern (später in einer linear-gradient-Funktion verwendet).

$stripe-width: 100% / length($colors); /* Only used in auto mode */
$gradient: ();

Jetzt können wir durch Farben / Farbstopps iterieren und unserer $gradient-Variable Dinge hinzufügen. Um unserer Schleife eine numerische Komponente hinzuzufügen, verwenden wir eine @for-Schleife anstelle einer @each-Schleife. Das macht die Sache aber nicht viel schwieriger. Wir deklarieren auch 2 neue Variablen innerhalb der Schleife: eine für das aktuelle Element und eine, um den aktuellen Farbstopp zu speichern, bevor er an $gradient angehängt wird.

@for $i from 1 through length($colors) {
    $item: nth($colors, $i);
    $dump: ();
}

Hier wird es kompliziert. Zuerst müssen wir zwischen Auto-Modus und Hard-Modus unterscheiden: Farbstopps sind nicht gleich. Im Auto-Modus werden sie berechnet, was bedeutet, dass beim ersten Schleifendurchlauf (wenn $i gleich 1 ist) der "vorherige Farbstopp" gleich 0 % ist ($stripe-width * ($i - 1)). Im Hard-Modus müssen wir prüfen, ob wir uns im ersten Schleifendurchlauf befinden oder nicht, da nth($colors, 0) nicht erlaubt ist; das löst einen Sass-Fehler aus. Lassen Sie uns den Code überprüfen

@for $i from 1 through length($colors) {
    $item: nth($colors, $i);
    $dump: ();

    /* If we're in auto-mode,
     * $item equals a color,
     * color-stops are automatically calculated based on $i
     */
    @if $auto == true {
        $dump: $item $stripe-width * ($i - 1), $item $stripe-width * $i;
        /*      red   0%                      , red   50%
         * ^ This is what the first loop run would output with a 2 colors gradient
         */
    }
    
    /* If we're in hard-mode
     */
    @else {
        /* We check if it is the first run loop;
         * if it isn't, we add the current color with the previous stop
         */
        @if $i > 1 {
          $previous-item: nth($colors, $i - 1);
          $dump: append($dump, nth($item, 1) nth($previous-item, 2));
        }
        /* No matter what, 
         * we add the new color stop
         */
        $dump: append($dump, $item);   
   }

   /* And no matter what, 
    * we append $dump to $gradient using join(),
    * separating both with a comma by forcing it as a 3rd argument
    */
   $gradient: join($gradient, $dump, comma);
}

Am Ende der Schleife haben wir eine gut formatierte Liste, die in einem linearen Farbverlauf verwendet werden kann. Wir können sie nun sicher als background-image verwenden. Sogar mit dem eingebauten Mixin von Compass, um alle Präfixe auszugeben. Hier ist nun das gesamte Mixin

@mixin stripes($colors, $direction: "to bottom") {  
    $stripe-width: 100% / length($colors);
    $auto:         if( type-of(nth($colors, 1)) == list, false, true );
    $gradient:     ();
    
    @for $i from 1 through length($colors) {
        $item: nth($colors, $i);
        $dump: ();
      
        @if $auto == true {
            $dump: $item $stripe-width * ($i - 1), $item $stripe-width * $i;
        }
      
        @else {   
            @if $i > 1 {
                $previous-item: nth($colors, $i - 1);
                $dump: append($dump, nth($item, 1) nth($previous-item, 2));
            }
            $dump: append($dump, $item);
        }

        $gradient: join($gradient, $dump, comma);
    }		

    @include background-image(linear-gradient($direction, $gradient));
}

Demo

Als Demo habe ich die Kopfzeile des Treehouse Blogs genommen: eine Zeile aus etwa 50 farbigen Streifen. Es sieht absolut entzückend aus. Sie verwenden derzeit 50 spans. Autsch! Sie könnten gestreifte Farbverläufe verwenden, und das ist jetzt mit diesem Mixin einfach.

Ich habe zwei Versionen erstellt: die erste läuft im Auto-Modus, was bedeutet, dass alle Streifen die gleiche Breite haben; die zweite verwendet benutzerdefinierte Farbstopps, um den Effekt von Treehouse zu reproduzieren.

/* Colors only (auto-mode) */
$treehouse-auto: #fa9300, #66c9ee, #c9c9c9, #82b964, #d24d33, #fffbdb, #2e77bb, #6bd5b1, #f87aa0, #c9c9c9, #72664e, #ccd600, #fffbdb, #df620e, #993838, #ff9600, #d24d33, #8960a7, #82b964, #f87aa0, #d43f3f, #668000, #ff9600, #8960a7, #c9c9c9, #993838, #ccd600, #668000, #f4cc13, #72664e, #fa9300, #66c9ee, #c9c9c9, #82b964, #ccd600, #fffbdb, #2e77bb, #6bd5b1, #f87aa0, #c9c9c9, #fa9300, #66c9ee, #c9c9c9, #82b964, #ccd600, #fffbdb, #fa9300;

/* Color-stops (hard-mode) */
$treehouse-hard: #fa9300 2.61%, #66c9ee 4.35%, #c9c9c9 6.96%, #82b964 9.13%, #d24d33 11.3%, #fffbdb 13.91%, #2e77bb 16.52%, #6bd5b1 17.82%, #f87aa0 19.12%, #c9c9c9 21.29%, #72664e 23.9%, #ccd600 26.07%, #fffbdb 28.68%, #df620e 31.29%, #993838 33.03%, #ff9600 34.33%, #d24d33 36.94%, #8960a7 39.55%, #82b964 42.16%, #f87aa0 43.36%, #d43f3f 45.63%, #668000 47.8%, #ff9600 50.41%, #8960a7 51.71%, #c9c9c9 53.88%, #993838 55.18%, #ccd600 57.79%, #668000 59.53%, #f4cc13 60.83%, #72664e 63.44%, #fa9300 66.05%, #66c9ee 67.35%, #c9c9c9 69.96%, #82b964 71.7%, #ccd600 74.31%, #fffbdb 76.92%, #2e77bb 79.53%, #6bd5b1 80.4%, #f87aa0 81.7%, #c9c9c9 83.87%, #fa9300 86.04%, #66c9ee 87.78%, #c9c9c9 90.39%, #82b964 92.56%, #ccd600 95.17%, #fffbdb 97.34%, #fa9300 100%;

/* Using a pseudo-element to display it, no extra markup */
.header:after {    
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    height: .5em;
    // Auto
    @include stripes($treehouse-auto, to right);
    // Hard
    @include stripes($treehouse-hard, to right);
}

Als Ergebnis sehen Sie den Auto-Modus oben im folgenden Stift und den Hard-Modus unten. Letzterer sieht definitiv besser aus.

Check out this Pen!

Ein weiterer Anwendungsfall könnte die Unterstützung des Tricks für fluidbreite Spalten gleicher Höhe sein (siehe Doug Neiners Methode).

Schlusswort

Ich denke, wir sind fertig, Team. Wenn Sie eine Funktion einem Mixin vorziehen, ist es recht einfach zu bearbeiten: ändern Sie einfach @mixin in @function und die background-image-Zeile in etwas wie @return linear-gradient(#{$gradient}, #{$linear}) und verwenden Sie sie dann mit background-image: stripes($colors). Ich persönlich ziehe es vor, ein Mixin zu verwenden, aber das ist wirklich Ihnen überlassen.

Was denkst du?

Wenn Sie das Gefühl haben, dass Sie den Code einfacher gestalten könnten, sagen Sie es bitte! Danke fürs Lesen. :)