Den Facebook Messenger Gradient-Effekt mit CSS nachbilden

Avatar of Stepan Bolotnikov
Stepan Bolotnikov am

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

An einem Sonntagmorgen wachte ich etwas früher als mir lieb war auf, dank des hartnäckigen Summens meines Handys. Ich griff danach, öffnete Facebook Messenger und schloss mich der Unterhaltung an. Schon bald richtete sich meine Aufmerksamkeit von den eigentlichen Gesprächen auf den schicken Farbverlaufseffekt der Nachrichtenkugeln, die sie enthielten. Lassen Sie mich Ihnen zeigen, was ich meine.

Dies ist eine neue Funktion von Messenger, mit der Sie anstelle einer einfarbigen Farbe einen Farbverlauf für den Hintergrund der Chatnachrichten wählen können. Sie ist derzeit sowohl in der mobilen Anwendung als auch auf der Website von Facebook verfügbar, jedoch noch nicht auf der Website von Messenger. Der Farbverlauf scheint „fest“ zu sein, sodass die Chatblasen beim vertikalen Scrollen ihre Hintergrundfarbe zu ändern scheinen.

Ich dachte, das sähe nach etwas aus, das man mit CSS machen könnte, also… Herausforderung angenommen!

Lassen Sie uns meinen Denkprozess durchgehen, als ich versuchte, es nachzubilden, und die CSS-Funktionen erklären, die verwendet wurden, um es zu ermöglichen. Außerdem werden wir sehen, wie Facebook es *tatsächlich* implementiert hat (Spoiler-Alarm: nicht so wie ich) und wie die beiden Ansätze verglichen werden.

Ärmel hochkrempeln

Schauen wir uns zuerst das Beispiel noch einmal an, um zu sehen, was genau wir hier erreichen wollen.

Im Allgemeinen haben wir ein ziemlich standardmäßiges Messaging-Layout: Nachrichten sind in Blasen von oben nach unten unterteilt, unsere auf der rechten Seite und die anderen Personen im Chat auf der linken Seite. Die auf der linken Seite haben alle eine graue Hintergrundfarbe, aber die auf der rechten Seite sehen so aus, als ob sie den gleichen festen Hintergrundverlauf teilen würden. Das ist so ziemlich alles!

Schritt 1: Layout einrichten

Dieser Teil ist ziemlich einfach: Ordnen wir die Nachrichten in einer geordneten Liste an und wenden wir etwas grundlegendes CSS an, damit es mehr wie eine tatsächliche Messaging-Anwendung aussieht.

<ol class="messages">
  <li class="ours">Hi, babe!</li>
  <li class="ours">I have something for you.</li>
  <li>What is it?</li>
  <li class="ours">Just a little something.</li>
  <li>Johnny, it’s beautiful. Thank you. Can I try it on now?</li>
  <li class="ours">Sure, it’s yours.</li>
  <li>Wait right here.</li>
  <li>I’ll try it on right now.</li>
</ol>

Wenn es darum geht, die Nachrichten nach links und rechts zu trennen, war meine erste Reaktion, Floats zu verwenden. Wir könnten float: left für Nachrichten auf der linken Seite und float: right für Nachrichten auf der rechten Seite verwenden, damit sie an verschiedenen Rändern haften. Dann würden wir clear: both auf jede Nachricht anwenden, damit sie gestapelt werden. Aber es gibt einen viel moderneren Ansatz – Flexbox!

Wir können Flexbox verwenden, um die Listenelemente vertikal mit flex-direction: column zu stapeln und allen Kindern zu sagen, dass sie am linken Rand haften sollen (oder „die Randkanten der Flex-Kinder mit den Randkanten der Zeilen ausrichten“, wenn Sie die technischen Begriffe bevorzugen) mit align-items: flex-start. Dann können wir den align-items-Wert für einzelne Flex-Elemente überschreiben, indem wir align-self: flex-end darauf setzen.

Was, meinen Sie, Sie konnten den Code anhand dessen nicht visualisieren? Nun gut, hier ist, wie das aussieht.

.messages {
  /* Flexbox-specific styles */
  display: flex;
  flex-direction: column;
  align-items: flex-start;

  /* General styling */
  font: 16px/1.3 sans-serif;
  height: 300px;
  list-style-type: none;
  margin: 0 auto;
  padding: 8px;
  overflow: auto;
  width: 200px;
}

/* Default styles for chat bubbles */
.messages li {
  background: #eee;
  border-radius: 8px;
  padding: 8px;
  margin: 2px 8px 2px 0;
}

/* Styles specific to our chat bubbles */
.messages li.ours {
  align-self: flex-end; /* Stick to the right side, please! */
  margin: 2px 0 2px 8px;
}

Etwas Polsterung und Farben hier und da, und das sieht schon ähnlich genug aus, um zum unterhaltsamen Teil überzugehen.

Schritt 2: Lassen Sie uns die Dinge einfärben!

Die ursprüngliche Idee für den Farbverlauf kam mir tatsächlich von diesem Tweet von Matthias Ott (den Chris in einem anderen Beitrag nachgebildet hat)

Der entscheidende Hinweis hier ist mix-blend-mode, eine CSS-Eigenschaft, mit der wir steuern können, wie der Inhalt eines Elements mit dem dahinter liegenden Inhalt verschmilzt. Es ist eine Funktion, die es schon seit einiger Zeit in Photoshop und ähnlichen Werkzeugen gibt, aber im Web noch relativ neu ist. Es gibt einen Almanach-Eintrag für die Eigenschaft, der alle ihre vielen möglichen Werte erklärt.

Einer der Werte ist screen: Er nimmt die Werte der Pixel des Hintergrunds und des Vordergrunds, invertiert sie, multipliziert sie und invertiert sie noch einmal. Dies führt zu einer Farbe, die heller ist als die ursprüngliche Hintergrundfarbe.

Die Beschreibung kann etwas verwirrend erscheinen, aber im Wesentlichen bedeutet sie, dass, wenn der Hintergrund monochrom ist, die Vordergrundpixel dort vollständig sichtbar sind, wo der Hintergrund schwarz ist, und weiß bleibt, wo er weiß ist.

Mit mix-blend-mode: screen; im Vordergrund sehen wir mehr vom Vordergrund, wenn der Hintergrund dunkler ist.

Für unsere Zwecke wird der Hintergrund das Chatfenster selbst sein und der Vordergrund wird ein Element mit dem gewünschten Farbverlauf als Hintergrund enthalten, das über dem Hintergrund positioniert ist. Dann wenden wir den entsprechenden Mischmodus auf das Vordergrundelement an und gestalten den Hintergrund neu. Wir möchten, dass der Hintergrund dort schwarz ist, wo der Farbverlauf gezeigt werden soll, und an anderen Stellen weiß, also gestalten wir die Blasen, indem wir ihnen einen einfachen schwarzen Hintergrund und weißen Text geben. Ach ja, und vergessen wir nicht, pointer-events: none zum Vordergrundelement hinzuzufügen, damit der Benutzer mit dem darunter liegenden Text interagieren kann.

Zu diesem Zeitpunkt habe ich auch die ursprüngliche HTML-Datei ein wenig geändert. Der gesamte Chat ist ein Wrapper in einem zusätzlichen Container, der es dem Farbverlauf ermöglicht, über dem scrollbaren Teil des Chats „fest“ zu bleiben.

.messages-container:after {
  content: '';
  background: linear-gradient(rgb(255, 143, 178) 0%, rgb(167, 151, 255) 50%, rgb(0, 229, 255) 100%);
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 100%;
  mix-blend-mode: screen;
  pointer-events: none;
}

.messages li {
  background: black;
  color: white;
  /* rest of styles */
}

Das Ergebnis sieht in etwa so aus.

Der auf die Chatblasen angewendete Farbverlauf

Schritt 3: Einige Nachrichten vom Farbverlauf ausschließen

Jetzt wird der Farbverlauf dort gezeigt, wo die Textblasen darunter liegen! Wir möchten ihn jedoch nur über *unseren* Blasen anzeigen – denen am rechten Rand. Ein Hinweis darauf, wie dies erreicht werden kann, ist in MDNs Beschreibung der mix-blend-mode-Eigenschaft versteckt.

Die CSS-Eigenschaft mix-blend-mode legt fest, wie der Inhalt eines Elements mit dem Inhalt des übergeordneten Elements und dem Hintergrund des Elements verschmelzen soll.

Das ist richtig! Der Hintergrund. Natürlich berücksichtigt der Effekt nur die HTML-Elemente, die sich hinter dem aktuellen Element befinden und eine niedrigere Stapelreihenfolge haben. Glücklicherweise kann die Stapelreihenfolge von Elementen einfach mit der z-index-Eigenschaft geändert werden. Wir müssen also nur den Chatblasen auf der linken Seite einen höheren z-index als dem Vordergrundelement geben, und sie werden darüber gehoben, außerhalb des Einflusses von mix-blend-mode! Dann können wir sie so gestalten, wie wir möchten.

Der auf die Chatblasen angewendete Farbverlauf.

Lassen Sie uns über Browser-Support sprechen

Zum Zeitpunkt des Schreibens wird mix-blend-mode in Internet Explorer und Edge überhaupt nicht unterstützt. In diesen Browsern wird der Farbverlauf über den gesamten Chat gelegt und die Blasen anderer werden darüber angezeigt, was keine ideale Lösung ist.

Diese Browser-Support-Daten stammen von Caniuse, wo es mehr Details gibt. Eine Zahl bedeutet, dass der Browser die Funktion ab dieser Version unterstützt.

Desktop

ChromeFirefoxIEEdgeSafari
4132Nein79TP

Mobil / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712718.0

Das ist also, was wir in nicht unterstützten Browsern erhalten.

Wie Browser, die mix-blend-mode nicht unterstützen, den Chat rendern.

Glücklicherweise unterstützen alle Browser, die mix-blend-mode unterstützen, auch CSS Feature Queries. Mit ihnen können wir zuerst Fallback-Stile für nicht unterstützte Browser schreiben und die schicken Effekte für die Browser einfügen, die sie unterstützen. Auf diese Weise kann ein Benutzer, auch wenn er den vollständigen Effekt nicht sehen kann, den gesamten Chat sehen und damit interagieren.

Eine vereinfachte Benutzeroberfläche für ältere Browser, die auf eine einfache Cyan-Hintergrundfarbe zurückfällt.

Hier ist der finale Pen mit dem vollen Effekt und Fallback-Stilen.

Sehen Sie den Pen
Facebook Messenger-ähnliche Farbverlauf-Färbung in CSS
von Stepan Bolotnikov (@Stopa)
auf CodePen.

Sehen wir uns jetzt an, wie Facebook es gemacht hat

Es stellt sich heraus, dass Facebooks Lösung fast das Gegenteil dessen ist, was wir hier behandelt haben. Anstatt den Farbverlauf über den Chat zu legen und Löcher hineinzuschneiden, wenden sie den Farbverlauf als festes Hintergrundbild für den gesamten Chat an. Der Chat selbst ist mit einer ganzen Menge leerer Elemente mit weißen Hintergründen und Rändern gefüllt, außer dort, wo der Farbverlauf sichtbar sein soll.

Das von der Facebook Messenger React-App gerenderte finale HTML ist ziemlich ausführlich und schwer zu durchsuchen, daher habe ich ein minimales Beispiel nachgebildet, um es zu demonstrieren. Viele der leeren HTML-Elemente können stattdessen durch Pseudo-Elemente ersetzt werden.

Sehen Sie den Pen
Facebook Messenger-ähnliche Farbverlauf-Färbung in CSS: Der Facebook-Weg
von Stepan Bolotnikov (@Stopa)
auf CodePen.

Wie Sie sehen können, sieht das Endergebnis dem mix-blend-mode-Ansatz ähnlich, aber mit ein wenig zusätzlichem Markup. Zusätzlich bietet ihr Ansatz mehr Flexibilität für Rich Content wie Bilder und Emojis. Der mix-blend-mode-Ansatz funktioniert nicht wirklich, wenn der Hintergrund etwas anderes als monochrom ist, und ich konnte keinen Weg finden, den inneren Inhalt über den Farbverlauf zu „heben“ oder diese Einschränkung anderweitig zu umgehen.

Aufgrund dieser Einschränkung ist es ratsamer, den Ansatz von Facebook in einer tatsächlichen Chat-Anwendung zu verwenden. Dennoch zeigt unsere Lösung mit mix-blend-mode eine interessante Möglichkeit, eine der am meisten unterschätzten CSS-Eigenschaften im modernen Webdesign zu nutzen, und hoffentlich hat sie Ihnen einige Ideen gegeben, was Sie damit machen könnten!