- Ausgehend von der frosted acrylic UI in Forza Horizon 3 und Forza Motorsport 7 wird beschrieben, wie sich ein ähnlicher Glaspanel-Effekt im Web mit HTML/CSS/JavaScript nachbilden lässt
- Im Mittelpunkt des Effekts steht Gaussian blur; um Browserunterschiede zu verringern, sollten CSS
backdrop-filterund für iOS-webkit-backdrop-filtergemeinsam verwendet werden - Da reine Unschärfe flach wirken kann, werden mit
box-shadow: insetKantentiefe und subsurface scattering ergänzt; ein normaler Schatten erzeugt den Eindruck, über dem Hintergrund zu schweben - Oberflächenreflexionen werden über ein Lichtstrahlen-Bild als separate Ebene umgesetzt; mit
background-attachment: fixedoder JavaScript wird eine dynamische Reflexion simuliert, die zur Bewegung des Glases passt - Die finale UI kombiniert die Ebenen
.glass,.lightund.drag-meund wird mit abgerundeten Ecken, Clipping und halbtransparenter Hintergrundfarbe zu einer kopierbaren Glaskomponente fertiggestellt
Glaspanel-Effekt aus Game-UIs
- Ziel ist es, das frosted acrylic design aus der UI-Entwicklungserfahrung mit Forza Horizon 3 und Forza Motorsport 7 in HTML nachzubilden
- Das Ergebnis ist ein ziehbares Glaspanel mit Hintergrundunschärfe, Kantentiefe, Lichtreflexionen, abgerundeten Ecken und einer halbtransparenten Farbebene
- Zu Beginn wird ein finales Rezept bereitgestellt, das sich direkt kopieren lässt; anschließend werden die einzelnen Effekte Schritt für Schritt aufgebaut
Hintergrundunschärfe mit backdrop-filter
- Der Kern eines guten Frosted-Glass-Effekts ist Gaussian blur, der den Hintergrund unscharf macht und ihn wie einen halbtransparenten Screen erscheinen lässt
- In CSS wird das durch Anwendung von
bluraufbackdrop-filterumgesetzt - Das grundlegende Glaselement beginnt mit einem einfachen
divund der Klasse.glassbackdrop-filter: blur(10px)-webkit-backdrop-filter: blur(10px)
- Unter iOS ist
-webkit-backdrop-filternötig, sofern man nicht tiefergehende separate Einstellungen ändert - Da
backdrop-filtererst seit Kurzem von Browsern unterstützt wird, können Nutzer von Internet Explorer die Demo nicht erleben
Tiefe durch Kanten und Schatten erzeugen
- Wenn nur
backdrop-filter: blur(10px)angewendet wird, kann das Glas flach und eintönig wirken - Die Kanten werden nicht mit
border: 1px solid, sondern mitbox-shadow: insetumgesetztborderbeeinflusst die Elementgröße und die Positionierung von Kindelementen- Mit
box-shadow: insetkönnen Kindelemente den Inhaltsbereich des Glases natürlich ausfüllen, ohne Anpassungen wie negative Margins
- Zwei halbtransparente weiße inset shadows stellen die Glaskanten dar
- Der erste Schatten steht für die von außen sichtbare Glaskante; im Beispiel erscheint er an der unteren und linken Kante
- Der zweite Schatten steht für die durch das Glas sichtbare Kante; im Beispiel erscheint er an der oberen und rechten Kante
- Die durch das Glas sichtbare Kante wird weicher und transparenter eingestellt, da das Licht dabei abnimmt
- Ein normaler dunkler
box-shadowkann dem Glas den Eindruck geben, physisch über dem Hintergrund zu schweben
Lichtstreuung und Oberflächenreflexion
- Das Gefühl, dass sich Licht im Inneren des Glases ausbreitet, wird durch eine vereinfachte Darstellung von
subsurface scatteringerzeugt - Für die Umsetzung wird erneut
box-shadow: insetverwendet- Kurzer Streueffekt:
inset 0px 0px 10px 5px rgba(255, 255, 255, 0.025) - Tieferer Streueffekt:
inset 0px 0px 40px 5px rgba(255, 255, 255, 0.025)
- Kurzer Streueffekt:
- Dieser Effekt ist besser sichtbar, wenn das Glas über einen dunklen Hintergrund gezogen wird
- Zusätzlich zum Eindruck eines unscharfen, gebrochenen Hintergrunds wird auch die Eigenschaft ergänzt, dass Licht von der Glasoberfläche reflektiert wird
- Die Lichtreflexion wird umgesetzt, indem ein Lichtstrahlen-Bild als Hintergrund eingemischt wird
- Zum Erstellen eines ähnlichen Bildes gibt es ein YouTube-Tutorial und eine Textanleitung
- Wenn das Bild direkt als
background-imagein das.glass-Element eingefügt wird, machtbackdrop-filterdas Bild unscharf; daher wird eine separate Ebene wie::beforeverwendet
Statische Reflexion dynamisch machen
- Wenn nur ein Lichtstrahlen-Bild darübergelegt wird, entsteht zwar eine Reflexion, aber beim Bewegen des Glases kann es so wirken, als wäre das Licht auf der Glasoberfläche fixiert
- Der reine CSS-Ansatz ergänzt
background-attachment: fixedauf::before- Die Umsetzung ist einfach, funktioniert aber möglicherweise nicht auf allen Plattformen
- Damit es auf allen Plattformen funktioniert, wird
background-attachment: fixedmit JavaScript imitiert- Da es ineffizient ist,
::beforedirekt aus JavaScript zu steuern, wird ein separatesdiv.light-Element verwendet - Das Zielelement erhält das Attribut
data-js-background-attachment-fixed
- Da es ineffizient ist,
- JavaScript liest in jedem Animationsframe den Wert von
getBoundingClientRect()des Zielelements und aktualisiertbackground-positionin die Gegenrichtung der Position im ViewportbackgroundPositionX = -clientRect.xbackgroundPositionY = -clientRect.y
- Die Wiederholungsschleife läuft über
requestAnimationFrame
Finale HTML/CSS-Struktur
- Das finale HTML der JavaScript-Version hat eine Struktur, bei der
.glassdie.light-Ebene für Lichtreflexionen sowie.drag-meals Text-/Farbebene enthält
Drag Me
.glassübernimmt die Grundform und die visuellen Effekte des Glaspanels- Anwendung der Hintergrundunschärfe mit
backdrop-filterund-webkit-backdrop-filter - Anwendung von Kanten, Schatten und Streueffekten mit mehreren
box-shadow-Werten position: relative, damit Kindelemente den Elternbereich ausfüllen können- Abgerundete Ecken mit
border-radius: 5px overflow: hidden, um Kindelemente abzuschneiden, damit sie nicht über die abgerundeten Ecken hinausragen
- Anwendung der Hintergrundunschärfe mit
.lightverwendet das Lichtstrahlen-Bild als wiederholten Hintergrundbackground-image: url(path/to/light.png)background-repeat: repeatbackground-size: 750pxopacity: 0.075- Füllt mit
position: absoluteund Offsets von0in alle vier Richtungen den gesamten Elternbereich aus - Rendert mit
z-index: -1hinter den anderen Kindelementen
.drag-mezentriert den Inhalt und erzeugt eine farbige, halbtransparente Glasebenedisplay: flexalign-items: centerjustify-content: centerheight: 30pxbackground-color: rgba(12, 13, 14, 0.75)
Unterschied der Version ohne JavaScript
- Die Version ohne JavaScript verwendet statt eines separaten
.light-Elements.glass::before - Auf
::beforewird das Lichtstrahlen-Bild angewendet, und mitbackground-attachment: fixedwird eine auf dem Bildschirm fixierte Reflexion umgesetzt - Dieser Ansatz funktioniert nicht auf allen Plattformen; die JavaScript-Version gleicht das aus, indem sie
background-positiondirekt aktualisiert
1 Kommentare
Hacker-News-Kommentare
Ästhetisch gefällt es mir wirklich gut, aber an den Rändern gibt es Stellen, die physikalisch nicht ganz passen.
Aus Sicht eines Embedded-Entwicklers wirkt es etwas verschwenderisch. Es fühlt sich so an, als würde jeder Client jedes Mal einen „teuren“ Blur-Filter berechnen, nur um ihn mit einer unscharfen Version des Hintergrundbilds zu mischen.
Da es die GPU nutzt und optimiert ist, ist es am Ende vielleicht kein großer Kostenfaktor, aber Webentwicklung wirkt heute insgesamt wie ein Trend zu immer mehr Aufblähung. Selbst einfache Sites laden fünf Sekunden lang und wälzen schwere Verarbeitung auf den Client ab – was natürlich nicht die Schuld des Autors dieses Beitrags ist.
Ich bin in der Zeit der 14,4k-Modems aufgewachsen und daran gewöhnt, Netzwerkbandbreite als viel knapper und teurer zu betrachten als CPU-Zeit.
Wenn sich etwas leicht auf dem Client berechnen lässt, halte ich es für verschwenderischer, das komplette Bild über das Internet herunterzuladen. Dafür müssen Router, Server und entfernte Festplatten arbeiten; all das aufzuwenden, nur um eine Verarbeitung auf Daten zu vermeiden, die bereits im RAM des Clients liegen, erscheint mir noch unnötiger.
Also ist entweder Unterhaltung selbst Verschwendung, oder es ist in Ordnung, mehr Rechenleistung einzusetzen, um Unterhaltung besser zu machen.
Wenn sich in einer UI etwas ändert, braucht man ohnehin GPU-Berechnungen zum Neuzeichnen, und ein einfacher Blur lässt sich ziemlich effizient hinzufügen. Wahrscheinlich ist das günstiger als Animationen von DOM-Objekten, die nicht als GPU-Layer optimiert sind.
Wenn heute selbst die simpelsten Sites über 1 MB JavaScript und massenhaft Tracker laden und damit CPU verbrauchen, steht ein Blur für ästhetische Effekte auf der Verschwendungsliste ziemlich weit unten.
Bei vielen hochauflösenden Bildern ist die reale Netzwerkbandbreite begrenzt, und besonders in mobilen Umgebungen mit schlechter Funkabdeckung ist das eindeutig langsamer als lokale Berechnung. Es ist erstaunlich, was heute allein mit CSS/WebGL möglich ist; früher brauchte man für solche Effekte viele Hacks und Workarounds.
Unabhängig davon, ob die Handlung selbst Verschwendung ist, zeigt schon diese Denkweise ein größeres gesellschaftliches Problem. Warum brauchen wir das, und warum gilt der Zustand ohne das als schlecht?
Angesichts des Ausmaßes heutiger gesellschaftlicher Probleme frage ich mich, wen es interessiert, ob ein UI-Panel verschwommen ist oder nicht.
Als ich auf Android ausprobieren wollte, was man mit der neuen Shader-API machen kann, habe ich den Windows 7 Aero Glass-Effekt nachgebaut und dabei eine ähnliche „Lichtstreifen“-Textur extrahiert.
Das Ergebnis war diesem Beitrag sehr ähnlich, allerdings ohne inneren Schatten, und die Sättigung des unscharfen Hintergrunds habe ich etwas erhöht.
https://mastodon.social/@grishka/110524476584503201
Ehrlich gesagt ist die für das Tutorial erstellte Version gar nicht so großartig. Mir gefallen die schärferen Linien aus Windows 7 besser.
Über eine Sättigungsanpassung habe ich ebenfalls nachgedacht und sie auch in anderen Beispielen gesehen, mich aber entschieden, sie im Artikel nicht zu verwenden. Das verwendete Mondbild hatte nicht besonders viele Farben, daher hätte es wohl keinen großen Unterschied gemacht. Wer selbst einen Glaseffekt baut, sollte auch mit der Sättigung experimentieren.
Die Arbeit selbst ist hervorragend, und auch die Präsentation als interaktive Demo ist gut. Es macht Spaß, das Fenster über den Mond zu ziehen.
Allerdings mag ich den Einsatz von Milchglas-Effekten im User-Interface-Design nicht, und als sie in Mac OS hinzugefügt wurden, empfand ich das als Rückschritt. Designer lassen sich von diesem Effekt viel zu leicht verführen, aber ideal ist er in der Praxis nie – besonders dann nicht, wenn der Inhalt hinter dem Panel dynamisch oder nutzergeneriert ist.
Er ist so etwas wie Brushed Metal der 2010er, und es ist erstaunlich, dass er aus Windows Vista herausgesickert ist und sich überall verbreitet hat.
Natürlich beeinflusst Design auch die Funktion, aber sein Hauptzweck ist es, die User Experience angenehmer zu machen.
Meiner Ansicht nach macht Skeuomorphismus Interfaces angenehmer als der minimalistische Trend der letzten über zehn Jahre, alles flach zu machen. Visuelle Verzierungen, die Oberflächen und Materialien der realen Welt nachahmen, schaffen Vertrautheit und Zugänglichkeit. Auch praktisch gesehen macht Flat Design es schwieriger, Elemente und Zustände zu unterscheiden, während es in Zeiten von 3D-Buttons, Brushed Metal und Milchglas viel klarer war.
Ich denke, das Pendel schwingt jetzt wieder zurück. Da immer mehr Designer flache Optik vermeiden, hoffe ich auf eine Rückkehr menschenfreundlicherer UIs.
Blur ist meistens nicht die richtige Antwort, aber manchmal ist er die passende Wahl.
2008 gab es, bevor CSS
backdrop-blurunterstützte, schon ein CSS-Experiment für einen ähnlichen Effekt: https://webdev.andersriggelsen.dk/aero/Dabei wurde ein Glaseffekt auf ein fest positioniertes, vorab weichgezeichnetes Hintergrundbild gelegt: https://webdev.andersriggelsen.dk/aero/bgl.jpg
Das ist deutlich performanter als ein Echtzeit-Gaussian Blur, hat aber weiterhin den Nachteil, dass es keine dynamischen Hintergrundbilder erlaubt
So ließ sich der Glaseffekt sogar in einem Frame erzeugen, der sich dynamisch bewegen konnte. Ich erinnere mich nicht, ob ich dafür ein iframe verwendet habe, müsste also den Code suchen; wenn man die damalige Zeit bedenkt, ist es aber ziemlich wahrscheinlich
Es ist Windows 10 19045.5131, und Chrome ist die aktuelle Version 131.0.6778.86 (Official Build) (64-bit)
Die technische Leistung ist beeindruckend, aber ich halte es für schlechte UX
Inhalte in halbtransparenten Panels sind schwerer zu lesen oder zu erfassen als vor einem einheitlichen, einfarbigen Hintergrund; der Kontrast zum Hintergrund ist gering und ungleichmäßig. Außerdem kann es ablenken und die Orientierung erschweren, wenn sich darunter etwas bewegt
Bei guter Integration sollte man die Intensität des Effekts so steuern, dass die UI nicht überladen wirkt, die Feature-Unterstützung prüfen, um zusätzliche Ausschmückungen zu vermeiden, wenn Blur nicht unterstützt wird, und die Display- und Grafikfähigkeiten prüfen, um auf Geräten, deren GPU möglicherweise nicht ausreicht, nicht zu rendern
Außerdem sollte man Nutzereinstellungen berücksichtigen, um Nutzern, die mit komplexen Hintergründen Schwierigkeiten haben, eine kontrastreiche Vollfarbe anzubieten; den Umfang von Effekten und Schatten je nach verfügbarem Platz begrenzen; und Blur sowie Opazität an die Komplexität und den Kontrast des Hintergrunds unter dem verschwommenen Bereich anpassen
Auch muss sichergestellt werden, dass Blur und Schatten passend zur Typografie adaptiv skalieren. UX ist im Kern das Design dafür, wie Nutzer die Interaktion mit der gesamten App erleben; sie entscheidet sich nicht am Erfolg oder Scheitern einer einzelnen Stilentscheidung
Das stellt die Lesbarkeit des Textes selbst im Extremfall eines schwarzen Hintergrunds sicher. In CSS lässt sich das mit der Eigenschaft
text-shadownachbildenIn Spielen gibt es dafür aber mehr Einsatzmöglichkeiten. Besonders in einem HUD, bei dem man den Hintergrund als Hauptbereich der Nutzerinteraktion nicht verdecken möchte, kann es passend sein
Guter Kontrast ist bei jedem Designelement eine Herausforderung, egal ob Vollfarbe oder Glaseffekt
Dass Vorgänge im Hintergrund ablenken und die Orientierung erschweren, ist ebenfalls sehr subjektiv. Genau wie man die Opazität einer Vollfarbe verringern kann, lässt sich auch die Transparenz des Glases reduzieren
Diese Kritik ist schwerlich objektiv wahr; es gibt Möglichkeiten, dieses Designelement zu integrieren und solche Probleme zu vermeiden. Der Forza-Screenshot sieht in Ordnung aus, und auch in der tatsächlichen Ansicht fand ich den Hintergrund nicht ablenkend. Stattdessen bekommt man eine UI, die interessanter und visuell ansprechender ist als ein einfarbiger Hintergrund. In Videospielen mag das wichtiger sein, aber auch im OS- und Webdesign lässt es sich geschmackvoll einsetzen
Wenn viel Kontext nötig ist, ist Blur keine gute Wahl; wenn gar kein Kontext nötig ist, ebenfalls nicht
Manchmal ist es aber eine ausgezeichnete Wahl
Das interaktive Beispiel ist gut, aber noch besser wäre ein Toggle gewesen, mit dem man es neben der vorherigen Stufe vergleichen oder zwischen beiden wechseln kann
In den meisten Stufen waren die Verbesserungen so subtil, dass der Unterschied schwer zu erkennen war
Da liegen etwa zehn Effekte übereinander, und wenn man nicht die anspruchsvollste Ästhetik anstrebt, sind ungefähr sieben davon zu viel
Hintergrundfarbe, Blur und etwas Schatten oder Rahmen reichen aus
Schon in der dritten Stufe entsteht nur mit Blur und Schatten ein ziemlich ordentliches Stück Glas. Persönlich würde ich empfehlen, dazu ein statisches Bild mit Lichtstreifen zu mischen. Für die meisten Anwendungen dürfte der vollständige JavaScript-Effekt nicht nötig sein. Er macht Spaß, kann aber ablenken
Allein mit Blur, Schatten und Lichtstreifen kommt man dem Forza-Bild ganz oben wirklich nahe
Ich denke, das ist einer der Gründe, warum alle zu Flat Design gewechselt sind. Windows Vista und Glaseffekte sahen toll aus, waren aber rechnerisch teuer
Flat Design ist ästhetisch umstritten und kann besonders für ältere Nutzer schwieriger zu verwenden sein als skeuomorphes Design [0][1]
Wenn Realismus die Benutzbarkeit unterstützen kann, halte ich den Einsatz solcher Effekte im Web für durchaus sinnvoll
[0]: https://www.tandfonline.com/doi/abs/10.1080/0144929X.2020.18...
[1]: https://www.sciencedirect.com/science/article/abs/pii/S01419...
n <= 3liegen sollIch weiß nicht, ob es um Barrierefreiheit, Performance, Wartbarkeit oder etwas anderes geht
CSS ist mit Abstand meine schwächste Entwicklerkompetenz, deshalb kenne ich Best Practices und Anti-Patterns überhaupt nicht
Interessant, es fühlt sich an, als hätten wir uns einmal komplett im Kreis gedreht
Eine der frühen CSS-Demos, eine Demo für CSS 1, war ein Frosted-Glass-Effekt: https://meyerweb.com/eric/css/edge/complexspiral/glassy.html
Ehrlich gesagt ziemlich beeindruckend. Es macht immer wieder Spaß zu sehen, wie kreativ und leistungsfähig CSS sein kann.
Allerdings fühlt es sich so an, als gäbe es bei HTML/CSS eine Ebene, die ich niemals verstehen werde. Diese Demo ist genau so ein Fall: Diese Person baut ein mattiertes Fenster, und ich bekomme immer noch kein einzelnes
divzentriert.divhinzuzufügen.Wenn man sich die meisten modernen Websites anschaut, sind
divs dort wie riesige Haufen übereinandergestapelt. Wenn man ein zentriertesdivmöchte, wird es vergleichsweise einfach, wenn man darin noch eindiverstellt, das den gesamten Bereich einnimmt, in dem zentriert werden soll.Viele visuelle Tricks funktionieren ähnlich, aber dieses Beispiel ist sehr sauber umgesetzt und deshalb noch beeindruckender.
Es ist nicht exakt mattiertes Glas, aber ich habe in die Sidebar von https://www.gyan.dev/ffmpeg/builds/ einen Glasfenster-Effekt eingebaut.