Es begann damit, dass ich mir einen aktuellen Pen von Mandy Michael mit ihren Text-Effekt-Demos ansah. Ich bin ein sehr visueller Mensch, daher bemerkte ich zuerst den Effekt und nicht den Titel (der klar angibt, wie der Effekt erzielt wurde). Sofort dachte ich: „Blend-Modi!“, was sich als falsch herausstellte.
Die Demo verwendet tatsächlich clip-path. Zuerst wird der Text dupliziert. Wir haben schwarzen Text darunter als eigentlichen Textinhalt des Elements und den weißen Text darüber als Wert der content-Eigenschaft (entnommen aus einem Data-Attribut, das über JS aktualisiert wird). Diese beiden werden übereinander gestapelt (sie überlappen sich vollständig). Dann wird das Pseudoelement mit dem weißen Text oben auf die Form des schwarzen Kleides zugeschnitten.
Das bedeutet jedoch, dass wir den Clipping-Pfad ändern müssen, wenn wir das Bild ändern, und zu diesem Zeitpunkt ist es alles andere als einfach, polygonale Clipping-Pfade mit vielen Punkten über Entwicklertools herauszufinden (weshalb etwas wie Benett Feelys Clippy mit zweiseitiger Bearbeitung direkt in Entwicklertools immens nützlich wäre). Also beschloss ich, meine ursprüngliche Idee – Blend-Modi – auszuprobieren.
Nehmen wir an, wir haben eine Überschrift in einem contentEditable1-Container mit einem schwarzen und weißen Bild (naja, Graustufen) als background. Die HTML-Struktur ist wie folgt:
<header>
<h2 contentEditable role='textbox' aria-multiline='true'>And stay alive</h2>
</header>
Wir setzen das background-image auf den header-Container, geben dem h2 weißen Text und setzen seinen mix-blend-mode auf difference oder exclusion. Das relevante CSS ist unten:
header { background: url(black-and-white-image.jpg) }
h2 {
color: white;
mix-blend-mode: difference;
}
Ich kann Blend-Modi nicht wirklich verstehen oder normalerweise einen Unterschied zwischen difference und exclusion erkennen, aber laut MDN sind sie ziemlich gleich, wobei exclusion weniger Kontrast hat. Was ich in dieser Situation verstehen kann, ist, dass weißer Text über dem Bild ein Ergebnis liefert, das dem invertierten Bild entspricht, wo der Text es überlappt. Für einfache Schwarz-Weiß-Bilder wird Schwarz im Originalbild zu Weiß dort, wo wir weißen Text darüber haben, und Weiß im Originalbild wird zu Schwarz dort, wo wir weißen Text darüber haben.
Das Ergebnis ist in folgendem Pen zu sehen
Siehe den Pen von thebabydino (@thebabydino) auf CodePen.
Mission erfüllt! Sowohl der Text als auch das Bild können geändert werden und der Effekt bleibt erhalten, ohne dass JavaScript oder Änderungen am CSS erforderlich sind.
Aber ich stellte sofort fest, dass es noch ein weiteres Problem gab: Was passiert, wenn das Bild nicht nur schwarz-weiß ist? Nun, versuchen wir das! Es stellt sich heraus, dass das Ergebnis tatsächlich ziemlich gut aussieht.
Siehe den Pen von thebabydino (@thebabydino) auf CodePen.
Der Text ist jedoch nicht mehr Graustufen, und das Setzen von filter: grayscale(1) ändert nichts. Funktioniert irgendein filter-Wert? Nun, ich habe als nächstes drop-shadow() ausprobiert, um eine Antwort auf diese Frage zu finden. Und die Antwort ist, dass drop-shadow() funktioniert, aber die Art und Weise, wie es funktioniert – der Schatten wird mit dem header-Hintergrund vermischt2 – gibt einen Hinweis darauf, warum grayscale() nichts geändert hat: Filter werden *vor* dem Mischen angewendet, unser Text ist weiß und die Ausgabe von grayscale() ist in diesem Fall identisch mit seiner Eingabe (weiß rein, weiß raus). Und da sich vor dem Mischen nichts ändert, ist das Ergebnis dasselbe.
Siehe den Pen von thebabydino (@thebabydino) auf CodePen.
Das hätte wahrscheinlich keine Überraschung sein dürfen. Ich bin schon früher auf Probleme gestoßen, die durch die Reihenfolge der Eigenschaften verursacht wurden.
Zum Beispiel wird filter auch *vor* clip-path angewendet. Wenn wir also ein Element auf eine nicht-rechteckige Form zuschneiden und einen Schatten darauf haben wollen, Pech gehabt, das Setzen des filter auf demselben Element liefert nicht das erwartete Ergebnis. Das liegt daran, dass das rechteckige Element den filter angewendet bekommt, sodass wir einen Schatten um seine rechteckige Box haben und *erst danach* wird es auf die Form zugeschnitten, die über clip-path angegeben wurde. Dies ist immer die Reihenfolge, in der diese beiden angewendet werden, unabhängig von der Reihenfolge, in der Sie sie in CSS festlegen.

filter und clip-path anwenden, wenn sie auf dasselbe Element gesetzt sind.Die Lösung für das filter + clip-path-Problem besteht darin, den filter auf ein Elternelement zu setzen, bei dem nichts sichtbar ist außer dem zugeschnittenen Kind. Der Teil „nichts sichtbar“ ist wichtig, denn wenn das Elternteil sichtbaren Text oder Ränder hat, bekommen diese ebenfalls den Schatten, während wenn es einen Hintergrund hat, der gesamte Hintergrundbereich den Schatten erhält.
Siehe den Pen von thebabydino (@thebabydino) auf CodePen.
Diese Lösung funktioniert jedoch nicht auch für das filter + mix-blend-mode-Problem. Wenn wir unseren h2 in ein div einwickeln und filter auf dieses div setzen, bricht dies den Mischungseffekt.
Siehe den Pen von thebabydino (@thebabydino) auf CodePen.
Schlimmer noch, ich kann mir nichts einfallen lassen, um dieses Problem zu umgehen. Es mag einen Weg geben, dies durch Duplizieren des Textes und Verwendung eines luminosity-Blend-Modus zu erreichen, aber wie bereits erwähnt, verstehe ich Blend-Modi nicht wirklich und habe es nicht geschafft, das richtig hinzubekommen.
Aber vielleicht könnten wir einen völlig anderen Ansatz versuchen, der kein Mischen verwendet. All das Spielen mit Filtern brachte mich auf die Idee, das Bild auf den Text anzuwenden, dann einen invert()-Filter anzuwenden, an den wir grayscale(), contrast() und mehr anhängen könnten.
Mit dieser Methode, die background-clip: text verwendet, haben wir auch den Vorteil einer browserübergreifenden Lösung, da Firefox und Edge dies inzwischen auch implementiert haben.
Der Weg, wie wir das machen, ist folgender: Wir stellen sicher, dass der header und das h2 identische Hintergründe haben und dass sich diese Hintergründe perfekt überlappen. Dann setzen wir color: transparent auf das h2 und schneiden seinen Hintergrund auf text zu. Der letzte Schritt ist das Setzen von filter: invert(1) auf das h2. Das relevante CSS3 ist wie folgt:
h2 {
background: inherit;
background-clip: text;
color: transparent;
filter: invert(1);
}
Das Ergebnis ist in folgendem Pen zu sehen
Siehe den Pen von thebabydino (@thebabydino) auf CodePen.
Es sieht aus wie zuvor, außer dass es eine andere Methode verwendet und wir jetzt mehr Funktionen an die filter-Eigenschaft anhängen können. Zum Beispiel können wir den Text in Graustufen umwandeln und seinen Kontrast erhöhen.
filter: invert(1) grayscale(1) contrast(9)
Siehe den Pen von thebabydino (@thebabydino) auf CodePen.
Das Ändern des filter-Wertes ist auch, wie wir einen Textschatten hinzufügen. Während wir im ersten Fall (mit mix-blend-mode) einfach die text-shadow-Eigenschaft setzen können (und der Schatten ebenfalls mit dem Hintergrund gemischt wird), bricht das Setzen im zweiten Fall die Dinge.
Siehe den Pen von thebabydino (@thebabydino) auf CodePen.
Glücklicherweise können wir drop-shadow() an unseren Filter anhängen.
Siehe den Pen von thebabydino (@thebabydino) auf CodePen.
Der untenstehende Pen zeigt die beiden in diesem Artikel beschriebenen Methoden. Links haben wir die mix-blend-mode-Methode und rechts die background-clip- und filter-Methode (mit den zusätzlichen Graustufen- und Kontrastkomponenten). Der Text ist editierbar und die Thumbnails ermöglichen das Ändern des background-image.
Siehe den Pen von thebabydino (@thebabydino) auf CodePen.
Also, wenn wir diese Methoden gegeneinander ausspielen, welche ist besser?
Auf Ästhetik gehen wir nicht ein, da dies eine subjektive Angelegenheit ist und wahrscheinlich von Fall zu Fall und sogar von Stimmung zu Stimmung unterschiedlich ist.
Was die grundlegende Unterstützung angeht, hat die letzte Methode einen Vorteil, da sie in Edge unterstützt wird, während mix-blend-mode dies nicht tut (aber wenn Sie sie in Edge wünschen, stimmen Sie dafür, denn Ihr Feedback zählt). Mandys Originalbeispiel verwendet clip-path, eine weitere sehr nützliche Funktion, die leider auch nicht in Edge funktioniert (Sie können hier dafür abstimmen).
Wenn es um die Auswahl von Text geht, funktioniert die mix-blend-mode-Methode perfekt und sieht in den unterstützten Browsern am besten aus.

mix-blend-mode-MethodeBei der Verwendung der clip-path-Methode sieht die Auswahl sauber aus und der Text bleibt lesbar, aber sie schien in Firefox zu stolpern, als ich über dem Pseudoelement-Text war. Glücklicherweise erwies sich dieses Problem als leicht zu beheben: Setzen von pointer-events: none auf dem Pseudoelement.

clip-path-MethodeWas die letzte Methode angeht, kann die Auswahl unschön aussehen und den Text schwerer lesbar machen. Ganz zu schweigen davon, dass der Schatten in diesem Fall auf das gesamte Auswahlrechteck angewendet wird und nicht nur auf den eigentlichen Text.

background-clip: text + filter-MethodeAuch das Ändern von Text wird in Firefox bei der letzten Methode umständlich, der Bildschirm wird beim Tippen neuer Texte „schmutzig“.

background-clip: text + filter-MethodeDie clip-path-Methode hatte anfangs auch ein Problem mit der Änderung von Text in Firefox: Der Versuch, die Bearbeitung mitten im Pseudoelement-Text zu beginnen, funktionierte nicht. Glücklicherweise behebt das Setzen von pointer-events: none auf dem Pseudoelement auch dieses Problem.

clip-path-MethodeWas die Flexibilität bei der Textgestaltung angeht, schneidet die letzte Methode am besten ab, da das Anhängen von Filterfunktionen uns weit bringen kann.
Letztendlich hängt die Frage, welche besser ist, vom jeweiligen Anwendungsfall ab. Welche Browser sollen unterstützt werden? Ändert sich das Bild? Ändert sich der Text? Wie soll der Text visuell verändert werden?
1 contentEditable ist nicht in allen Browsern standardmäßig zugänglich, daher müssen wir Semantik bereitstellen, um das zu beheben.
2 Achten Sie bei Experimenten mit Blend-Modi auf die Lesbarkeitsprobleme, die sie verursachen können, insbesondere in Bezug auf den Kontrast. WCAG 2.0 besagt, dass, es sei denn, der Text bildet Teil rein dekorativer Bilder, er einen Mindestkontrastschwellenwert bestehen sollte. Werkzeuge wie Color ContrastAnalyzer können Ihnen helfen, diese Anforderung zu erfüllen.
3 Präfixe werden zur Kürze weggelassen, aber background-clip benötigt immer noch das -webkit--Präfix für WebKit-Browser (Firefox und Edge haben es ungeprägt implementiert, obwohl beide es auch mit dem -webkit--Präfix unterstützen, wahrscheinlich weil es bereits so stark mit diesem Präfix verwendet wurde) und dieses Präfix muss manuell/über eine Präprozessor-Mixin hinzugefügt werden, was etwas ist, das ich normalerweise nicht empfehle, aber in diesem speziellen Fall geschieht das automatische Präfixierung über Autoprefixer oder Prefixfree nicht (Prefixfree funktioniert über Feature-Erkennung, die keine Eigenschaften wie background-clip, filter oder clip-path erfasst, und dies ist das Autoprefixer-Problem). Was filter betrifft, so wird es jetzt ungeprägt in allen aktuellen Desktop-Browsern unterstützt und Autoprefixer kann es trotzdem präfixen.
Tolle Arbeit. Danke fürs Teilen!
Das Beeindruckendste, was ich je auf CSS Tricks gesehen habe. Ich kann es kaum erwarten, bis zum nächsten Mal, wenn ich dieses Problem habe!
Hat mir sehr gut gefallen. Dies ist eine großartige Verbesserung gegenüber dem, was ich früher getan habe. Ich suchte nach einer Möglichkeit, dies gegen flache Farben aus unbekannter Quelle arbeiten zu lassen.
Danke! Ich werde zurückgehen und einige Codes aktualisieren.:)
Das ist ein lebensrettender Trick, normalerweise verwende ich SVG-Masken, um diesen Effekt zu erzielen. Wie sieht es mit der Browserkompatibilität aus?
Funktioniert nicht für irgendeinen Microsoft-Browser (IE, Edge).
„Funktioniert nicht für irgendeinen Microsoft-Browser (IE, Edge).“
Ist das nicht die Standard-Entschuldigung für fast alles im Web? Jeden Tag lese ich Beiträge/Artikel/usw. und unvermeidlich gegen Ende werden sie diese Entschuldigung haben. Zu diesem Zeitpunkt denke ich, dass Microsoft-Browser nur als Chrome-Installationsanwendungen verwendet werden sollten.
IE ist tot und begraben. Die Beerdigung war vor über zwei Jahren. Entschuldigung, wenn Sie keinen Beerdigungskuchen bekommen haben. Auf jeden Fall hat das Ausgraben der Toten Jahre später die unangenehme Angewohnheit, einen hartnäckigen Gestank hervorzubringen, daher würde ich es nicht empfehlen.
Die Unterstützung für Desktop-Browser wird im Artikel diskutiert. Es ist wahr, nicht in einem separaten Abschnitt am Ende, daher könnten einige Stile des schrägen Lesens es verpassen.
Zur Wiederholung: Mandys
clip-path-Methode sowie meinemix-blend-mode-Methode werden derzeit in Edge nicht unterstützt. Ich wäre Ihnen sehr dankbar, wenn Sie sich die Zeit nehmen und dafür abstimmen würden, damit sie implementiert werden, denn die Priorität, die diesen Funktionen zugewiesen wird, hängt von der Anzahl der Leute ab, die sie anfordern. Hier sind die Links erneut:clip-pathAbstimmen für
mix-blend-modeDie letzte Methode funktioniert in Edge. Hier ist eine GIF-Aufnahme, wie sie in Edge funktioniert.
Ich werde auf jeden Fall abstimmen.
Es wäre wunderbar, die Unterstützung für Internet Explorer nicht als totes Thema betrachten zu müssen, aber der Browser ist noch nicht tot. Ja, seine Nutzung ist erheblich gesunken, aber er liegt immer noch an zweiter Stelle (1). Firefox hat tatsächlich weniger Marktanteil als Internet Explorer. Edge, das noch weniger Marktanteil hat als Firefox und Internet Explorer, wird in diesem Artikel berücksichtigt. Während zugegeben, das Wachstum der Edge-Nutzung zunimmt, (2) scheinen die Benutzer es nicht in einem Tempo anzunehmen, das dazu führen würde, dass es bald den Internet Explorer übertrifft.
Internet Explorer stirbt, aber Entwickler sind seinen Fängen noch nicht entkommen.
http://www.netmarketshare.com
https://arstechnica.com/information-technology/2017/01/2016-on-the-web-firefox-fights-back-as-microsofts-share-slumps/
Hallo,
Ich möchte diese Funktion nutzen, um Icons Kontrast zu geben, die absolut über Hintergrundelementen platziert sind, die einfache Vollfarben oder vielleicht Bilder haben könnten. Zweck sollte sein, immer „sichtbare“ Icons zu haben, unabhängig davon, was im Hintergrund ist.
Ist das möglich? Bitte beachten Sie, dass der Hintergrund nicht direkt auf dem übergeordneten Element liegt, sondern alles sein kann...
Die
mix-blend-mode-Methode funktioniert auf jedem Hintergrund (nicht nur dem unmittelbaren Elternteil), solange keines der übergeordneten Elemente Ihres Icons einen Stapelkontext etabliert, was die Isolierung von Mischungen erzwingt. Es ist in Ordnung, wenn das Icon selbst ein Stapelkontext ist (z. B. wenn es absolut positioniert ist): solange die Misch-Eigenschaft auf demselben Element wie die Isolierung gesetzt ist oder auf einem Element höher im Baum.Sie können einen
drop-shadow-Filter auf Ihrem Icon verwenden, um den gleichen Effekt wie ein Textschatten zu erzielen.Natürlich möchten Sie einen
@supports-Test verwenden, um sicherzustellen, dassmix-blend-modeundfilter: drop-shadow(...)unterstützt werden, und wenn nicht, verwenden Sie eine einfachere Methode, um den Kontrast sicherzustellen, wie z. B. einen soliden Hintergrund auf Ihrem Icon-Element.Das ist ein cooler Effekt, aber es gibt eine wichtige Sache, über die Sie nachdenken sollten, bevor Sie ihn verwenden. Wie unruhig ist das Hintergrundbild?
Gegen ein einfaches Bild funktioniert der Effekt gut. Wenn Sie versuchen, den Effekt gegen ein unruhiges Bild zu verwenden (wie die Seite eines Harley-Davidson-Motorrads zum Beispiel), wird der Text unglaublich schwer lesbar.
Dies ist also keine magische Barrierefreiheitskugel. Wenn der Kunde das Bild ändern kann (und das tut er normalerweise), könnte er leicht ein Bild hochladen, das aussieht, als käme es aus einem „Wo ist Walter?“-Buch und macht den Text unlesbar.
Es ist auch wichtig, dass der Text dick ist. Papierdünner Text geht eher in einem Hintergrundbild verloren als dicker Text.
Ich denke immer noch, dass die beste Methode, um Text hervorzuheben, eine kontrastierende Kontur (mit text-shadow) ist.
Ehrlich gesagt, ich benutze das immer noch vor allem anderen. Da ich keinen künstlerischen Sinn habe, fühlt es sich für mich einfacher und risikoreicher an. Es ist viel einfacher, Dinge zu vermasseln, wenn man Hintergründe einführt.
Funktioniert auch nicht in Safari (TP 29, 10.2).
Großartige Leistung. Danke fürs Teilen.
Was die Browserunterstützung angeht, muss man irgendwo anfangen. Niemand zwingt Sie, diese Funktionen zu verwenden. Wenn die Mehrheit Ihrer Benutzer IE oder andere nicht kompatible Browser verwendet, ist es vielleicht nichts für Sie. Sie können auch normalerweise ein JS-Polyfill finden, bis diese Benutzer aufrüsten.