Web Liquid Glass
Ein produktionsreifes Glasmaterial für Websites, extrahiert aus einer echten Next.js + Tailwind-Seite. Der vollständige funktionierende Quellcode befindet sich in reference/:
reference/liquid-glass.css: das gesamte Material (Token, Oberfläche, Varianten, geformtes Glas, Brechung, Degradation). Etwa 2.200 Zeilen mit ausführlichen Kommentaren zu jedem Wert. Lies den benötigten Abschnitt, nicht die gesamte Datei.reference/glass.tsx: die<Glass>-React-Komponente und der SVG-Refraktionsfilter.reference/glass-specular.tsx: das spekuläre Highlight mit Zeiger- und Neigungsverfolgung.
Die Referenz importiert zwei Hilfsfunktionen der Seite (cn und LITE_CLASS aus einem Lite-Mode-Modul). Ersetze sie durch das eigene cn/clsx des Projekts und einen Klassennamen für „Effekte aus“. Regeln mit den Namen sky-*, kiosk-* und gebetsbezogene Selektoren sind seiten-spezifische Beispiele für Varianten. Entferne sie oder verwende sie als Vorlagen.
Was Glas ist
Glas besteht aus vier Teilen. Eine Webversion wirkt billig, wenn sie nur den ersten Teil enthält:
- Material: Unschärfe UND eine Sättigungserhöhung (etwa 200%). Unter ~150% wirkt es wie graues Plastik. Füge Helligkeitsanhebung und Kontrastreduzierung hinzu, damit sich der dahinterliegende, bewegte Inhalt zu einer weichen Waschung auflöst.
- Rand: Ein heller Haarstrich, an dem das Licht die Kante trifft, auf der gegenüberliegenden Seite dunkler. Unschärfe ohne Rand wirkt nie wie Glas.
- Glanz: Ein weiches, spekuläres Highlight innerhalb der Oberkante.
- Tiefe: Ein breiter, sehr weicher Schatten mit geringer Deckkraft, kein enger Kartenschatten.
Brechung (das Verbiegen von Inhalten an der Kante) ist ein fünfter Teil und der einzige, den das Web nicht günstig umsetzen kann. Dafür wird backdrop-filter: url(#svg-filter) benötigt, was nur in Chromium funktioniert.
Wohin mit Glas
Setze Glas auf die Navigationsebene (Leisten, Kapsel-Navigationen, schwebende Bedienelemente, Blätter), nicht auf den Hauptinhalt. Der Textkontrast auf Glas hängt von dem ab, was dahinter scrollt, und kann daher nicht garantiert werden. Behalte undurchsichtige Karten als Standard für Inhalte bei und mache Glas pro Oberfläche opt-in (.lg).
Regeln, die viel Zeit kosten
- Das Glas-CSS muss in derselben Datei wie
@tailwind baseinnerhalb von@layerstehen. Tailwind löst@layerpro Datei auf, daher führt eine separate CSS-Datei zu einem Fehler bei@layer base. Das Entfernen des Wrappers macht die Regeln ungeschichtet, und ungeschichtete Regeln überschreiben jede Tailwind-Dienstprogrammklasse..lg { position: relative }überschreibt dann stillfixedauf einer Navi. - Schreibe niemals
--x: calc(var(--x) * 0.7). Es handelt sich um einen Zyklus: Ungültig zum Zeitpunkt der Berechnung des Werts, fällt es still auf den geerbten Wert zurück, ohne Fehlermeldung. Verwende eine zweite Variable (--lg-clarity-bump,--lg-press). - Eine Glasoberfläche hat genau eine Kante, und
::beforezeichnet sie. Zwei Kanten (ein::before-Rand plus eingelassenebox-shadow-Fasen oder ein gespreizter Schatten außerhalb der Border-Box) ergeben einen „Doppelrahmen“, den keine noch so feine Alpha-Anpassung behebt. corner-shapewird nicht vererbt. Wenn die Oberflächecorner-shape: squirclehat, benötigt jedes Pseudoelement, das auf der Grenze zeichnet, sowohlborder-radius: inheritals auchcorner-shape: inherit, sonst folgt der Rand einer anderen Kurve als der Körper.- Kein
backdrop-filterauf Glas, das in Glas verschachtelt ist. Es tastet einen bereits getönten Hintergrund ab und wird trüb. Ein Auswahl-Chip innerhalb einer Glasleiste (.lg-chip) ist eine getönte Linse ohne eigene Unschärfe. - Animieren keine geerbte benutzerdefinierte Eigenschaft auf
:root. Es invalidiert den Stil des gesamten Dokuments: etwa 11,6 ms pro Frame auf einer Seite mit 60 Oberflächen, gegenüber 2 ms, wenn der gleiche Wert pro Element geschrieben wird. - Leisten verwischen bei jedem Scroll-Frame neu. Gib
.lg-bareinen kleineren Unschärferadius pluscontain: paint. Wenn ein Gerät immer noch ruckelt, setze--lg-blur-bar: 0px; der Rand und der Glanz tragen den Großteil des Looks. - Glasiertes Glas nicht abflachen, um einen Fehler zu beheben. Eine nahezu undurchsichtige „einfarbige“ Leiste verliert den Look. Finde stattdessen die geometrische Ursache (Masken, die den Körper an der Kante ausdünnen, ein verdoppelter Rand).
- Eine SVG-Refraktionslinse darf niemals über ihre eigene Box hinaus tasten. Chrome gibt dort Transparent zurück, und der ursprüngliche Inhalt erscheint als Geisterbild.
Safari und iPhone
WebKit unterstützt backdrop-filter, lehnt aber SVG-Filter darin ab, daher erhält Safari weniger als Chrome: nie eine Brechung. Was Safari brechen kann, ist seine eigene Symbolleiste. Setze viewportFit: "cover", damit die Seite darunter läuft, dann wird env(safe-area-inset-*) für die Navigation und Fußzeile obligatorisch.
Barrierefreiheit und Fallbacks (immer ausliefern)
Jede Oberfläche muss zu einem nahezu undurchsichtigen Farbton degradieren, der ähnlich aussieht und nichts pro Frame kostet:
@media (prefers-reduced-transparency: reduce)@supports not (backdrop-filter: blur(1px))@media (prefers-contrast: more): ein stärkerer Farbton und eine solide Kante- eine Root-Klasse wie
.lg-off, die alle Glasoberflächen auf einmal deaktiviert (für einen Benutzer-Schalter oder einen Energiesparmodus)
Gib Leisten ihren eigenen, höheren maximalen Farbton (--lg-tint-max-bar), damit Navigationslinks den Textkontrast behalten, wenn Inhalt darunter scrollt.
Wie anwenden
- Kopiere den Token-Block und den Oberflächenabschnitt aus
reference/liquid-glass.cssin die Haupt-CSS-Datei des Projekts, innerhalb seiner vorhandenen@layer-Blöcke (Regel 1). - Ordne die Farb-Token der Palette des Projekts zu. Die Referenz verwendet shadcn-artige
hsl(var(--card))-Token. - Verwende
<Glass>ausreference/glass.tsxoder die einfachen Klassen.lg,.lg-bar,.lg-nav,.lg-pane,.lg-chipund.lg-refract. - Füge das spekuläre Highlight aus
reference/glass-specular.tsxnur dort hinzu, wo es seinen Preis wert ist (Heldensteuerung, Hauptnavigation), und beachteprefers-reduced-motion. - Überprüfe in Chrome UND Safari, in hell UND dunkel, über einem belebten Foto und über einfachem Text.
Fertige Steuerelemente: Glisse
Glisse von Kelvin Zhang (npm install glisse, MIT, React 18+, keine weiteren Abhängigkeiten) liefert interaktive Liquid-Glass-Steuerelemente mit dem bereits integrierten „Drücken zum Linsen“-Verhalten: Button, Switch, Slider, TabBar, SegmentedControl, Menu, Input, SearchField und eine einfache Glass-Oberfläche. Seine Stile werden vom JS-Bundle injiziert, es muss also keine CSS-Datei importiert werden.
Wann was verwenden:
- Glisse für Steuerelemente: Schalter, Slider, Tab-Leisten und segmentierte Steuerelemente, deren Daumen beim Ziehen in eine Linse aufsteigt. Das von Hand zu bauen, ist Tage Arbeit.
- Dieses Material für Oberflächen: Navigationsleisten, Kapsel-Navigationen, Panels, Blätter, Karten über Fotos und alles, was zu einem bestehenden Designsystem oder Tailwind-Theme passen muss.
Fallstricke bei der Kombination:
- Beide verwenden das Präfix
lg-. Glisse definiert.lg-glass,.lg-button,.lg-tab-barund die Variablen--lg-blur,--lg-tint,--lg-rimund--lg-filter, die mit den Token dieses Materials kollidieren. Auf einer Seite, die beide verwendet, benenne das Präfix dieses Materials um (z. B. inylg-) oder beschränke Glisse auf einen Wrapper, der diese Variablen zurücksetzt. Ansonsten stimmen sie sich gegenseitig stillschweigend nach. - Glisses Dark Mode orientiert sich an
data-theme="dark"oderprefers-color-scheme, nicht an Tailwinds.dark-Klasse. Bei klassenbasiertem Dark Mode setzedata-themeauf<html>zusammen mit.dark, sonst bleibt Glisse hell. - Glisse behandelt
prefers-reduced-motion, aber nichtprefers-reduced-transparencyoderprefers-contrast. Füge die Fallbacks aus dem Barrierefreiheitsabschnitt dieser Skill um die Glisse-Steuerelemente hinzu. - Glisses
.lg-glasszeichnet bereits eine Kante mit einem eingelassenenbox-shadow. Füge keinen::before-Rand darauf hinzu (Regel 3: nur eine Kante).