Ich bin kürzlich auf einen coolen Effekt gesto?en, der als Glassmorphismus in einem Dribble -Schuss bekannt ist. Mein erster Gedanke war, dass ich es in ein paar Minuten schnell nachbilden konnte, wenn ich nur ein paar Emojis für die Ikonen benutze, ohne die Zeit für SVG-Inging zu verschwenden.
Ich h?tte mich nicht mehr in diesen ?wenigen Minuten“ falsch machen k?nnen - sie waren Tage, in denen sie wütend und frustrierend an diesem Juckreiz kratzten!
Es stellt sich heraus, dass es jedoch Ressourcen gibt, wie CSS ein solcher Effekt vorhanden ist, aber alle annehmen, dass die überlagerung rechteckig ist oder h?chstens ein Rechteck mit randlichem Radius. Es ist jedoch viel komplizierter als erwartet, dass es sich lohnt, den Prozess zu teilen, die Fallen, die ich auf dem Weg gelernt habe. Und auch die Dinge, die ich immer noch nicht verstehe.
Warum Emojis?
Kurze Antwort: Weil SVG zu viel Zeit braucht. Lange Antwort: Weil mir das künstlerische Gefühl fehlt, sie einfach in einen Bildredakteur zu zeichnen, aber ich bin mit der Syntax so vertraut, dass ich oft vorgefertigte SVGs zu weniger als 10% ihrer ursprünglichen Gr??e finde. Ich kann sie also nicht einfach verwenden, da ich sie im Internet finde - ich muss den Code wiederholen, um ihn super sauber und kompakt zu machen. Und das braucht Zeit. Viel Zeit, weil es detaillierte Arbeit ist.
Und wenn ich nur ein Menükonzept mit Symbolen schnell codieren m?chte, greife ich mit Emojis zurück und wende einen Filter auf sie an, um sie mit dem Thema übereinzustimmen, und das war's! Es ist das, was ich für diese Demo für flüssige Registerkarteninteraktion getan habe - diese Symbole sind alle Emojis! Der glatte Valley -Effekt verwendet die Maskenkompositionstechnik.
Okay, das wird unser Ausgangspunkt sein: Verwenden von Emojis für die Ikonen.
Die anf?ngliche Idee
Mein erster Gedanke war, die beiden Pseudos (mit Emoji -Inhalten) der Navigationsverbindungen zu stapeln, leicht versetzt und die untere mit einer Transformation zu drehen, damit sie sich nur teilweise überlappen. Dann würde ich den oberen Semitransparent mit einem Deckkraftwert kleiner als 1 machen, den Hintergrund-Filter () () darauf einstellen, und das sollte gerade genug sein.
Nachdem Sie das Intro gelesen haben, haben Sie wahrscheinlich herausgefunden, dass dies nicht wie geplant verlief, aber lassen Sie uns sehen, wie es in Code aussieht und welche Probleme es damit gibt.
Wir erzeugen die Navigationsleiste mit dem folgenden Mops:
- sei data = { - Home: {ICO: '?', Hue: 200}, - Hinweise: {ICO: '? umpf', Hue: 260}, - Aktivit?t: {ICO: '?', Hue: 320}, - Entdeckung: {ICO: '?', Hue: 30} -}; - sei E = Object.Entries (Daten); - Sei n = E.Length; Navigation - für (lass i = 0; i> n; i) a (href = ' #' data-ICO = e [i] [1] .ICO style = `--hue: $ {e [i] [1] .hue} Deg`) #{e [i] [0]}
Welche zum HTML unten kompiliert:
<nav> <a href="'#'" data-ico="'?'" style="'-hue:"> home </a> <a href="'#'" data-ico="'?" style="'-hue:"> Notizen </a> <a href="'#'" data-ico="'?'" style="'-hue:"> Aktivit?t </a> <a href="'#'" data-ico="'?'" style="'-hue:"> iscovery </a> </nav>
Wir beginnen mit dem Layout und machen unsere Elemente Grid -Gegenst?nde. Wir legen den NAN in der Mitte, geben Links explizite Breiten, legen beide Pseudos für jeden Link in die obere Zelle (der den Link-Text-Inhalt in die untere Zelle drückt) und richten Sie den Link-Text und die Pseudos aus.
K?rper, NAV, A {Anzeige: Grid; } K?rper { Rand: 0; H?he: 100VH; } nav { Grid-Auto-Flow: S?ule; Ort selbst: Zentrum; Polsterung: .75em 0 .375em; } A { Breite: 5EM; Text-Align: Mitte; & :: vor, & :: nach { Gitterfl?che: 1/1; Inhalt: Attr (Data-ICO); } }
Beachten Sie, dass das Aussehen der Emojis je nach Browser, den Sie verwenden, die Demos verwenden wird.
Wir w?hlen eine lesbare Schriftart, st?bern ihre Gr??e, machen die Symbole noch gr??er, setzen Hintergründe und eine sch?nere Farbe für jede der Links (basierend auf der benutzerdefinierten Eigenschaft -Hue im Stilattribut jedes):
K?rper { / * wie früher */ Hintergrund: #333; } nav { / * wie früher */ Hintergrund: #fff; Schriftart: Clamp (.625EM, 5VW, 1,25EM)/ 1,25 Ubuntu, Sans-Serif; } A { / * wie früher */ Farbe: HSL (var (-Hue), 100%, 50%); Textdekoration: Keine; & :: vor, & :: nach { / * wie früher */ Schriftgr??e: 2.5EM; } }
Hier werden die Dinge interessant, weil wir zwischen den beiden Emoji -Ebenen unterscheiden, die mit den Link -Pseudos erstellt wurden. Wir bewegen uns leicht und drehen das :: vor Pseudo, machen es mit einem Sepia (1) -Filter monochrom, bringen Sie es auf den rechten Farbton und st?bern Sie in den Kontrast () - eine alte, aber Goldie -Technik von Lea Verou. Wir wenden auch einen Filter an: Graustufen (1) auf das :: nach pseudo und machen es semitransparent, weil wir sonst nicht in der Lage w?ren, den anderen Pseudo durch ihn zu sehen.
A { / * wie früher */ & :: vor { verwandeln: translate (.375em, -.25em) drehen (22,5 Grad); Filter: Sepia (1) Hue-rotate (calc (var (-hue)-50 Grad)) ges?ttigt (3); } &::nach { Deckkraft: .5; Filter: Graustufen (1); } }
Eine Wand treffen
So weit, so gut ... na und? Der n?chste Schritt, den ich dumm dachte, w?re der letzte, wenn ich die Idee hatte, dies zu codieren, beinhaltet das Einstellen eines Hintergrunds-Filters: Blur (5PX) auf der oberen (:: After) -Schiete.
Beachten Sie, dass Firefox noch die GFX.Webrender.All und layout.css.backdrop-filter.Enabled Flags ben?tigen.
Leider sieht das Ergebnis nicht so aus, was ich erwartet hatte. Wir erhalten eine Art überlagerung der Gr??e des gesamten oberen Symbols, aber das untere Symbol ist nicht wirklich verschwommen.
Ich bin mir jedoch ziemlich sicher, dass ich zuvor mit Backdrop-Filter: Blur () gespielt habe und es hat funktioniert. Was zum Teufel ist hier zu haarig?
An die Wurzel des Problems kommen
Nun, wenn Sie überhaupt keine Ahnung haben, warum etwas nicht funktioniert, k?nnen Sie nur ein weiteres funktionierendes Beispiel nehmen, es anzupassen, um zu versuchen, das gewünschte Ergebnis zu erzielen ... und zu sehen, wo es bricht!
Sehen wir uns also eine vereinfachte Version meiner ?lteren funktionierenden Demo an. Die HTML ist nur ein Artikel in einem Abschnitt. Im CSS haben wir zun?chst einige Dimensionen festgelegt, dann einen Bildhintergrund in den Abschnitt und einen halbtransparenten im Artikel festgelegt. Schlie?lich setzen wir die Eigenschaft im Hintergrund-Filter auf dem Artikel.
Abschnitt {Hintergrund: URL (Cake.jpg) 50%/ Cover; } Artikel { Rand: 25VMin; H?he: 40 VH; Hintergrund: HSLA (0, 0%, 97%, .25); Backdrop-Filter: Blur (5px); }
Das funktioniert, aber wir wollen nicht, dass unsere beiden Schichten ineinander verschachtelt sind. Wir m?chten, dass sie Geschwister sind. Lassen Sie uns also beide Schichtartikel -Geschwister erstellen, sie teilweise überlappen und prüfen, ob unser Glasmorphismus -Effekt noch funktioniert.
<article class="'base'"> </article> <article class="'Gray'"> </article>
Artikel {Breite: 66%; H?he: 40 VH; } .Base {Hintergrund: URL (Cake.jpg) 50%/ Cover; } .grau { Marge: -50% 0 0 33%; Hintergrund: HSLA (0, 0%, 97%, .25); Backdrop-Filter: Blur (5px); }
In Chrome scheint immer noch alles in Ordnung zu sein und zum gr??ten Teil auch Firefox. Es ist nur so, wie Blur () an den R?ndern in Firefox umst?ndlich und nicht so aussieht, was wir wollen. Und basierend auf den wenigen Bildern der Spezifikation glaube ich, dass das Firefox -Ergebnis auch falsch ist?
Ich nehme an, eine Fix für das Firefox-Problem in dem Fall, in dem unsere beiden Schichten auf einem festen Hintergrund (in diesem speziellen Fall wei?) sitzen, besteht darin, die untere Schicht (.base) einen Box-Shadow ohne Offsets, ohne Unsch?rfe und einen auf der oberen Schicht angewendeten Spread-Radius zu geben, der doppelt so hoch ist. Sicher genug, diese Korrektur scheint in unserem speziellen Fall zu funktionieren.
Die Dinge werden viel haariger, wenn unsere beiden Schichten auf einem Element mit einem Bildhintergrund sitzen, der nicht behoben ist (in diesem Fall k?nnten wir einen Ansatz von Layered -Hintergründen verwenden, um das Problem der Firefox zu l?sen), aber das ist hier nicht der Fall, daher werden wir uns nicht damit einlassen.
Gehen wir trotzdem mit dem n?chsten Schritt über. Wir m?chten nicht, dass unsere beiden Schichten zwei Quadratk?sten sind. Wir m?chten dann Emojis, was bedeutet, dass wir nicht sicherstellen k?nnen, dass die Semitransparenz für den oberen mit einem HSLA () -Gtinten Hintergrund eine Semitransparente für die obere Weise sicherstellen kann - wir müssen die Opazit?t verwenden.
.grau { / * wie früher */ Deckkraft: .25; Hintergrund: HSL (0, 0%, 97%); }
Es sieht so aus, als h?tten wir das Problem gefunden! Aus irgendeinem Grund bricht die Top-Layer-Semitransparent mithilfe der Opazit?t den Hintergrund-Filter-Effekt sowohl in Chrom als auch in Firefox aus. Ist das ein Fehler? Soll das passieren?
Fehler oder nicht?
MDN sagt Folgendes im ersten Absatz auf der Seite Backdrop-Filter:
Da es für alles hinter dem Element gilt, müssen Sie das Element oder seinen Hintergrund zumindest teilweise transparent machen.
Wenn ich den obigen Satz nicht verstehe, scheint dies darauf hinzudeuten, dass die Opazit?t den Effekt nicht brechen sollte, obwohl dies sowohl in Chrom als auch in Firefox der Fall ist.
Was ist mit der Spezifikation? Nun, die Spezifikation ist eine riesige Textwand ohne viele Illustrationen oder interaktive Demos, die in einer Sprache geschrieben wurden, die das Lesen so ansprechend wie das Schnüffeln eines Stinkters einsetzt. Es enth?lt diesen Teil, den ich ein Gefühl habe, aber ich bin mir nicht sicher, dass ich verstehe, was es zu sagen versucht-dass die Opazit?t, die auf dem oberen Element festgelegt ist, auf dem wir auch den Hintergrund-Filter haben, auch auf das Geschwister darunter angewendet wird? Wenn dies das beabsichtigte Ergebnis ist, geschieht es in der Praxis sicherlich nicht.
Die Wirkung des Hintergrundfilters ist nicht sichtbar, es sei denn, ein Teil des Elements B ist halbtransparent. Beachten Sie auch, dass jede an Element B angewendete Deckkraft auch auf das gefilterte Hintergrundbild angewendet wird.
Zuf?llige Dinge versuchen
Unabh?ngig von der Spezifikation bleibt die Tatsache bestehen: Die Top -Layer -Semitransparent mit der Eigenschaft der Opazit?t bricht den Glassmorphismus -Effekt sowohl in Chrom als auch in Firefox. Gibt es eine andere M?glichkeit, einen Emoji -Semitransparenten zu machen? Nun, wir k?nnten versuchen, Filter zu filtern: Deckkraft ()!
An diesem Punkt sollte ich wahrscheinlich berichten, ob diese alternative Funktionsweise funktioniert oder nicht, aber die Realit?t ist… Ich habe keine Ahnung! Ich habe ein paar Tage in diesem Schritt in der Zwischenzeit verbracht und den Test in der Zwischenzeit unz?hlige Male überprüfen - manchmal funktioniert er, manchmal nicht in den gleichen Browsern, mit unterschiedlichen Ergebnissen je nach Tageszeit. Ich fragte auch auf Twitter und bekam gemischte Antworten. Nur einer dieser Momente, in denen Sie sich fragen k?nnen, ob ein Halloween -Geist Ihren Code nicht verfolgt, Angst und Narben. Für die Ewigkeit!
Es sieht so aus, als ob alle Hoffnung weg ist, aber versuchen wir es nur noch eins: Ersetzen der Rechtecke durch Text, wobei der obere Semitransparent mit Farbe ist: hsla (). Wir k?nnen den coolen Emoji -Glassmorphismus -Effekt, den wir gesucht haben, m?glicherweise nicht erzielen, aber vielleicht k?nnen wir ein solches Ergebnis für einfachen Text erzielen.
Daher fügen wir unseren Artikelelementen Textinhalte hinzu, l?schen ihre explizite Gr??e, st?bern ihre Schriftgr??e, passen den Rand an, der uns teilweise überlappungen gibt und vor allem die Hintergrunddeklarationen in der letzten Arbeitsversion durch farbige Version ersetzen. Aus Gründengründen setzen wir auch Aria-Hidden = 'True' unten.
<article class="'base'" aria-hidden="'true'"> lion? </article> <artikel class="'Gray'"> Lion? </artikel>
Artikel {Schriftart: 900 21VW/ 1 Cursive; } .base {color: #ff7a18; } .grau { Rand: -.75em 0 0 .5EM; Farbe: HSLA (0, 0%, 50%, .25); Backdrop-Filter: Blur (5px); }
Hier gibt es ein paar Dinge zu beachten.
Erstens macht es Emojis -Semitransparent, nicht nur in Chrome und in Firefox, auch in einem unteruhluster Alpha die Farbeigenschaft auf einen Wert mit einem unterubstierenden Alpha zu setzen ! Dies ist etwas, das ich noch nie gewusst habe, und ich finde absolut umwerfend, da die anderen Kan?le Emojis in keiner Weise beeinflussen.
Zweitens verwischen sowohl Chrome als auch Firefox den gesamten Bereich des orangefarbenen Textes und Emoji, der unter dem Begrenzungsfeld der oberen halbransparenten grauen Schicht gefunden wird, anstatt nur das zu verwischen, was sich unter dem tats?chlichen Text befindet. In Firefox sehen die Dinge aufgrund dieses unangenehmen scharfen Kanteneffekts noch schlechter aus.
Obwohl die Box -Unsch?rfe nicht das ist, was wir wollen, kann ich nicht anders, als zu glauben, dass sie sinnvoll ist, da die Spezifikation Folgendes sagt:
[…] Um ein ?transparentes“ Element zu erstellen, das das vollst?ndige filtrierte Hintergrundbild erm?glicht, k?nnen Sie ?Hintergrundfarbe: transparent“ verwenden.
Lassen Sie uns also einen Test durchführen, um zu überprüfen, was passiert, wenn die oberste Ebene eine weitere nicht rektangul?re Form ist, die kein Text ist, sondern mit einem Hintergrundgradienten, einem Clip-Pfad oder einer Maske erhalten wird!
Sowohl in Chrom als auch in Firefox wird der Bereich unter der gesamten Schachtel der obersten Schicht verschwommen, wenn die Form mit Hintergrund erhalten wird: Gradient (), was, wie im Textfall erw?hnt, nach der Spezifikation sinnvoll ist. Chrome respektiert jedoch die Clip-Pfad- und Maskenformen, w?hrend Firefox nicht. Und in diesem Fall wei? ich wirklich nicht, was korrekt ist, obwohl das Chromergebnis für mich sinnvoller ist.
Sich in Richtung einer Chroml?sung bewegen
Dieses Ergebnis und ein Twitter -Vorschlag, den ich bekam, als ich fragte, wie die Unsch?rfe die Textkanten respektieren kann, und nicht die des Begrenzungsfelds führte mich zum n?chsten Schritt für Chrome: Auftragen einer Maske auf der oberen Ebene (.grey). Diese L?sung funktioniert aus zwei Gründen nicht in Firefox: Erste, Text ist leider ein nicht standardm??iger Masken-Clip-Wert, der nur in Webkit-Browsern funktioniert, und um zwei, wie der obige Test gezeigt, beschr?nkt das Maskieren den Unsch?rfenbereich nicht auf die Form der Maske in Firefox.
/ * wie früher */ .grau { / * wie früher */ -Webkit-Maske: Linear-Gradient (rot, rot) Text; / * funktioniert nur in Webkit -Browsern */ }
Okay, das sieht tats?chlich so aus, was wir wollen, also k?nnen wir sagen, dass wir in die richtige Richtung gehen! Hier haben wir jedoch ein orangefarbenes Herz -Emoji für die untere Schicht und ein schwarzes Herz -Emoji für die obere halbtransparente Schicht verwendet. Andere generische Emojis haben keine Schwarz -Wei? -Versionen, daher war meine n?chste Idee, die beiden Schichten zun?chst identisch zu machen, dann den oberen Semitransparenten zu machen und Filter zu verwenden: Graustufe (1) darauf.
Artikel { Farbe: HSLA (25, 100%, 55%, var (-a, 1)); Schriftart: 900 21VW/ 1,25 Kursiv; } .grau { -A: .25; Rand: -1em 0 0 .5EM; Filter: Graustufen (1); Backdrop-Filter: Blur (5px); -Webkit-Maske: Linear-Gradient (rot, rot) Text; }
Nun, das hatte sicherlich den Effekt, den wir auf der obersten Schicht wollten. Leider scheint es aus irgendeinem seltsamen Grund auch den verschwommenen Bereich der darunter liegenden Schicht beeinflusst zu haben. In diesem Moment ist es in Betracht gezogen, den Laptop kurz aus dem Fenster zu werfen ... bevor Sie die Idee bekommen, eine weitere Ebene hinzuzufügen.
Es würde so laufen: Wir haben die Basisschicht, genau wie wir es bisher bisher leicht von den beiden anderen über ihr verankert haben. Die mittlere Schicht ist ein ?Geist“ (transparent), der den Hintergrund-Filter angewendet hat. Und schlie?lich ist der obere Semitransparent und erh?lt den Graustufen -Filter (1).
K?rper {Anzeige: Grid; } Artikel { Gitterfl?che: 1/1; Ort selbst: Zentrum; Polsterung: .25em; Farbe: HSLA (25, 100%, 55%, var (-a, 1)); Schriftart: 900 21VW/ 1.25 Pacifico, Z003, Segoe Script, Comic Sans MS, Cursive; } .base {margin: -.5em 0 0 -.5em; } .midl { -A: 0; Backdrop-Filter: Blur (5px); -Webkit-Maske: Linear-Gradient (rot, rot) Text; } .Grey {Filter: Graustufen (1) Opazit?t (.25)}
Jetzt kommen wir irgendwo! Es gibt nur noch eine Sache zu tun: Machen Sie die Basisschicht monochrom!
/ * wie früher */ .base { Rand: -.5EM 0 0 -.5EM; Filter: Sepia (1) Hue-Rotat (165 °) Kontrast (1,5); }
Okay, das ist der Effekt, den wir wollen!
Zu einer Firefox -L?sung kommen
W?hrend ich die Chroml?sung codierte, konnte ich nicht anders, als zu glauben, dass wir in der Lage sein k?nnten, das gleiche Ergebnis von Firefox zu erzielen, da Firefox der einzige Browser ist, der die Funktion Element () unterstützt. Diese Funktion erm?glicht es uns, ein Element zu nehmen und es als Hintergrund für ein anderes Element zu verwenden.
Die Idee ist, dass die Schichten .Base und .Grey die gleichen Stile wie in der Chrome -Version haben, w?hrend die mittlere Schicht einen Hintergrund hat, der (über die Element () -Funktion) eine verschwommene Version unserer Ebenen ist.
Um die Dinge zu erleichtern, beginnen wir nur mit dieser verschwommenen Version und der mittleren Schicht.
<article id="'Blur'" aria-hidden="'true'"> lion? </article> <article class="'midl'"> lion? </article>
Wir positionieren die verschwommene Version absolut (halten sie vorerst in Sicht), machen sie monochrom und verwischen sie und verwenden sie dann als Hintergrund für .midl.
#blur { Position: absolut; Top: 2EM; Rechts: 0; Rand: -.5EM 0 0 -.5EM; Filter: Sepia (1) Hue-Rotat (165 ° C) Kontrast (1,5) Blur (5px); } .midl { -A: .5; Hintergrund: -moz -Element (#blur); }
Wir haben auch den Text im Semitransparent des .midl -Elements erstellt, damit wir den Hintergrund durch ihn sehen k?nnen. Wir werden es irgendwann voll transparent machen, aber im Moment m?chten wir immer noch seine Position im Verh?ltnis zum Hintergrund sehen.
Wir k?nnen sofort ein Problem bemerken: W?hrend der Margin das eigentliche #Blur -Element ausgleichen, tut es nichts, um seine Position als Hintergrund zu verschieben. Um einen solchen Effekt zu erzielen, müssen wir die Transformationseigenschaft verwenden. Dies kann uns auch helfen, wenn wir eine Rotation oder eine andere Transformation wünschen-wie sie unten zu sehen ist, wo wir den Rand durch Transformation ersetzt haben: Drehen (-9de).
Okay, aber wir bleiben vorerst nur an eine übersetzung:
#blur { / * wie früher */ Transformation: Translate ( -. 25em, -.25em); / * ersetzt Rand *//// }
Eine Sache, die hier zu beachten ist, ist, dass ein Stück des verschwommenen Hintergrunds abgeschnitten wird, wenn es au?erhalb der Grenzen der Polsterkasten der mittleren Schicht geht. Das spielt bei diesem Schritt sowieso keine Rolle, da unser n?chster Zug den Hintergrund in den Textbereich übertreffen, aber es ist gut, nur diesen Platz zu haben, da die Base -Schicht genau so weit übersetzt wird.
Also werden wir die Polsterung um ein wenig erh?hen, auch wenn es zu diesem Zeitpunkt visuell keinen Unterschied macht, da wir auch Hintergrund-Clip: Text in unserem .midl-Element festlegen.
Artikel { / * wie früher */ Polsterung: .5em; } #blur { Position: absolut; unten: 100VH; Transformation: Translate ( -. 25em, -.25em); Filter: Sepia (1) Hue-Rotat (165 ° C) Kontrast (1,5) Blur (5px); } .midl { -A: .1; Hintergrund: -moz -Element (#blur); Hintergrund-Clip: Text; }
Wir haben auch das #Blur -Element au?er Sichtweite bewegt und das Alpha der Farbe des .midl -Elements weiter reduziert, da wir durch den Text eine bessere Sicht auf den Hintergrund haben m?chten. Wir machen es nicht vollst?ndig transparent, halten es aber vorerst trotzdem sichtbar, damit wir wissen, welchen Bereich er abdeckt.
Der n?chste Schritt besteht darin, das .base -Element mit so ziemlich den gleichen Stilen wie im Chromgeh?use hinzuzufügen und den Rand nur durch eine Transformation zu ersetzen.
<article id="'Blur'" aria-hidden="'true'"> lion? </article> <article class="'base'" aria-hidden="'true'"> lion? </article> <article class="'midl'"> lion? </article>
#blur { Position: absolut; unten: 100VH; Transformation: Translate ( -. 25em, -.25em); Filter: Sepia (1) Hue-Rotat (165 ° C) Kontrast (1,5) Blur (5px); } .base { Transformation: Translate ( -. 25em, -.25em); Filter: Sepia (1) Hue-Rotat (165 °) Kontrast (1,5); }
Da ein Teil dieser Stile üblich ist, k?nnen wir auch die .base -Klasse zu unserem verschwommenen Element #Blur hinzufügen, um die Duplikation zu vermeiden und die Menge an Code zu verringern, die wir schreiben.
<article id="'Blur'" class="'base'" aria-hidden="'true'"> lion? </article> <article class="'base'" aria-hidden="'true'"> lion? </article> <article class="'midl'"> lion? </article>
#blur { --R: 5px; Position: absolut; unten: 100VH; } .base { Transformation: Translate ( -. 25em, -.25em); Filter: Sepia (1) Hue-Rotat (165de) Kontrast (1,5) Blur (var (-r, 0)); }
Wir haben hier ein anderes Problem. Da die .Base -Schicht eine Transformation aufweist, liegt sie jetzt trotz der DOM -Reihenfolge auf der .midl -Schicht. Die einfachste L?sung? Fügen Sie Z-Index: 2 auf das .midl-Element hinzu!
Wir haben immer noch ein weiteres, etwas subtileres Problem: Das Base -Element ist immer noch unter den semitransparenten Teilen des verschwommenen Hintergrunds sichtbar, den wir auf dem .midl -Element festgelegt haben. Wir m?chten nicht, dass die scharfen Kanten des. Base -Layer -Textes darunter sind, aber wir sind, weil verschwommene Pixel nahe am Rand semitransparent werden.
Abh?ngig von der Art von Hintergrund, die wir über die Eltern unserer Textschichten haben, ist dies ein Problem, das mit ein wenig oder viel Anstrengung gel?st werden kann.
Wenn wir nur einen soliden Hintergrund haben, wird das Problem gel?st, indem die Hintergrundfarbe in unserem .midl-Element auf denselben Wert festgelegt wird. Glücklicherweise ist dies unser Fall, sodass wir nicht über das andere Szenario diskutieren werden. Vielleicht in einem anderen Artikel.
.midl { / * wie früher */ Hintergrund: -moz -Element (#blur) #fff; Hintergrund-Clip: Text; }
Wir n?hern uns einem sch?nen Ergebnis von Firefox! Alles, was zu tun bleibt, ist die obere .Grey -Ebene mit genau den gleichen Stilen wie in der Chrome -Version hinzuzufügen!
.Grey {Filter: Graustufen (1) Opazit?t (.25); }
Leider erzeugt dies nicht das gewünschte Ergebnis, was wirklich offensichtlich ist, wenn wir auch den Text mit mittlerer Ebene vollst?ndig transparent machen (indem wir sein Alpha -A: 0), so dass wir nur den Hintergrund sehen (der das verschwommene Element #blur über festes Wei? verwendet), das in den Textbereich abgeschnitten ist:
Das Problem ist, dass wir die .Grey -Schicht nicht sehen k?nnen! Aufgrund der Einstellung von Z-Index: 2 darauf befindet sich die mittlere Schicht .Midl jetzt über der oberen Schicht (die .grey One) trotz der DOM-Reihenfolge. Das Fix? Setzen Sie Z-Index: 3 auf der .grey-Schicht!
.grau { Z-Index: 3; Filter: Graustufen (1) Deckkraft (.25); }
Ich gebe nicht wirklich gern Z-Index-Schicht für Layer, aber hey, es ist niedrig und es funktioniert! Wir haben jetzt eine sch?ne Firefox -L?sung:
Kombinieren Sie unsere L?sungen zu einem Cross-Browser
Wir beginnen mit dem Firefox -Code, weil es nur noch mehr davon gibt:
<article id="'Blur'" class="'base'" aria-hidden="'true'"> lion? </article> <article class="'base'" aria-hidden="'true'"> lion? </article> <article class="'midl'" aria-hidden="'true'"> lion? </article> <artikel class="'Gray'"> Lion? </artikel>
K?rper {Anzeige: Grid; } Artikel { Gitterfl?che: 1/1; Ort selbst: Zentrum; Polsterung: .5em; Farbe: HSLA (25, 100%, 55%, var (-a, 1)); Schriftart: 900 21VW/ 1,25 Kursiv; } #blur { --R: 5px; Position: absolut; unten: 100VH; } .base { Transformation: Translate ( -. 25em, -.25em); Filter: Sepia (1) Hue-Rotat (165de) Kontrast (1,5) Blur (var (-r, 0)); } .midl { -A: 0; Z-Index: 2; Hintergrund: -moz -Element (#blur) #fff; Hintergrund-Clip: Text; } .grau { Z-Index: 3; Filter: Graustufen (1) Deckkraft (.25); }
Die zus?tzlichen Z-Index-Deklarationen beeinflussen das Ergebnis nicht in Chrom, und das au?er Sicht #Blur-Element auch nicht. Die einzigen Dinge, die dies fehlt, damit dies in Chrome funktioniert, sind die Hintergrundfilter- und Maskenerkl?rungen auf dem .midl-Element:
Backdrop-Filter: Blur (5px); -Webkit-Maske: Linear-Gradient (rot, rot) Text;
Da wir nicht m?chten, dass der Hintergrund-Filter in Firefox angewendet wird und wir auch nicht m?chten, dass der Hintergrund in Chrome angewendet wird, verwenden wir @Supports:
$ r: 5px; / * wie früher */ #blur { / * wie früher */ --R: #{$ r}; } .midl { -A: 0; Z-Index: 2; / * muss in @Supports zurückgesetzt werden, damit es nicht in Firefox angewendet wird */ Backdrop-Filter: Blur ($ R); / * Ungültiger Wert in Firefox, sowieso nicht angewendet, kein Zurücksetzen */ -Webkit-Maske: Linear-Gradient (rot, rot) Text; @Supports (Hintergrund: -moz -Element (#blur)) { / * für Firefox * / Hintergrund: -moz -Element (#blur) #fff; Hintergrund-Clip: Text; Backdrop-Filter: Keine; } }
Dies gibt uns eine Cross-Browser-L?sung!
W?hrend das Ergebnis in den beiden Browsern nicht dasselbe ist, ist es immer noch ziemlich ?hnlich und gut genug für mich.
Was ist mit einer Einselementierung unserer L?sung?
Leider ist das unm?glich.
Zun?chst einmal erfordert die Firefox -L?sung, dass wir mindestens zwei Elemente haben, da wir eine (auf die durch ihre ID verwiesen) als Hintergrund für einen anderen verwendet werden.
Zweitens ist der erste Gedanke mit den verbleibenden drei Schichten (die die einzigen für die Chroml?sung sowieso ben?tigen), dass einer von ihnen das tats?chliche Element und die beiden anderen Pseudos sein k?nnte, aber in diesem speziellen Fall nicht so einfach.
Für die Chroml?sung hat jede der Schichten mindestens eine Eigenschaft, die auch irreversibel auf Kinder und Pseudos auswirkt, die sie m?glicherweise haben kann. Für die .Base- und .grey -Schichten ist das die Filtereigenschaft. Für die mittlere Schicht ist das die Maskeneigenschaft.
Obwohl es nicht hübsch ist, all diese Elemente zu haben, sieht es so aus, als h?tten wir keine bessere L?sung, wenn wir m?chten, dass der Glassmorphismus -Effekt auch an Emojis arbeitet.
Wenn wir nur den Glassmorphismus -Effekt auf einfachen Text - keine Emojis auf dem Bild - wollen, kann dies mit nur zwei Elementen erreicht werden, aus denen nur einer für die Chroml?sung ben?tigt wird. Das andere ist das #Blur -Element, das wir nur in Firefox ben?tigen.
<article id="'Blur'"> Blood </article> <article class="'text'" aria-hidden="'true'" data-text="'blood'"> </article>
Wir verwenden die beiden Pseudos des .textelements, um die Basisschicht (mit dem :: vor) und eine Kombination der beiden anderen Schichten (mit dem :: nach) zu erstellen. Was uns hier hilft, ist, dass wir mit Emojis aus dem Bild keinen Filter ben?tigen: Graustufen (1), sondern die S?ttigungskomponente des Farbwerts steuern k?nnen.
Diese beiden Pseudos sind übereinander gestapelt, wobei der untere (:: vor) durch die gleiche Menge und die gleiche Farbe wie das #Blur -Element aufweist. Dieser Farbwert h?ngt von einer Flagge ab -F -F, die uns hilft, sowohl die S?ttigung als auch die Alpha zu steuern. Für das #Blur-Element und das :: vor Pseudo (--f: 1) betr?gt die S?ttigung 100% und das Alpha 1. Für das :: nach Pseudo (--f: 0) betr?gt die S?ttigung 0% und das Alpha 0,25.
$ r: 5px; %Text {// verwendet von #Blur und beiden .Text Pseudos --f: 1; Gitterfl?che: 1/1; // Pseudos stapeln, ignoriert für absolut positionierte #Base Polsterung: .5em; Farbe: HSLA (345, Calc (var (-f)*100%), 55%, Calc (.25,75*var (-f)); Inhalt: Attr (Datentext); } Artikel {Schriftart: 900 21VW/ 1.25 Cursive} #blur { Position: absolut; unten: 100VH; Filter: Blur ($ R); } #blur, .Text :: vor { Transformation: Translate ( -. 125em, -.125em); @extend %text; } .Text { Anzeige: Grid; &::nach { --f: 0; @extend %text; Z-Index: 2; Backdrop-Filter: Blur ($ R); -Webkit-Maske: Linear-Gradient (rot, rot) Text; @Supports (Hintergrund: -moz -Element (#blur)) { Hintergrund: -moz -Element (#blur) #fff; Hintergrund-Clip: Text; Backdrop-Filter: Keine; } } }
Anwenden der Kreuzbrowser-L?sung auf unseren Anwendungsfall
Die gute Nachricht hier ist unser spezieller Anwendungsfall, in dem wir nur den GlaSmorphismus -Effekt auf das Link -Symbol (nicht auf dem gesamten Link einschlie?lich des Textes) haben, vereinfacht die Dinge tats?chlich ein kleines bisschen.
Wir verwenden den folgenden Mops, um die Struktur zu erzeugen:
- sei data = { - Home: {ICO: '?', Hue: 200}, - Hinweise: {ICO: '? umpf', Hue: 260}, - Aktivit?t: {ICO: '?', Hue: 320}, - Entdeckung: {ICO: '?', Hue: 30} -}; - sei E = Object.Entries (Daten); - Sei n = E.Length; Navigation - für (lass i = 0; i <n i ico="E" .ico a.item style="`--hue:" .hue deg span.icon.tint aria-hidden="'true')" span.icon.midl span.icon.grey><p> Dies erzeugt eine HTML -Struktur wie die folgende:</p> <pre rel="HTML" data-line=""> <nav> <a class="'item'" item> <span class="'icon" tint id="'Blur0'" aria-hidden="'true'">? </span> <span class="'icon" tint aria-hidden="'true'">? </span> <span class="'icon" midl aria-hidden="'true'" style="'Hintergrund-Image:">? </span> <span class="'icon" grau aria-hidden="'true'">? </span> heim </a> </nav>
Wir k?nnten wahrscheinlich einen Teil dieser Spannweiten durch Pseudos ersetzen, aber ich denke, es ist konsequenter und einfacher wie dieses, also ist es ein Spannwichsandwich!
Eine sehr wichtige Sache ist zu bemerken, dass wir für jedes der Elemente eine andere verschwommene Symbolschicht haben (da jedes Element ein eigenes Symbol hat). Daher setzen wir den Hintergrund des .midl -Elements in dem Style -Attribut. Wenn wir auf diese Weise Dinge tun, k?nnen wir nicht ?nderungen an der CSS -Datei vornehmen, wenn wir Eintr?ge aus dem Datenobjekt hinzufügen oder entfernen (somit die Anzahl der Menüelemente ?ndern).
Wir haben fast das gleiche Layout und die gleichen Layout- und Feinstile, die wir hatten, als wir zum ersten Mal CSS in der Navigationsleiste haben. Der einzige Unterschied besteht darin, dass wir jetzt keine Pseudos in der oberen Zelle eines Elementrasters haben. Wir haben die Spannweiten:
Span { Gitterfl?che: 1/1; / * stapeln Sie alle Emojis übereinander */// Schriftgr??e: 4EM; / * Bump Up Emoji Gr??e */ }
Für die Emoji-Ikonenschichten selbst müssen wir auch nicht viele ?nderungen gegenüber der Cross-Browser-Version vornehmen, die wir etwas früher erhalten haben, obwohl es einige LTTLE-Versionen gibt.
Zun?chst verwenden wir die Transformations- und Filterketten, die wir ursprünglich ausgew?hlt haben, als wir die Link Pseudos anstelle von Spannweiten verwendeten. Wir brauchen auch die Farbe auch nicht: HSLA () Erkl?rung zu den Spannweitenschichten, da wir hier nur Emojis haben, ist es nur der Alpha -Kanal, der z?hlt. Die Standardeinstellung, die für die .Base- und die .Grey -Schichten erhalten bleiben, betr?gt 1., anstatt einen Farbwert festzulegen, bei dem nur das Alpha, -ein Kanal von Bedeutung, und wir ?ndern diese auf 0 auf der .midl -Ebene, wir setzen direkt Farbe: transparent dort. Wir müssen auch nur die Hintergrundfarbe auf das .midl-Element im Firefox-Fall einstellen, da wir das Hintergrundbild bereits im Style-Attribut festgelegt haben. Dies führt zur folgenden Anpassung der L?sung:
.base { / * mono emoji Version * / Transformation: Translate (.375EM, -.25EM) Drehung (22,5 Grad); Filter: Sepia (1) Hue-Rotat (var (-hue)) s?ttig (3) Blur (var (-r, 0)); } .Midl { / * Mitte, transparente Emoji -Version * / Farbe: transparent; / * Also ist es nicht sichtbar */ Backdrop-Filter: Blur (5px); -Webkit-Maske: Linear-Gradient (rot 0 0) Text; @Supports (Hintergrund: -moz -Element (#B)) { Hintergrundfarbe: #fff; Hintergrund-Clip: Text; Backdrop-Filter: Keine; } }
Und das war's - wir haben einen sch?nen Icon -Glasmorphismus -Effekt für diese Navigationsriegel!
Es gibt nur noch eine Sache, um die man sich kümmern muss - wir wollen diesen Effekt nicht immer; Nur zu: schweben oder: Fokuszust?nde. Wir werden also eine Flagge, - -HL, die 0 im normalen Zustand ist, und 1 im: schwebenden oder: Fokuszustand, um die Opazit?t und Transformationswerte der .base -Spans zu kontrollieren. Dies ist eine Technik, die ich in einem früheren Artikel beschrieben habe.
$ t: .3s; A { / * wie früher */ --hl: 0; Farbe: HSL (var (-hue), calc (var (-hl)*100%), 65%); übergang: Farbe $ T; &: Hover, &: Fokus { - -hl: 1; } } .base { verwandeln: Translate (calc (var (-hl)*. 375em), calc (var (-hl)*-. 25em)) rotieren (calc (var (-hl)*22,5 Grad)); Opazit?t: var (-hl); übergang: $ T, Opazit?t $ T; }
Das Ergebnis ist in der folgenden interaktiven Demo zu sehen, wenn die Symbole schwebten oder fokussiert sind.
Was ist mit SVG -Symbolen?
Ich habe mir diese Frage natürlich gestellt, nachdem ich die CSS Emoji -Version zum Laufen gebracht hatte. W?re der einfache SVG -Weg nicht sinnvoller als ein Spannweinweinwich, und w?re es nicht einfacher? Nun, obwohl es sinnvoller ist, zumal wir für alles keine Emojis haben, ist es leider nicht weniger Code und es ist auch nicht einfacher.
Aber wir werden in einem anderen Artikel auf Details eingehen!
Das obige ist der detaillierte Inhalt vonIconglasmorphismus -Effekt in CSS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Hei?e KI -Werkzeuge

Undress AI Tool
Ausziehbilder kostenlos

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem v?llig kostenlosen KI-Gesichtstausch-Tool aus!

Hei?er Artikel

Hei?e Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Hei?e Themen

CSS -Bl?cke Seitenrenderung, da Browser inline und externe CSS standardm??ig als wichtige Ressourcen anzeigen, insbesondere mit importierten Stylesheets, Header gro?er Mengen an Inline -CSS und nicht optimierten Medienfragestilen. 1. extrahieren kritische CSS und einbetten Sie es in HTML ein; 2. Verz?gerung des Ladens nichtkritischer CSS durch JavaScript; 3.. Verwenden Sie Medienattribute, um das Laden wie Druckstile zu optimieren. 4. Komprimieren und verschmelzen CSS, um Anfragen zu reduzieren. Es wird empfohlen, Tools zum Extrahieren von Schlüssel -CSS zu verwenden, REL = "Vorspannung" zu kombinieren, und verwenden Sie die asynchrone Belastung und verwenden Sie die Medienverz?gerungsladeverletzung, um eine überm??ige Aufteilung und eine komplexe Skriptsteuerung zu vermeiden.

ThebestApproachforcssDependsonTheProject'Sspecificneeds.forlargerProjects, externalcssisbetterDuetomaintainability;

Csssmostlycase-unempfindlich, buturlsandfontfamilynamesarecase-sensitiv.1) Eigenschaften und ValueslikeColor: rot; sensitiv.2) URLSMUTMATTHESERVER'SCASE, z.

AutoPrefixer ist ein Tool, das die Pr?fixe von Anbietern automatisch zu CSS -Attributen basierend auf dem Zielbrowserbereich hinzufügt. 1. Es l?st das Problem, die Pr?fixe mit Fehlern manuell aufrechtzuerhalten. 2. Arbeiten Sie das POSTCSS-Plug-in-Formular durch, analysieren Sie CSS, analysieren Sie Attribute, die vorangestellt werden müssen, und generieren Sie den Code gem?? Konfiguration. 3.. 4. Notizen enthalten nicht manuelles Hinzufügen von Pr?fixen, Konfigurationsaktualisierungen, Pr?fixe nicht alle Attribute, und es wird empfohlen, sie mit dem Pr?prozessor zu verwenden.

CSSCOUNTERSCANATOMATIONSNUMBERSEctions und.1) usecounter-resettoinitialize, counter-IncrementtoIncrease, und Counter () orcounters () todisplayValues.2) kombinierte withjavascriptfordynamiccontentToEsSureAccurateupdates.

In CSS sind Selektor- und Attributnamen fallempfindlich, w?hrend Werte, Namen, URLs und benutzerdefinierte Attribute fallempfindlich sind. 1. Die Auswahl- und Attributnamen sind unempfindlich, z. B. Hintergrundfarbe und Hintergrundfarbe sind gleich. 2. Die hexadezimale Farbe im Wert ist fallempfindlich, aber die benannte Farbe ist fallempfindlich, wie rot und rot ist ungültig. 3. Die URLs sind fallsempfindlich und k?nnen zu Ladeproblemen von Dateien führen. 4. Benutzerdefinierte Eigenschaften (Variablen) sind fallempfindlich und Sie müssen auf die Konsistenz des Falles bei der Verwendung achten.

Theconic-Gradient () FunctionincsScreateScircular GradecentStroTRotateColorStopsaroundAcentralPoint.1.ISISIDEALFORPieCharts, Fortschrittsindikatoren, Farbw?sche und DecorativeBackgrounds.2
