Easing Linear Gradients

Avatar of Andreas Larsen
Andreas Larsen am

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

Lineare Verläufe sind in CSS einfach zu erstellen und äußerst nützlich. Wie wir in diesem Artikel sehen werden, können wir sie visuell viel weicher gestalten, indem wir sie mit *nicht*-linearen Verläufen erstellen. Nun, nicht-linear im Sinne von Easing, jedenfalls!

Hier ist ein Beispiel, das zeigt, wie hart ein Standard-linear-gradient() sein kann, im Vergleich dazu, wie weich wir ihn durch *Easing* machen können.

Screencap aus „The Good, the Bad and the Ugly“ mit überlagerten Verläufen.
  • Il buono (der Gute): Weiche Verläufe in CSS, die sich in ihren Kontext einfügen.
  • Il cattivo (der Schlechte): Kein Textschutz (schlechte Zugänglichkeit).
  • Il brutto (der Hässliche): Standard-Linearverläufe mit scharfen Kanten.

In diesem Artikel konzentrieren wir uns darauf, wie wir Il brutto in Il buono verwandeln können.

Die frustrierenden scharfen Kanten von background: linear-gradient()

In letzter Zeit habe ich mit Verläufen bei der Arbeit herumgespielt. Ich war frustriert von einfachen linearen Verläufen, weil sie wie Il cattivo oben aussahen.

/* Sharp edges :( */
.image__text {
  background-image: linear-gradient(
    hsla(0, 0%, 0%, 0.6),
    transparent;
  );
}

Ich begann, nach Möglichkeiten zu suchen, konsistent optisch ansprechendere Verläufe zu erstellen. Genauer gesagt, ich habe schnell ein paar hübscher aussehende Verläufe als Einzelstücke begutachtet und dann angefangen, damit herumzuspielen, als ich nach Hause kam.

Inspiration: Mathematik und Physik

Da ein Verlauf ein Farbübergang ist, ließ ich mich davon inspirieren, wie wir Übergänge anderswo behandeln.

Ich war schon immer fasziniert von der Eulerschen Spirale (oder Cornu-Spirale), deren Krümmung linear mit der Kurvenlänge zunimmt, d.h., wenn wir uns entlang der Linie von (0, 0) bewegen, nimmt der Radius linear mit der zurückgelegten Strecke ab (da die Krümmung der Kehrwert des Radius ist).

Das Endergebnis ist eine Kurve, die sich so reibungslos wie möglich von einer geraden Linie zu einer Kurve übergangslos wandelt. (Anmerkung am Rande: Gerade Linien im euklidischen Raum sind Kurven mit unendlichem Radius!)

Euler-Spirale von AdiJapan, CC BY-SA 3.0

Diese Art von Kurve wird als Übergangskurve bezeichnet und wird in der realen Welt verwendet. Wenn Sie das nächste Mal eine gut gebaute Autobahn verlassen, achten Sie darauf, wie allmählich Sie das Lenkrad drehen. Wir können Euler dafür danken, dass plötzliche Änderungen der Zentripetalbeschleunigung auf ein absolutes Minimum reduziert werden, d.h. seine Mathematik ist der Grund, warum das Auto nicht umkippt, gerade wenn wir die Autobahn mit erlaubter Höchstgeschwindigkeit verlassen.

Das folgende Bild ist ein Beispiel dafür, wie allmählich die Änderungen in der Krümmung von Autobahnen sind.

Kreuzung außerhalb von Sagamihara, Japan von @digitalanthill

Inspiration: Typografie

Schriftgestalter waren im Laufe der Geschichte besessen von glatten Kurven. Wir haben das getan, weil wir nicht wollen, dass Buchstaben und Zahlen wie eine Kombination verschiedener Formen aussehen, sondern selbst eine kohärente Form bilden.

Deshalb habe ich den Übergang von einer geraden Linie zum Kreis in der unten stehenden „9“ so reibungslos wie möglich gestaltet. Das lässt die Zahl 9 wie eine einzige Form und nicht wie eine Linie plus einen Kreis wirken.

Als Schriftgestalter haben wir Werkzeuge, die uns dabei helfen. FontForge, ein quelloffener Schrifteditor, hat sogar einen Spiro/Euler-Zeichenmodus. Eine der beliebtesten Erweiterungen für die Schriftgestaltung ist Speed Punk, die die Krümmung visualisiert.

Spiro-Modus in FontForge links und Speed-Punk-Visualisierung in Glyphs rechts.

Inspiration: Design

Apple verwendet diesen Ansatz für Übergänge von Linien zu Kurven intensiv in den Abteilungen für digitales Design und Hardware-Design. (Siehe Apples Icons haben diesen Shape aus einem sehr guten Grund). Als Apple iOS7 auf den Markt brachte, wurden die Icon-Masken aktualisiert, um einen viel glatteren Übergang von geraden Linien zu abgerundeten Ecken zu haben.

Visualisierung der Krümmung der iOS6- und iOS7-App-Icons.

(Anmerkung am Rande: Die iOS7-Form oben ist direkt aus dem Apple HIG übernommen, das leider einige kleinere Unvollkommenheiten aufweist, besonders dort, wo die horizontalen Linien zu krümmen beginnen. Es ist auch manchmal als „Squircle“ bekannt.)

Inspiration: Webdesign

Im Webdesign waren wir manchmal durch das, was wir tun konnten, eingeschränkt. Zum Beispiel bietet border-radius keine Möglichkeit, ein Squircle wie das iOS7-Icon zu erstellen. Ähnlich gibt es bei linear-gradient keine natürlichen Easing-Funktionen.

Wir *haben* jedoch Easing und Bézier-Kurven für Animationen! Sie haben uns ermöglicht, Animationen natürlicher, weicher und subtiler aussehen zu lassen.

Screenshot von easings.net

Auswirkungen von Verläufen

Meistens möchten wir im Webdesign, dass sich der Verlauf so gut wie möglich einfügt. Wenn wir einen Textschutz-Verlauf wie Il buono haben, möchten wir nicht, dass der Benutzer dem Verlauf selbst Beachtung schenkt. Er sollte eher unsichtbar sein und dem Leser ermöglichen, sich auf das Bild und den Text zu konzentrieren.

Scrim

In den Material Design Style Guidelines für Bilder sprechen die Designer bei Google über Textschutz-Verläufe. Sie nennen sie *Scrim*. Sie empfehlen

[der] Verlauf sollte lang sein… mit dem Mittelpunkt etwa 3/10 in Richtung der dunkleren Seite des Verlaufs. Das verleiht dem Verlauf einen natürlichen Fall und vermeidet eine scharfe Kante.

Ein Scrim gemäß den Material Design Richtlinien

Das können wir mit linearen Verläufen nicht exakt nachbilden, aber wir können eine „Low Poly“-Annäherung mit mehr Farbstopps erstellen (und werden das tun).

Ein Scrim mit 5 Farbstopps, um das Prinzip zu zeigen

Nur 5 Farbstopps zu verwenden (wie in der obigen Abbildung) würde zu ernsthaften Banding-Effekten führen. Mehr Stopps hinzuzufügen, macht den Verlauf viel weicher. Das ist genau das, was ich im Demo gemacht habe, das Sie im ersten Bild dieses Artikels gesehen haben. Il buono hat einen Verlauf mit 13 Farbstopps, wodurch er schöner in das Bild übergeht.

Siehe den Pen The Good, The Bad & The Ugly – correct text von Andreas Larsen (@larsenwork) auf CodePen.

Im Vergleich zum Material Design Scrim habe ich ihn so angepasst, dass er am Anfang etwas linearer ist, um einen höheren Textkontrast zu erzielen, und habe ihm einen sanften Ausblendeffekt gegeben.

Vergleich zwischen dem Material Design Scrim und meinem, gezeichnet mit 13 Farbstopps.

Wenn wir den Material Design Scrim mit einem einfachen linearen Verlauf vergleichen, müsste er etwa 60 % länger sein, um denselben Kontrast zur Hälfte zu erreichen, während mein Versuch nur etwa 30 % länger sein muss. Die Idee ist, nicht mehr Bild zu verdunkeln als nötig, aber trotzdem sanft darin überzugehen.

Die beiden Scrims im Vergleich zu einem einfachen linearen Verlauf

Ich habe mich entschieden, den Material Design Scrim nicht einzubeziehen, da er fast identisch mit dem hübscheren easeOutSine ist. Wir können vergleichen, wie linear-gradient, mein scrim-gradient und ease-out-sine-gradient hier aussehen.

Beide Enden verschmelzen lassen

Im Scrim-Beispiel müssen wir nur ein Ende überblenden, da das andere Ende mit dem Bild abschließt. Manchmal müssen wir an beiden Enden überblenden, und da sind Easing-Funktionen wie easeInOutSine sehr nützlich.

Linear-gradient im Vergleich zur ease-in-out-sine Annäherung.

Mit einer easeInOut-Funktion stellen wir sicher, dass sowohl der Übergang von colorA zu Verlauf als auch von Verlauf zu colorB so glatt wie möglich ist. Das gleiche Prinzip wird in diesem Pen veranschaulicht.

Siehe den Stift.

Wie man die Verläufe zeichnet

Auf YouTube gibt es einen Verlauf hinter den Steuerelementen, wenn man mit der Maus über ein Video fährt. Er wird mit einem Base64-kodierten PNG erstellt. Diese Technik funktioniert auch sehr gut, aber man kann sie nicht wirklich automatisieren oder einfach anpassen.

Screenshot von YouTube (Künstler ist Wintergatan).

Die meisten anderen Orte verwenden linear-gradient(hsla(0, 0%, 0%, 0.8), transparent), wobei die Start-Alpha meist zwischen 0,6 und 0,8 liegt. Das löst das Problem der Lesbarkeit des Textes, aber der resultierende Verlauf ist sehr auffällig. Ein Beispiel dafür ist die BBC, wo ich versucht habe, stattdessen den Scrim-Gradient zu verwenden.

Screenshots von BBC mit linear-gradient (links) und scrim-gradient (rechts).

PostCSS zur Rettung

Ich habe ein Plugin erstellt, das diese Verläufe für mich erstellt. Hier ist die Syntax

scrim-gradient(
  black,
  transparent
);

wird zu

linear-gradient(
  hsl(0, 0%, 0%) 0%,
  hsla(0, 0%, 0%, 0.738) 19%,
  hsla(0, 0%, 0%, 0.541) 34%,
  hsla(0, 0%, 0%, 0.382) 47%,
  hsla(0, 0%, 0%, 0.278) 56.5%,
  hsla(0, 0%, 0%, 0.194) 65%,
  hsla(0, 0%, 0%, 0.126) 73%,
  hsla(0, 0%, 0%, 0.075) 80.2%,
  hsla(0, 0%, 0%, 0.042) 86.1%,
  hsla(0, 0%, 0%, 0.021) 91%,
  hsla(0, 0%, 0%, 0.008) 95.2%,
  hsla(0, 0%, 0%, 0.002) 98.2%,
  hsla(0, 0%, 0%, 0) 100%
);

Das zugrunde liegende Prinzip ist das, was wir durchgegangen sind: Kombination von Easing-Funktionen und mehreren Farbstopps, um Annäherungen zu erstellen, die glatter aussehen als einfache lineare Verläufe.

Tatsächlich wird der oben genannte Scrim-Gradient mit einem benutzerdefinierten Satz von Koordinaten generiert, aber wenn wir uns die Easing-Gradienten wie ease-in-out-sine-gradient ansehen, sind die Schritte:

  1. Durchsuchen Sie die .css (oder .pcss) und finden Sie sie.
  2. Generieren Sie gleichmäßig verteilte Koordinaten entlang der ease-in-out-sine-Kurve.
  3. Verwenden Sie diese Koordinaten, um Farbstopps zu erstellen. Die x-Koordinate bestimmt das Mischverhältnis der Farben, und die y-Koordinate bestimmt die Position des Farbstopps.
  4. Ersetzen Sie den Easing-Gradient durch den generierten Linear-Gradient.
Ease-in-out-sine-Koordinatenwerte, generiert in Schritt 2.

Das Plugin hat derzeit zwei optionale Einstellungen

  • precision — korreliert mit der Anzahl der generierten Farbstopps
  • alphaDecimals — legt die Anzahl der Nachkommastellen fest, die in den hsla()-Alphawerten verwendet werden.

Das Plugin: postcss-easing-gradients

Insgesamt bin ich mit dem Ergebnis ziemlich zufrieden. Dinge, die ich in Betracht ziehe hinzuzufügen:

  • Sass-Version? Ich benutze es nicht mehr. Vielleicht möchte jemand anderes eine schreiben?
  • Die Koordinaten, die zum Mischen der Farben für die Farbstopps verwendet werden, sind gleichmäßig über die Easing-Kurven verteilt. Idealerweise wäre der Abstand zwischen den Farbstopps relativ kürzer, wo die Änderung der Krümmung am größten ist.
  • Vielleicht haben Sie ja einige Ideen?

Sie finden es auf GitHub, NPM und als Vorlage auf CodePen. Spielen Sie damit herum! Ihre Beiträge und Vorschläge sind sehr willkommen.

CSS

Vorzugsweise würde ich gerne etwas wie ease-in-out-gradient(#bada55, transparent) schreiben können und dass der Browser es versteht, ohne benutzerdefinierte CSS-Verarbeitung durchführen zu müssen.

Referenzen/Weiterführende Lektüre