Hintergrundmuster, vereinfacht durch konische Verläufe

Avatar of Ana Tudor
Ana Tudor am

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

Für alle, die die großen Neuigkeiten verpasst haben: Firefox unterstützt jetzt Conic Gradients!

Ab Firefox 75, der am 7. April veröffentlicht wurde, können wir zu about:config gehen, nach dem Flag layout.css.conic-gradient.enabled suchen und dessen Wert auf true setzen (standardmäßig ist er false und alles, was nötig ist, um ihn umzuschalten, ist ein Doppelklick).

Screenshot. Shows the Firefox URL bar at `about:config`, a search for 'conic' giving the `layout.css.conic-gradient.enabled` flag as the sole result and its value set to `true`.
Konische Verläufe in Firefox 75+ aktivieren

Wenn dies aktiviert ist, können wir unseren CSS-Code, einschließlich konischer Verläufe, nun auch in Firefox testen.

Während einige der Demos in diesem Artikel gut funktionieren, wenn man ein Polyfill verwendet, nutzen einige CSS-Variablen innerhalb des konischen Verlaufs und erfordern daher native Unterstützung für diese Funktion.

Eine Sache, die mir an konischen Verläufen besonders gefällt, ist, wie sehr sie background-Muster vereinfachen können. Nehmen wir also ein paar linear-gradient()-Muster aus der Galerie von Lea Verou, die vor etwa einem Jahrzehnt erstellt wurde, und sehen wir, wie wir sie jetzt mit conic-gradient vereinfachen können!

Pyramide

Screenshot. Shows the original pyramid pattern with the code that was used to create it.
Das Pyramidenmuster

Das obige Muster verwendet vier lineare Verläufe

background:
  linear-gradient(315deg, transparent 75%, #d45d55 0) -10px 0,
  linear-gradient(45deg, transparent 75%, #d45d55 0) -10px 0,
  linear-gradient(135deg, #a7332b 50%, transparent 0) 0 0,
  linear-gradient(45deg, #6a201b 50%, #561a16 0) 0 0 #561a16;
background-size: 20px 20px;

Das ist ziemlich viel CSS und vielleicht sogar ein wenig einschüchternd. Es ist nicht einfach, dies anzusehen und zu verstehen, wie alles zusammenwirkt, um uns das Pyramidenmuster zu geben. Ich konnte es auf jeden Fall nicht. Es hat eine Weile gedauert, bis ich es verstanden habe, obwohl Verläufe eine der CSS-Funktionen sind, mit denen ich am vertrautesten bin. Machen Sie sich also keine Sorgen, wenn Sie nicht verstehen, wie diese Verläufe das Pyramidenmuster erzeugen, denn erstens ist es kompliziert und zweitens müssen Sie das nicht einmal verstehen!

Mit conic-gradient() können wir nun dasselbe Ergebnis auf wesentlich einfachere Weise erzielen, mit einer einzigen background-Schicht anstelle von vier!

Was ich beim Codieren von sich wiederholenden Mustern besonders mag, ist, wie sehr sie background-Muster vereinfachen können. Nehmen wir also ein paar linear-gradient()-Muster aus der Galerie von Lea Verou, die vor etwa einem Jahrzehnt erstellt wurde, und sehen wir, wie wir sie jetzt mit conic-gradient vereinfachen können!

Annotated screenshot. Shows the rectangles (squares in this case) defined by the `background-size`.
Hervorhebung der Musterzellen

Standardmäßig beginnen konische Verläufe um 12 Uhr und verlaufen im Uhrzeigersinn. In unserem Fall möchten wir den Start des Verlaufs jedoch um 45° im Uhrzeigersinn versetzen und anschließend jedem der vier Farbtöne ein Viertel (25 %) des verfügbaren Platzes um den Mittelpunkt unserer quadratischen Box herum zuweisen.

SVG illustration. Shows how we place a conic gradient into a single pattern cell by rotating the gradient start point 45° in the clockwise (positive) direction.
Eine Musterzelle mit harten Stopps eines konischen Verlaufs bei jeweils 25 %, beginnend bei 45° relativ zur vertikalen Achse (live).

Das bedeutet, dass unser Pyramidenmuster reduziert werden kann auf

$s: 20px;
background:
  conic-gradient(from 45deg, 
    #561a16 25%, 
    #6a201b 0% 50%, 
    #a7332b 0% 75%, 
    #d45d55 0%) 
    50%/ #{$s $s};

Nicht nur der Code sieht einfacher aus, wir sind auch von 260 Bytes auf 103 Bytes gekommen und haben den Code für dieses Muster um mehr als die Hälfte reduziert.

Wir verwenden die Syntax mit doppelter Positionierung, da diese heutzutage ebenfalls gut unterstützt wird.

Wir können es in Aktion im folgenden Pen sehen

Schachbrett

Screenshot. Shows the original checkerboard pattern with the code that was used to create it.
Das Schachbrettmuster

Das obige Muster wird mit zwei linearen Verläufen erstellt

background-color: #eee;
background-image:
  linear-gradient(45deg, black 25%, transparent 25%, 
    transparent 75%, black 75%, black),
  linear-gradient(45deg, black 25%, transparent 25%, 
    transparent 75%, black 75%, black);
background-size: 60px 60px;
background-position: 0 0, 30px 30px;

Sehen wir uns an, wie wir dieses CSS vereinfachen können, indem wir diese linearen Verläufe durch einen konischen ersetzen!

Genau wie im vorherigen Fall zeichnen wir vertikale und horizontale Linien, um die durch die background-size definierten Rechtecke besser zu sehen.

Annotated screenshot. Shows the rectangles (squares in this case) defined by the `background-size`.
Hervorhebung der Musterzellen

Betrachtet man das Quadrat, das in der obigen Abbildung in deeppink hervorgehoben ist, so sieht man, dass in diesem Fall unser konischer Verlauf von der Standardposition um 12 Uhr beginnt. Ein Viertel davon ist schwarz, das nächste Viertel ist schmutzigweiß und dann wiederholt sich dies (die gleichen schwarzen und dann schmutzigweißen Viertel-Scheiben noch einmal).

SVG illustration. Shows how we place a conic gradient into a single pattern cell and then make it repeat after the 50% point.
Eine Musterzelle mit harten Stopps eines konischen Verlaufs bei jeweils 25%, beginnend bei der Standardposition um 12 Uhr und wiederholend nach 50% (Demo).

Diese Wiederholung in der zweiten Hälfte des [0%, 100%]-Intervalls bedeutet, dass wir einen repeating-conic-gradient() verwenden können, was uns den folgenden Code liefert (wodurch der kompilierte CSS-Code von 263 Bytes auf nur 73 Bytes reduziert wird – das ist eine Reduzierung um über 70%)

$s: 60px;
background:
  repeating-conic-gradient(#000 0% 25%, #eee 0% 50%) 
    50%/ #{$s $s};

Der folgende Pen zeigt es in Aktion

Diagonales Schachbrett

Screenshot. Shows the original diagonal checkerboard pattern with the code that was used to create it.
Das diagonale Schachbrettmuster

Auch hier haben wir ein Muster, das mit zwei linearen Verläufen erstellt wurde

background-color: #eee;
background-image: 
  linear-gradient(45deg, black 25%, transparent 25%, 
    transparent 75%, black 75%, black),
  linear-gradient(-45deg, black 25%, transparent 25%, 
    transparent 75%, black 75%, black);
background-size: 60px 60px;

Wir zeichnen horizontale und vertikale Linien, um dieses Muster in identische Rechtecke zu unterteilen

Annotated screenshot. Shows the rectangles (squares in this case) defined by the `background-size`.
Hervorhebung der Musterzellen

Was wir jetzt haben, ist so ziemlich das gleiche Schachbrettmuster wie zuvor, mit dem einzigen Unterschied, dass wir nicht von der Standardposition um 12 Uhr ausgehen, sondern von 45° in Richtung des Uhrzeigers.

Wenn Sie Schwierigkeiten haben, sich vorzustellen, wie einfach das Ändern des Startwinkels uns vom vorherigen Muster zu diesem bringen kann, können Sie damit in der interaktiven Demo unten experimentieren.

Beachten Sie, dass diese Demo in Browsern, die keine native Unterstützung für konische Verläufe haben, nicht funktioniert.

Das bedeutet, dass unser Code wie folgt aussieht

$s: 60px;
background:
  repeating-conic-gradient(from 45deg, 
    #000 0% 25%, #eee 0% 50%) 
  50%/ #{$s $s};

Wir können es unten in Aktion sehen

Auch hier ist nicht nur der Code einfacher zu verstehen, sondern wir sind auch von 229 Bytes auf nur 83 Bytes im kompilierten CSS gegangen, was einer Reduzierung um fast zwei Drittel entspricht!

Halbe Rauten

Screenshot. Shows the original Half-Rombes pattern with the code that was used to create it.
Das Muster mit halben Rauten

Dieses Muster wurde mit vier linearen Verläufen erstellt

background: #36c;
background:
  linear-gradient(115deg, transparent 75%, rgba(255,255,255,.8) 75%) 0 0,
  linear-gradient(245deg, transparent 75%, rgba(255,255,255,.8) 75%) 0 0,
  linear-gradient(115deg, transparent 75%, rgba(255,255,255,.8) 75%) 7px -15px,
  linear-gradient(245deg, transparent 75%, rgba(255,255,255,.8) 75%) 7px -15px,
  #36c;
background-size: 15px 30px;

Wie in den vorherigen Fällen zeichnen wir äquidistante vertikale und horizontale Linien, um die sich wiederholende Einheit besser zu sehen

Annotated screenshot. Shows the rectangles (squares in this case) defined by the `background-size`.
Hervorhebung der Musterzellen.

Was wir hier haben, ist ein Muster, das aus kongruenten gleichschenkligen Dreiecken besteht (die schrägen Kanten sind gleich und die dunkelblauen Dreiecke sind eine Spiegelung der hellblauen), die durch die Schnittmenge von äquidistanten parallelen Linien gebildet werden, die entweder horizontal, im Uhrzeigersinn oder umgekehrt ausgerichtet sind. Jeder dieser drei Typen von parallelen Linien ist in der folgenden Abbildung hervorgehoben.

Illustration. Shows the equidistant parallel lines which create the pattern of isosceles triangles.
Parallele Hilfslinien

Jede Musterzelle enthält ein volles Dreieck und zwei angrenzende halbe Dreiecke im oberen Teil, dann eine Spiegelung dieses oberen Teils im unteren Teil. Das bedeutet, dass wir eine Reihe von kongruenten rechtwinkligen Dreiecken identifizieren können, die uns helfen, die Winkel zu erhalten, die wir für unseren conic-gradient() benötigen.

SVG illustration. Shows how we place a conic gradient into a single pattern cell by rotating the gradient start point by an angle β in the clockwise (positive) direction such that the 0% line goes through the top right corner and then all the other hard stops are either horizontal or going through the cell corners.
Eine Musterzelle mit harten Stopps eines konischen Verlaufs, so dass sie entweder horizontal sind oder durch die Zellenecken verlaufen, alle beginnend bei β relativ zur vertikalen Achse (Demo)

Diese Abbildung zeigt, dass der Verlauf von einem Winkel, β, vom Standard-Startpunkt des konischen Verlaufs um 12 Uhr ausgeht. Der erste konische Abschnitt (das obere rechte halbe Dreieck) geht bis α, der zweite (das untere rechte dunkle Dreieck) bis 2·α, und der dritte (das untere helle Dreieck) geht vom Startpunkt um die halbe Kreisfläche (das sind 180° oder 50 %). Der vierte (das untere linke dunkle Dreieck) geht bis 180° + α und der fünfte (das obere linke helle Dreieck) geht bis 180° + 2·α, während der sechste den Rest abdeckt.

SVG illustration. Highlights the right triangle from where we can get α knowing the catheti and shows how we can then compute β.
Berechnung von α und β (Demo)

Aus dem hervorgehobenen rechtwinkligen Dreieck erhalten wir, dass

tan(α) = (.5·h)/(.5·w) = h/w

Wenn wir die Breite (w) und Höhe (h) einer Musterzelle kennen, können wir die Winkel α und β erhalten

α = atan(h/w)
β = 90° - α

Dies führt zu dem Muster, das durch den folgenden Code erzeugt wird.

$w: 15px;
$h: 30px;
$a: atan($h/$w)*180deg/pi();
$b: 90deg - $a;
$c0: #36c;
$c1: #d6e0f5;

html {
  background: 
    conic-gradient(from $b, 
      $c1 0% $a, 
      $c0 0% 2*$a, 
      $c1 0% 50%, 
      $c0 0% 180deg + $a, 
      $c1 0% 180deg + 2*$a, 
      $c0 0%) 
    0 0/ #{$w $h};
}

Das bedeutet eine Reduzierung von 343 Bytes auf nur 157 Bytes im kompilierten CSS. Das Ergebnis kann unten betrachtet werden.

Sie können die Musterbreite ($w) und -höhe ($h) im Sass-Code anpassen, um zu sehen, wie das Muster für verschiedene Seitenverhältnisse gequetscht und gestreckt wird.

In dem speziellen Fall, in dem der Winkel zwischen 2*$a und 50% (oder 180deg) ebenfalls $a ist, ergibt sich, dass $a 60deg ist, unsere gleichschenkligen Dreiecke gleichseitig sind und unser Verlauf auf einen wiederholenden (und unter 100 Bytes im kompilierten CSS) reduziert werden kann.

$a: 60deg;
$b: 90deg - $a;
$w: 15px;
$h: $w*tan($a);
$c0: #36c;
$c1: #d6e0f5;

html {
  background: 
    repeating-conic-gradient(from $b, 
      $c1 0% $a, $c0 0% 2*$a) 
    0 0/ #{$w $h}
}

Das Live-Ergebnis ist unten zu sehen.

Bonus: Hintergrundbilder mit sich schneidenden Linien!

Screenshot. Shows the original intersecting lines pattern with the code that was used to create it.
Beispiele für Hintergrundbilder mit sich schneidenden Linien

Obwohl dies keine sich wiederholenden Muster sind, sind es Beispiele für eine Situation, in der ein einzelner konischer Verlauf einen Effekt erzielt, der zuvor eine Menge linearer Verläufe erfordert hätte.

Was wir hier haben, ist ein conic-gradient(), der von zwei geraden Linien ausgeht, die sich innerhalb des rechteckigen Feldes schneiden, in dem wir den background gesetzt haben.

SVG illustration. Shows a rectangular box and two random lines intersecting inside it. This intersection point (x,y) is the point the conic gradient goes around, while the gradient's start is from the angle β formed by the line segment closest to the top right corner with the vertical. The hard stops are at α, the angle between the start segment and the next one in clockwise order, at 50% and at 180° + α.
Bonus-Musterstruktur (Demo)

Der Verlauf geht um den Punkt mit den Koordinaten x,y, an dem sich die beiden geraden Linien schneiden. Er beginnt bei einem Winkel, β, der der Winkel der Linie ist, die dem oberen rechten Eck am nächsten liegt, dann hat er harte Stopps bei α, 50% (oder 180°) und 180° + α.

Wenn wir mehrere Elemente mit ähnlichen Mustern erstellen möchten, die mithilfe verschiedener sich schneidender Linien und verschiedener Paletten erstellt wurden, haben wir den perfekten Anwendungsfall für CSS-Variablen.

.panel {
  background: 
    conic-gradient(from var(--b) at var(--xy), 
      var(--c0) var(--a), var(--c1) 0% 50%, 
      var(--c2) 0% calc(180deg + var(--a)), var(--c3) 0%);
}

Alles, was wir tun müssen, ist die Position (--xy), den Startwinkel (--b), den ersten Winkel (--a) und die Palette (--c0 bis --c3) festzulegen.

.panel {
  /* same as before */
  
  &:nth-child(1) {
    --xy: 80% 65%; 
    --b: 31deg;
    --a: 121deg; 
    --c0: #be5128;
    --c1: #ce9248;
    --c2: #e4c060;
    --c3: #db9c4e
  }
  
  /* similarly for the other panels */
}

Anstatt Hardcoding könnten wir diese Werte auch zufällig generieren oder sie mit Hilfe eines CSS- oder HTML-Präprozessors aus einem Datenobjekt extrahieren. Im letzteren Fall würden wir diese benutzerdefinierten Eigenschaften inline festlegen, was genau das ist, was ich im folgenden Pen getan habe.

Da wir benutzerdefinierte Eigenschaften innerhalb der konischen Verläufe verwenden, funktioniert diese Demo nicht in Browsern, die sie nicht nativ unterstützen.

Das war's! Ich hoffe, dieser Artikel hat Ihnen gefallen und gibt Ihnen einige Ideen, wie konische Verläufe Ihr Leben einfacher machen können.