Während Filter wie Kontrast, Sättigung und Weichzeichnung in Bildbearbeitungsprogrammen schon seit einiger Zeit existieren, erforderte deren Bereitstellung im Web historisch das Ausliefern von Bildern mit bereits angewendeten Filtern. Da Browser Filter als Teil der Webplattform zu integrieren beginnen, können wir komplexe visuelle Effekte in ihre Bestandteile zerlegen und sie im Web implementieren. Dieser Artikel untersucht einen solchen Effekt, den Milchglaseffekt, und wie CSS-Filter eine sauberere und flexiblere Lösung als statische Bilder bieten.
Old School: Milchglaseffekt mit Bildern
Der Milchglaseffekt ist im Internet schon seit einiger Zeit verbreitet; wir haben ihn hier auf CSS-Tricks bereits 2008 gesehen. Die Idee hinter dem Effekt ist relativ einfach: den Bereich hinter überlagertem Inhalt einfach weichzeichnen und aufhellen. Der Inhalt erhält einen höheren Kontrast zum Hintergrund, aber man behält trotzdem eine grobe Vorstellung davon, was dahinter vor sich geht. Der CSS-Tricks-Artikel verwendet zwei Bilder: eine Standardversion und eine mattierte Version (weichgezeichnet mit einem weißen Stich). In unserem Beispiel gleitet eine Karte hoch, um Inhalt freizugeben, während sie den Hintergrund mattiert.
Demo
Siehe den Pen Milchglaseffekt mit mehreren Bildern von betravis (@betravis) auf CodePen.
Das HTML
Das Markup ist relativ einfach. Wir haben nur einen einzigen Artikel, der Inhalt enthält.
<article class="glass down">
<h1>Pelican</h1>
<p>additional content...</p>
</article>
Das CSS
Wir dimensionieren zunächst alles auf das Viewport. Dann überlagern wir eine weichgezeichnete Version des Hintergrunds über dem ursprünglichen Hintergrund. Schließlich fügen wir einen weißen Stich hinzu. Der Überlauf wird versteckt, um Scrollen zu verhindern und den Effekt auf das .glass-Element zu beschneiden.
html, body, .glass {
width: 100%;
height: 100%;
overflow: hidden;
}
body {
background-image: url('pelican.jpg');
background-size: cover;
}
.glass::before {
display: block;
width: 100%;
height: 100%;
background-image: url('pelican-blurry.jpg');
background-size: cover;
content: ' ';
opacity: 0.4;
}
.glass {
background-color: white;
}
Die obige CSS erstellt unsere weichgezeichnete und aufgehellte Überlagerung. Wir müssen die Überlagerung auch nach unten zum unteren Ende der Seite verschieben, sodass gerade genug Platz bleibt, um den Header-Text zu sehen. Da das weichgezeichnete Bild ein Kind der Überlagerung ist, müssen wir es auch um den entgegengesetzten Betrag nach oben verschieben, um es mit dem Body-Hintergrund ausgerichtet zu halten. Da die Demo Übergänge verwendet, habe ich mich entschieden, CSS-Transformationen anstelle der Eigenschaft background-attachment zu verwenden, da CSS-Transformationen Hardware-beschleunigt sein können.
.glass.down {
transform: translateY(100%) translateY(-7rem);
}
.glass.down::before {
transform: translateY(-100%) translateY(7rem);
}
.glass.up, .glass.up::before {
transform: translateY(0);
}
Notizen
Die obige Technik ist unkompliziert und hat eine solide Browserunterstützung. Obwohl ich die Demo mit Übergängen etwas aufgepeppt habe, haben die anderen erforderlichen Funktionen – generierter Inhalt, Deckkraft, Transformationen und Hintergrundgröße – alle eine solide Browserunterstützung, die bis IE 9 zurückreicht (mit Ausnahme von Opera Mini).
New School: Milchglaseffekt mit Filtern
Die Technik mit dem doppelten Bild erfordert die Beibehaltung eines weichgezeichneten Bildes neben dem Original, was zu einer Qual werden kann, wenn man den Effekt für mehrere Bilder wiederverwenden muss. Responsive Designs erfordern beispielsweise möglicherweise den Austausch verschiedener Bilder bei unterschiedlichen Bildschirmgrößen. Oder Vorlagenlayouts können Bilder dynamisch einfügen (z. B. ein anderes Header-Bild für jeden Blogbeitrag). In diesen Fällen wäre es schön, den Effekt nur mit dem Quellbild zu generieren. Schließlich blenden wir es nur aus.
Hier kommen CSS-Filter ins Spiel. Sie erlauben uns, die Unschärfe im Browser anzuwenden, mithilfe von der CSS-Eigenschaft filter.
Das CSS
Wir können die CSS für die mattierte Glasüberlagerung so anpassen, dass sie das Originalbild mit einem angewendeten blur-Filter ist.
.glass::before {
background-image: url('pelican-blurry.jpg');
}
.glass::before {
background-image: url('pelican.jpg');
filter: blur(5px);
}
Demo
Siehe den Pen Milchglaseffekt mit Filtereffekten von betravis (@betravis) auf CodePen.
Einschränkungen
Kinderleicht, oder? Leider sind CSS-Filter relativ neu. Das bedeutet, dass sie möglicherweise mit Vendor-Präfixen versehen sind und dass ihre Browserunterstützung noch nicht universell ist. Filter haben jedoch eine längere Geschichte in SVG, und das Anwenden von SVG-Filtern auf HTML-Inhalte über CSS hat eine breitere Browserunterstützung. Sie können sie leicht als Fallback für den Fall hinzufügen, dass CSS-Filter nicht unterstützt werden. Die obige Demo macht das tatsächlich.
Um einen SVG-Filter hinzuzufügen, fügen wir etwas Inline-SVG in unser HTML-Markup ein und referenzieren den Filter mit einer url(). Profi-Tipp: Eine Alternative ist, den SVG-Filter zu kodieren und als Daten-URL zu referenzieren, aber dieses Format ist in einem Artikel etwas schwieriger zu lesen.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="blur">
<feGaussianBlur stdDeviation="5" />
</filter>
</defs>
</svg>
.glass::before {
background-image: url('pelican.jpg');
/* Fallback to SVG filters */
filter: url('#blur');
filter: blur(5px);
}
Es wird immer noch Fälle geben, in denen weder CSS- noch SVG-Filter von einem Browser unterstützt werden. In diesem Fall sieht der Benutzer Text auf einem aufgehellten (getönten, aber unscharfen) Hintergrund, was nicht schlecht ist.
Fazit
Filter ermöglichen es uns, Effekte im Browser zu verwenden, die zuvor nur in Bildbearbeitungsprogrammen verfügbar waren. Als Stil eines Elements, anstatt als gerendertes Bild, sind sie leichter zu ändern und wiederzuverwenden. Sie können CSS-Filter in aktuellen Versionen von Chrome, Safari und Opera verwenden, und sie werden aktiv in Firefox entwickelt (noch keine Nachricht für Internet Explorer). Mit etwas Sorgfalt für das Fallback-Verhalten können Sie sie noch heute verwenden.
Im "New School" CSS-Vorbeispiel. Wollten Sie pelican.jpg und nicht pelican-blurry.jpg? Wenn ich falsch liege, können Sie meinen Kommentar gerne löschen.
@Jared: Im „New School“-Beispiel verwendet er ‚filter: blur(5px);‘, daher ist pelican-blurry.jpg nicht nötig. Deshalb ist es New School.
Ja, ich stimme zu, es ist ein Tippfehler
@Jared, @Strve: Beziehen Sie sich auf die Abschnitte „CSS Before“ und „CSS After“ zu Beginn des New-School-Abschnitts? Ich hätte das klarer aufteilen sollen, aber „CSS Before“ soll die Syntax im alten Stil (pelican-blurry.jpg) darstellen, während „CSS After“ die angepasste Syntax im neuen Stil (pelican.jpg + Blur-Filter) demonstriert. Ich nehme an, es hilft nicht, dass ich auch das ::before-Pseudoelement in der CSS verwende.
nett :)
Wäre cool gewesen, als skeumorphes Design im Trend lag, aber heutzutage eher veraltet. Beeindruckend trotzdem.
Der Kontrast zwischen Text und Hintergrundbild ist niemals veraltet. Dies ist nur eine Möglichkeit, dies zu tun.
So veraltet, dass Apple es in das neueste iOS integriert hat, meinst du?
Ich denke, das größte Problem bei CSS-Filtern ist immer noch die Leistung. Ich erinnere mich, dass ich kürzlich versucht habe, einen ähnlichen mattierten Effekt auf einem Vollbild-, Retina-Bild zu erzielen, und selbst auf meinem 12-Kern-MacPro hatte Chrome plötzlich erhebliche Schwierigkeiten beim Scrollen der Seite und jegliche CSS-Übergänge wurden unmöglich.
Hatte ungefähr eine Woche zuvor genau das gleiche Problem. Habe den Effekt aus der App, die ich gerade erstellte, entfernt. Er ist großartig, wenn er sparsam eingesetzt wird, kann aber die CPU stark belasten, wenn er nicht sorgfältig gehandhabt wird.
@ryab, @mike: Der Effekt kann kostspielig sein, besonders bei großen Bildern. Wenn einer von Ihnen Beispiele teilen kann, bei denen die Leistung des Effekts problematisch wurde, würde ich mich sehr für eine Betrachtung interessieren. Der einzige Tipp, den ich geben kann, betrifft Animationen und Übergänge, bei denen es manchmal hilfreich sein kann, den Effekt GPU-freundlicher zu gestalten.
@Bear, wenn es doch nur eine einmal schreibbare, überall laufende Lösung für das Web gäbe, die all diese Effekte bereits unterstützt ;P
Ich habe etwas Ähnliches mit dem Filterausdruck gemacht (http://codepen.io/jamespr/pen/aipgo). Freut mich, solche Effekte zu sehen.
Sollte ich nicht Präfixe für den Browser verwenden?
Mein Pen http://codepen.io/Shaz3e/pen/qJwnx/
@Shaz3e,
Nur -webkit ist erforderlich, was in der Demo verwendet wird.
http://caniuse.com/css-filters
@Shaz3e: Ja, Sie müssen möglicherweise Vendor-Präfixe verwenden, obwohl, wie Dan erwähnt, derzeit nur -webkit unterstützt wird. Die Demo verwendet Prefix Free, aber ich musste explizit die -webkit-Filtervariante hinzufügen. Ich habe mich auch entschieden, die Browserunterstützung auf IE 9 und höher zu vereinfachen und daher die ältere IE-Filter-Syntax (veraltet IE 9, nicht unterstützt ab IE 10) fallen gelassen.
Vielen Dank @Dan Mathisen & @Bear Travis für Ihre Kommentare, ich denke, ich sollte für mein nächstes Projekt Prefix Free verwenden.
Ausgezeichnet! Ich habe nach einfacheren Möglichkeiten gesucht, den iPhone-Effekt von weichgezeichneten Hintergründen mit Scrollen zu integrieren. Ich kann es kaum erwarten, bis es breiter akzeptiert wird!
Ich glaube, ich habe einen Fehler gefunden… Ich kann den Weichzeichnungseffekt auf meinem Android 4.4 KitKat mit dem neuen Google Chrome nicht sehen? Hat jemand anderes dieses Problem?
Ja, das habe ich auch.
Schlüssel (unerwünschter) Unterschied: gefiederte Kanten. Das CSS-gefilterte Bild erzeugt weiche gefiederte Kanten, und meines Wissens gibt es keine Möglichkeit, sie zu beschneiden. Der Browser wendet die Weichzeichnung auf den sichtbaren Teil des Bildes an, auch wenn es innerhalb eines kleineren Elements mit overflow:hidden beschnitten ist. Die einzige Lösung, die ich für eine schöne, saubere Weichzeichnung gefunden habe, ist die Verwendung von Canvas zum Importieren der Bilddaten, das Ausführen eines Weichzeichnungsfilters auf den Daten und das Exportieren des weichgezeichneten Bildes mit toDataURL, oder alternativ die Verwendung des Canvas selbst.
Schauen Sie hier für einige gute Weichzeichnungen: https://github.com/Quasimondo/QuasimondoJS/tree/master/blur
#protip – importieren Sie das Bild in ein kleineres Canvas (es ist ohnehin ein verlustbehafteter Prozess), aber es umgeht eine enge Engstelle in Safari.
Ich habe diesen Trick mit großem Erfolg bei Videos angewendet und eine volle 60fps auf allen Geräten erzielt. Stören Sie mich auf Twitter (@furf), und ich poste die Codebeispiele.
Beispiele für die Canvas-Blur-Implementierung über Video (wie oben erwähnt).
http://www.furf.com/exp/video-blur/
Ich stimme zu, dass die gefiederten Kanten etwas frustrierend sein können. In bestimmten Fällen können Sie ein etwas größeres weichgezeichnetes Bildelement auf sein übergeordnetes Element zuschneiden, um eine scharfe Kante zu erhalten. Ich habe eine kurze Mock-up erstellt, wie das mit der Demo in diesem Artikel aussehen würde.
Schön. Aus irgendeinem Grund konnte ich den Beschnitt nie zum Laufen bringen. Muss meine Demo nochmal prüfen :) Danke!
Der CSS-Blur-Filter erzeugt hässliche Gradienten zum Rand hin.
Sehr coole Sache. Interessanterweise funktioniert die Old-School-Version bei mir in Safari 6.1 nicht.
Würde man nicht
inheritfür den background-image-Wert verwenden können, um die Wiederholung der URL zu verhindern, wenn manfilter:blur()verwenden würde?Leider nicht in diesem Fall, da der Elternteil von .glass::before .glass ist und das Hintergrundbild auf dem Body gesetzt ist.
Nur zur Info, dies ist „in Erwägung gezogen“ für IE12
Vor einiger Zeit habe ich mit CSS-Filtern und Scrollen experimentiert.
Zwei Pens zum Genießen von CSS
Dynamische Innen-Weichzeichnung
Dynamische Außen-Weichzeichnung
@Kseso, danke für deine Idee.
Die New-School-Version gefällt mir überhaupt nicht. Die Blur-Eigenschaft zerstört die klare Kante und fügt einen Halo um das Bild.
Ich hasse die Blur-Eigenschaft wirklich.
„und fügt einen Halo um das Bild hinzu“
Das sehe ich nicht. Welcher Browser? Ich benutze Chrome 33.
Der Halo ist sehr gering, aber in der oberen Demo noch vorhanden.
Erhöhen Sie die Weichzeichnung und die Deckkraft, dann sehen Sie ihn.
Chrome – Version 33.0.1750.152
Ich habe das pelican-Bild auf 400 % vergrößert und sehe überhaupt keinen Halo. Das könnte eine persönliche wahrgenommene visuelle Verzerrung sein.
Es wäre noch besser, wenn wir das ohne eine zweite Instanz des Bildes hinbekommen könnten. Ich weiß, dass viele Leute (einschließlich meiner selbst) nach Wegen suchen, den mattierten Effekt über nicht-Bild-HTML-Elementen darunter zu legen. Es gibt Workarounds, wenn die Überlagerung bildschirmfüllend ist, aber nicht, wenn der mattierte Effekt mitten im Bildschirm abgeschnitten werden muss.
Brillant, genau das, was ich gesucht habe. Vielen Dank.
Hallo
Ich bin etwas verwirrt, ich habe den CodePen nachgebaut und er erscheint nicht gleich, als ob ich nicht die richtige Schriftart (Source Sans Pro) bekomme? Irgendwelche Ideen, warum das so wäre?
Am Ende habe ich einfach den HTML-, CSS- und JS-Code von Ihrem in meinen kopiert und es ist immer noch dasselbe.
Mein Pen und Ihrer Ihr Pen
Gefunden, musste die Einstellungen in der CSS ändern und die Schriftarten laden!! Habe erst jetzt das Zahnrad-Symbol bei Codepen bemerkt.
Aus irgendeinem Grund, als ich diese Theorie auf ein Hintergrundbild innerhalb eines absolut positionierten Pseudoelements eines Flexbox-Items angewendet und es gedreht habe, deaktiviert es das Hintergrundbild selbst in Firefox. Seltsam, und das sogar, nachdem ich jeden Stil außer dem Filter und dem Hintergrundbild deaktiviert habe (sogar den Inhalt: „;“), und es funktioniert immer noch nicht.
Ich frage mich, ob es tatsächlich eine konkrete Lösung dafür gibt. Habe Referenzen auf StackOverflow gefunden, aber keine der Lösungen scheint zu funktionieren.
Wäre es möglich, das mit einem Videohintergrund zu machen?
http://furf.com/exp/video-blur
Erreicht mit Canvas.