Communitygithub.com

sridhar-raj/blur-craft

Hochwertige Glas-Effekte und Unschärfe für UI, mit nachweislicher Lesbarkeit: Apple-inspiriertes Milchglas (gemessenes Material mit Dickenstufen, beleuchteter Kante und abgetönter Stufe), fertige Glasoberflächen, Liquid-Glass-Refraktion, progressive Unschärfe und Kontrastprüfungen für React, Vue, Svelte, Tailwind und native Frameworks.

Was ist blur-craft?

Blur craft ist eine technische Sammlung von CSS-, Script- und Framework-Komponenten, die hochwertige Glas-Effekte für Web- und native UIs ermöglicht, die oft billig aussehen. Die Lösung folgt drei Prinzipien: Licht hinter dem Glas gestalten, das Glas als gemessenes Material behandeln (mit Dickenstufen, Gradienten, beleuchteten Kanten, Glanz und Körnung) und den Textkontrast an der dunkelsten Stelle automatisch prüfen. Enthalten sind vorgefertigte Oberflächen wie sticky Navbars, Docks, Menüs, Dialoge und Toasts, die alle auf den CSS-Klassen in `assets/glass.css` basieren und für React, Vue, Svelte und Tailwind v4 verfügbar sind. Die Lösung umfasst außerdem Signature-Effekte wie Liquid-Glass-Refraktion, progressive Unschärfe, Blur-Reveals und Glow-Effekte sowie Leistungsoptimierungen (geringer Blur-Flächenverbrauch, Geräte-Tiering, Vermeidung von Blur auf verdeckten Flächen). Zwei Prüfskripte (`frost-check.mjs` und `glass-contrast.mjs`) stellen sicher, dass Glas konsistent und lesbar bleibt, selbst bei hellen oder dunklen Hintergründen.

Funktioniert mit~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/sridhar-raj/blur-craft/tree/HEAD

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Blur craft

Das meiste Glas im Web sieht billig aus – aus drei Gründen: Dahinter passiert nichts Interessantes, das Material besteht aus einem einfarbigen Tönung mit einer Unschärfe, und der Text darauf ist ein matschiges Grau, das niemand gemessen hat. Glas, das teuer aussieht (Apples Materialien, visionOS, die besten Produktseiten), macht drei Dinge richtig, in dieser Reihenfolge:

  1. Das Licht hinter dem Glas ist gestaltet. Glas zeigt, was dahinter ist, also platziere dort ein Licht.
  2. Das Glas ist ein Material, keine Tönung. Gesättigte Unschärfe, eine Verlaufsfüllung, eine beleuchtete Kante, ein spiegelnder Glanz, Tiefe, Körnung. Das ist assets/glass.css.
  3. Der Text ist gemessen. Transluzentes Glas ändert den Kontrast mit jedem Pixel dahinter, daher wird der Kontrast an der schlechtesten Stelle geprüft, per Script, in drei Zuständen (scripts/glass-contrast.mjs).

Schnellübersicht

Ich baue …VerwendeHinweise
Eine sticky Navigationsleiste.gs-bar (surfaces.css)Erweiterter Hintergrund; füge gs-bar--on-scroll hinzu, um es erst nach dem Scrollen gläsern zu machen
Einen Player, Dock oder Pill über Kunst.gs-dock.glass.glass--clear + liquid-glass.jsKlares Liquid Glass, eines pro Bildschirm; adaptiver Farbton bei stark wechselnder Kunst
Eine schwebende Karte oder ein Panel mit Text.glass.glass--regularthick über einem detaillierten Foto
Ein Menü, Popover oder Command-Bar.gs-menu.glass32px über ~86%, 0,5px oberer Highlight
Einen Dialog.gs-veil + .gs-dialog.glass.glass--thickglass--solid wenn es um Geld, Löschen oder Unterschriften geht; gs-veil--flat + .gs-modal-open wenn Glas-Chrom darunter sitzt
Einen Toast oder ein Bottom-Sheet.gs-toast.glass.glass--regular / .gs-sheet.glass.glass--thickDie gs--Klassen sind nur Layout; das Material kommt von .glass
Inhalt, der unter einer Leiste verschwindetProgressive Unschärfe (Rezept 2)Ein Scroll-Kanten-Effekt pro Ansicht
Eine Überschrift, die erscheint, oder ein Wert, der sich ändertBlur Reveal (4) / 2px Crossfade (4b)Einmal pro Bildschirm
Eine Seite, die in den Farben der Kunst getaucht istArt-Backdrop, gebacken (Rezept 8)Niemals eine Live-Unschärfe unter festem Glas
Ein Tailwind v4-Projektglass.css + glass.tailwind.css (glass-blur-24, …)Tailwinds eigenes backdrop-blur-* bricht auf Sonoma Safari
Eine native App (SwiftUI, Flutter, React Native, Compose)references/native.mdGleiche Methode, jedes Toolkits Material
Chrom für einen Foto-, Video- oder Design-Editor.glass.glass--thick.glass--neutralNeutral: keine Sättigungssteigerung, das Glas darf die Arbeit nicht verfärben

Danach: Komponiere das Licht (§1), setze das Material (§2), prüfe (§5). assets/demo.html zeigt jede Oberfläche live mit Bedienelementen; öffne es, um zu sehen, was jede Klasse bewirkt, bevor du dich entscheidest.

1. Zuerst das Licht komponieren

Entscheide, was direkt hinter jeder Glasoberfläche sein wird, und mache es zum Leuchtendsten dort.

  • Platziere ein Licht unter dem Glas: einen Glow, die Sonne in der Kunst, die Farben des Produkts, eine live WebGL-Komponente. Unscharfe, einfarbige Farbe ist dieselbe einfarbige Farbe; Glas über einer Leere ist eine graue Box.

  • Lass das Licht die Kante überqueren. Das beste Glas sitzt zur Hälfte über dem Licht und zur Hälfte über der Dunkelheit, sodass sich die Farbe über seine Breite verschiebt.

  • Richte die Kante auf das Licht aus. Setze --glass-light auf die Farbe des Lichts (255 200 160 für einen Sonnenuntergang) und --glass-rim-angle auf seine Richtung. Das helle Ende der Kante zeigt zum Licht:

    Licht vonoben-linksobenoben-rechtsrechtsunten-rechtsuntenunten-linkslinks
    Winkel135deg180deg225deg270deg315deg0deg45deg90deg

    Ein Licht unter dem Glas nimmt den Winkel seiner nächsten Kante plus ~15deg zur Mitte hin. Der Winkel ist eine registrierte @property, sodass er dem Zeiger oder dem Scrollen sanft folgen kann (Apples Highlights wandern um das Material, während sich das Licht bewegt).

  • Bemesse Glas wie den Helden, der es ist. Es liest sich als Material, wenn es groß genug ist, um die Szenenänderung darunter zu zeigen. Apple lässt größeres Glas sich wie dickeres Glas verhalten: tieferer Schatten, weichere Streuung.

2. Das Material setzen

Verwende assets/glass.css (benenne das glass-Präfix beim Kopieren um) und assets/surfaces.css für die vorgefertigten Oberflächen, oder die Komponenten: Glass.tsx (React), Glass.vue (Vue 3), Glass.svelte (Svelte 5). Schreibe keine einzeilige backdrop-filter-Karte von Hand.

Schreibe backdrop-filter mit Literalwerten, niemals var(), zuerst ohne Präfix und -webkit- zuletzt. Safari 18 und 26 unter macOS Sonoma rendert keine Unschärfe, wenn der Filter aus benutzerdefinierten Eigenschaften aufgebaut ist (WebKit 297620, offen), und Tailwind v4s backdrop-blur-* ist genau so aufgebaut. Derselbe Bugbericht zeigt, dass die unprefixierte Eigenschaft dort sogar mit einem Literalwert fehlschlägt, daher kommt die mit Präfix deklarierte zuletzt, wo Safari sie anwendet (Chrome und Firefox ignorieren sie). glass.css hat einen Literalfilter pro Dicke × Ton und wechselt per Klasse; Variablen sind für Füllungen, Abdunklungen und Farben in Ordnung.

Dicke. Wähle danach, wie viel Text das Glas trägt. Die Werte wurden mit dem Kontrastprüfer über einem hellen Licht in demo.html kalibriert:

KlasseUnschärfe, AbdunklungBesteht 4.5:1 über hellem Licht?Verwende für
glass--clear16px, 22%Nein: nur fett oder großen Text und SymboleDocks, Play-Buttons, Pills über Medien (Apple: Clear benötigt fette, helle Inhalte und eine Abdunklungsschicht)
glass--thin24px, 30%Nicht über dem hellsten LichtSteuerelemente, Chips, kleine Karten über moderaten Hintergründen
glass--regular32px, 48%Ja auf der Kalibrierungsseite; ein heller Sonnenuntergang hinter einem Player benötigte thick bei 0.62Player, Panels, Toasts: der Standard. Der Zustand ohne Unschärfe (nur Tönung) versagt meist zuerst
glass--thick44px, 56%JaMenüs, Sheets, Dialoge, alles Textlastige
glass--solid4px, 92%JaZahlungen, Löschvorgänge, Unterschriften (über ~85% Füllung ist eine große Unschärfe nicht sichtbar, daher 4px)

Füge glass--light für helles Glas mit tintenfarbenem Text hinzu und glass--neutral bei farbkritischen Apps (Foto-, Video- und Design-Editoren): keine Sättigungssteigerung oder Farbtonverschiebung, weil das Glas das Aussehen der Arbeit nicht verändern darf. Über einem detaillierten Foto starte mit thick und --glass-dim: rgb(10 10 18 / 0.65–0.75) (es ist eine Farbe, keine Zahl): lebendiges Glas und lesbarer Text ziehen dort gegeneinander, also gib die Lebendigkeit für die Kante, den Glanz und das um das Glas herumfließende Licht aus.

Zwei Stufen, wie iOS 26.1: eine getönte Stufe (mehr Deckkraft, niemals weniger) schaltet sich für prefers-contrast: more ein (die Einstellung, die Safari-Nutzer erreichen können; Safari hat kein prefers-reduced-transparency), mit glass--tinted, oder seitenweit mit <html data-glass="tinted">. glass.css behandelt auch Windows High Contrast (solide Canvas-Oberfläche), Druck (einfach gerahmte Box), Capture-Modus für Screenshot-Tools und RTL.

Glas gehört zur Steuerungsebene (Navigation, Symbolleisten, Docks, Menüs, Sheets, Dialoge), die über dem Inhalt schwebt, niemals zum Inhalt selbst, und niemals Glas auf Glas (Apple, WWDC25). Töne nur die primäre Aktion. Passe das Register des Briefings an: immersive Briefings nehmen starkes Licht und klares Glas auf der Heldensteuerung; vertrauenswürdige (Finanzen, Gesundheit) nehmen dickes oder solides Glas und kaum Licht.

references/material.md enthält den Rest: was jede Ebene tut und warum, die Presets aus Apple.com, Linear, Raycast, Radix, Material und Fluent, Apples vollständige WWDC25-Regelliste und die Registertabelle.

3. Signature-Effekte

Code in references/recipes.md:

  • Liquid-Glass-Refraktion: Die Kante biegt, was dahinter ist, wie eine Linse, optional mit chromatischer Aberration (0.6–1). Zwei Versionen: liquid-glass.ts/.js beugt jeden Seiteninhalt, aber nur in Chromium (Safari malt nichts für SVG-Hintergrundfilter, WebKit 245510); liquid-glass-webgl.js beugt einen Hintergrund, den die Seite selbst zeichnet (ein <canvas>, <img> oder <video>, z. B. ein Hero-Hintergrundbild) in jedem Browser, getestetes Rendering in Chromium und WebKit. Anderswo muss das matte Material für sich allein fertig aussehen. Refraktion und Mattierung tauschen gegeneinander ab: Die Biegung zeigt sich durch klares Glas (blur 0–6); mattiertes (12–20) mattiert von Kante zu Kante und die Biegung wird zu einer sanften Farbverschiebung. Klar für ein Wort oder ein Symbol, mattiert für Sätze, Text einen Rahmenbreite innerhalb der Kante. Niemals auf einem Dialog über einem Schleier: Es gibt nichts Scharfes zum Biegen mehr.
  • Erweiterter Hintergrund für sticky Bars: Farbe kommt im Glas an, bevor Inhalt darunter scrollt. gs-bar--on-scroll macht die Leiste nur nach dem Scrollen gläsern, in reinem CSS (scrollgesteuerte Animationen).
  • Progressive Unschärfe: Inhalt löst sich unter einer Leiste auf, statt abgeschnitten zu werden. Gestapelte maskierte Ebenen sind der einzige Weg, bis CSS linear-blur() erhält (vorgeschlagen, csswg #13285).
  • Blur-überbrückter Crossfade: 2px Unschärfe während eines Zustandswechsels (Emil Kowalski).
  • Blur Reveal: von blur(8px), einmal, als Ankunftsmoment.
  • Fokus-Schleier: Die Seite hinter einem Dialog tritt 4–8px zurück.
  • Glas-Morph und Drücken: ein layoutId-Morph zwischen nahen Glasformen (Cursor: 0.34s, [0.32, 0.72, 0, 1]) und ein Inner-Glow-Puls beim Drücken, keine Skalierung.
  • Verschmelzende Glasformen: eine Glasebene, geschnitten durch eine goo-gefilterte SVG-Maske, sodass nahe Formen mit einem flüssigen Hals verbunden werden, wie Apples Glasbehälter (Rezept 11, getestet in Chromium).
  • Ambient-Glow aus Video: ein 10×6-Canvas-Sample des laufenden Videos, hochskaliert (Rezept 8b).
  • Tönung: Chroma ~0.03–0.05 für strukturelles Glas, relativer Farb-Alpha für Tönungen (Rezept 12).
  • Tiefenschärfe, Geschwindigkeitsbewegungsunschärfe, Kunst-Hintergrund (gebacken), gesperrter Inhalt, Körnung.

4. Halte es schnell

Gestalte zuerst das Aussehen, dann halte diese Punkte ein:

  • Lange oder sich wiederholende Animationen finden auf Deckkraft und Transformation statt, nicht auf dem Unschärferadius. Kurze Einmal-Aktionen sind in Ordnung: Apple.com animiert die Unschärfe seines Menüvorhangs von 0 → 20px über 320ms.
  • Verwische niemals zwei gestapelte Oberflächen gleichzeitig (Apples Navigation gibt ihre eigene Unschärfe auf, während ein Flyout geöffnet ist). Wenn ein Dialog über Glas-Chrom geöffnet wird, füge .gs-modal-open zu <html> hinzu (das Chrom stoppt die Unschärfe und wird nahezu undurchsichtig) und verwende gs-veil--flat, oder backe den Schleier aus einem Bild- oder Canvas-Hintergrund. Gemessen in einem Fotoeditor-Test: ein Live-Vollbild-Schleier-Unschärfe über fünf Glaspanels lief mit 31fps; ohne sie 60.
  • Eine fixierte oder sticky Unschärfe wird bei jedem Scroll-Frame neu ausgeführt. Eine große pro Bildschirm; backe große unscharfe Bilder darunter (gemessen: 60 → 22fps mit Live-Unschärfe, zurück auf 60 gebacken).
  • Telefone: sieben 18px-Panels kosten ~3,5ms pro Frame auf einem Mali-G57 (75–80% der Frames rechtzeitig vs. 99% ohne). Bei mehr als ein paar Panels entferne backdrop-filter am Telefon-Breakpoint deines Layouts und behalte die transluzente Füllung (oder lass glass-tier.js pro Gerät entscheiden).
  • Budgetiere die unscharfe Fläche, nicht den Radius oder die Anzahl. Gemessen für diese Fähigkeit (Chromium, Software-Rendering bei 2×, bewegter Hintergrund, vsync an): Radius 4 → 64px und 1 → 9 Oberflächen bei derselben Gesamtfläche machte keinen Unterschied; das Verwischen von 90% des Bildschirms fiel auf 51fps (p95 33ms). Das stimmt mit Skia-Downsampling großer Unschärfen überein. Die Zahlen sind relativ (ein schneller Mac, der in Software rendert), das Ranking ist das, was übertragbar ist.
  • Gib html eine undurchsichtige Hintergrundfarbe: Safari überspringt dann eine zusätzliche Vollbild-Compositing-Ebene für Seiten mit Glas (WebKit 271340: der Fix überspringt die Ebene nur für undurchsichtige Dokumente).
  • Verwische nicht unter einer undurchsichtigen Füllung. Framer und Dia liefern backdrop-filter auf soliden Hintergründen und bezahlen für eine Unschärfe, die niemand sehen kann. Über ~85% Füllung verwende ≤ 4px oder keine (Arcs Toasts: 85% und 3px).
  • Stufe Glas nach Gerät: assets/glass-tier.js setzt data-glass-tier auf full, lite (eine 8px-Unschärfe) oder flat (keine Unschärfe, mehr Tönung) basierend auf Gerätespeicher, Save-Data, einem Frame-Rate-Sensor (iOS Low Power Mode begrenzt Animationen absichtlich auf 30fps) und Compute Pressure, so wie Android, Fluent und Apple Unschärfe auf schwachen oder energiesparenden Geräten entfernen.
  • Über Video: verwische nicht das laufende Video; sample es in eine winzige Canvas (Rezept 8b) und entferne Glas im Vollbildmodus. Safari übergibt niemals Videopixel an SVG-Filter.
  • Hintergrund-Root: ein Elternelement mit opacity < 1, filter, einer Maske, clip-path, mix-blend-mode, backdrop-filter oder will-change auf einem davon macht Glas darin flach. Das schließt ein Framer Motion-Eltern-Fade und einen goo filter auf einem Elternelement von Glas-Blobs ein. Fade das Glas selbst; entferne Reveal-Filter (filter: none), wenn sie fertig sind.
  • backdrop-filter macht ein Element zum Containing Block für position: fixed-Kinder: Portal-Menüs, Toasts und Dialoge aus Glasbehältern.
  • Ein stehender view-transition-name auf einem Vorfahren macht Glas in Chromium flach; setze Namen nur während des Übergangs. Framework-Fade-Übergänge auf einem Wrapper tun dasselbe: Fade das Glas selbst.
  • Screenshots, OG-Bilder oder PDFs von Glas: html2canvas, Satori und Druck entfernen oder brechen die Unschärfe. Setze data-glass-capture auf <html> während des Aufnehmens (glass.css macht Glas undurchsichtig) und siehe quirks.md.

5. Prüfen (erforderlich)

Führe alle folgenden Schritte aus, bevor du das Glas als fertig bezeichnest:

  1. Frost-Check: node <skill>/scripts/frost-check.mjs <url or file.html> misst für jede Glasoberfläche, wie viel Detail die Unschärfe entfernt (Unschärfe an vs. aus). NO BLUR bedeutet ein Hintergrund-Root, ein kaputtes Präfix oder var() oder eine veraltete Liquid-Glass-Karte; FLAT bedeutet, dass nichts dahinter zu messen ist. Um stattdessen mit dem Auge zu prüfen, setze fetten roten Text hinter das Glas, erfasse bei deviceScaleFactor: 1 und vergrößere.
  2. Kontrast, gemessen, auf dem schlechtesten Hintergrund: node <skill>/scripts/glass-contrast.mjs <url or file.html>. Richte es auf den hellsten realistischen Zustand, nicht den hübschen Standard: das hellste Foto, einen Tageslicht-Frame, ein um +2 EV angehobenes Bild, den weißen Seitenabschnitt, der unter die Leiste scrollt (füge URL-Parameter oder einen Testzustand hinzu, damit das Skript ihn laden kann). Bei einem Editor bestand das Standardfoto bei 8.7:1 und ein heller Frame fiel bei 4.4:1 durch. Prüfe auch die Telefonbreite (--width 390 --height 844). Es versteckt den Text, findet den hellsten und dunkelsten Pixel unter jeder Zeile und prüft 4.5:1 (3:1 groß) in drei Zuständen: normal, nur Tönung (Unschärfe aus, wie iOS Low Power Mode es zeigt) und prefers-contrast: more. Behebe Fehler, indem du eine Dicke höher gehst, den Alpha in --glass-dim erhöhst (z. B. --glass-dim: rgb(10 10 18 / 0.7)) oder die Glasfüllung mehr zur undurchsichtigen Seite verschiebst, ohne den Materialcharakter zu verlieren: Die Grenze liegt bei etwa 75–80% je nach Textgröße. Wenn der Text auf der Tönung allein besteht, das Glas aber auf der Unschärfe angewiesen ist, um lesbar zu sein, entferne die Unschärfe auf diesem Gerät vollständig (flat) und gleiche mit mehr Tönung aus.

assets/demo.html öffnet jede Oberfläche live mit Bedienelementen für die Dicke, den Lichtwinkel und die Prüfungen.

Verwandte Skills