Glassmorphism UI Library
Vollständige CSS-Komponentenbibliothek im Glasmorphism-Stil – entwickelt von der Jungherz GmbH. Reines CSS, keine Abhängigkeiten, Dark & Light Mode.
Installation
Eine CSS-Datei einbinden – fertig. Optional ein Theme-Override für andere Markenfarben.
Design Tokens
Alle visuellen Werte werden über CSS Custom Properties gesteuert.
Farbpalette
| Token | Dark-Wert | Verwendung |
|---|---|---|
--gl-color-primary | #f5a623 | Primärfarbe, Buttons, aktive Elemente |
--gl-color-primary-dark | #d4692a | Gradient-Endwert |
--gl-color-primary-text | var(--gl-color-primary) | Text und Linien-Icons in der Primärfarbe: Links in Prose, der aktive Tab, die primäre Modal-Aktion, Akzent-Listenzeilen, der Wert eines Reglers, das Akkordeon — seit 1.26.0, siehe Primärfarbe als Text |
--gl-color-primary-on-glass | color-mix(in srgb, var(--gl-color-primary-text) 60%, #ffffff) | Die Primärfarbe als Text auf dem Glas einer Karte, eines Modals oder eines Sheets: Links, der Range-Wert, Akzentzeilen, die primäre Modal-Aktion (seit 1.35.0); im hellen Modus der Primärtext |
--gl-focus-ring | color-mix(in srgb, var(--gl-color-primary) 15%, #ffffff) | Die Markierung der Tastatur, eine deckende Farbe; --gl-border-focus und --gl-shadow-focus nehmen sie. Im hellen Theme var(--gl-color-primary-on-surface) — seit 1.40.0, siehe Fokusmarkierungen |
--gl-color-text | #ffffff | Standard-Textfarbe |
--gl-color-text-muted | rgba(255,255,255,0.65) | Sekundärer Text |
--gl-color-success | #34c759 | Erfolg-Status |
--gl-color-error | #ff3b30 | Fehler-Status |
--gl-color-warning | #ffcc00 | Warn-Status |
--gl-color-{state}-surface, -border, -on-surface | color-mix(…) | Getönte Fläche, Rand und Schrift eines Status-Badges, abgeleitet von der Statusfarbe — für success, error und seit 1.18.0 warning |
Glasflächen
| Token | Wert | Verwendung |
|---|---|---|
--gl-surface-1 | rgba(…, 0.08) | Subtilste Fläche (Status) |
--gl-surface-2 | rgba(…, 0.10) | Standard (Inputs, Cards) |
--gl-surface-3 | rgba(…, 0.14) | Nav-Pills, Badges |
--gl-surface-4 | rgba(…, 0.16) | Hover-States |
--gl-surface-5 | rgba(…, 0.22) | Starker Hover |
--gl-surface-milk-strong | rgba(…, 0.75) | Secondary Button |
Glanz
| Token | Wert | Verwendung |
|---|---|---|
--gl-gloss-card | linear-gradient(90deg, …) | Licht an der Oberkante von .glass-card--glow |
--gl-gloss-modal | linear-gradient(90deg, …) | Dasselbe an .glass-modal |
--gl-gloss-progress | linear-gradient(to bottom, …) | Schimmer auf dem Fortschrittsbalken |
--gl-range-thumb-border | 2px solid rgba(255,255,255,0.5) | Rand des Range-Knopfs |
--gl-gloss-droplet | radial-gradient(…), radial-gradient(…) | Glanzlicht und Leuchten im Tropfen der --droplet-Zeilen (seit 1.27.0) |
Seit 1.24.0, in beiden Themes gleich. data-surface="solid" schaltet sie ab, zusammen mit dem Blur und dem Glanz von --gl-inset-*.
Spacing & Radii
| Token | Wert | Token | Wert |
|---|---|---|---|
--gl-space-2xs | 4px | --gl-radius-xs | 8px |
--gl-space-xs | 8px | --gl-radius-sm | 12px |
--gl-space-sm | 12px | --gl-radius-input | 14px |
--gl-space-md | 16px | --gl-radius-btn | 16px |
--gl-space-lg | 20px | --gl-radius-card | 24px |
--gl-space-xl | 24px | --gl-radius-full | 9999px |
--gl-space-2xl | 32px | --gl-radius-pill | 50% |
Dichte
| Token | Standard | Kompakt | Verwendung |
|---|---|---|---|
--gl-control-height | 52px | 40px | Input, Select, Suchfeld |
--gl-control-padding-x | nicht gesetzt → --gl-space-md | --gl-space-sm | Innenabstand links und rechts von Input, Select, Textarea |
--gl-btn-height | 56px | 40px | Button |
--gl-btn-height-sm | 44px | 32px | Button --sm |
--gl-btn-height-lg | 64px | 48px | Button --lg |
--gl-textarea-min-height | 120px | 88px | Textarea |
--gl-list-item-min-height | 56px | 48px | Listenzeile |
--gl-list-item-padding-y | nicht gesetzt → --gl-space-md | 10px | Listenzeile, oben und unten |
--gl-toggle-width × -height | 52 × 30px | 44 × 26px | Toggle-Spur |
--gl-toggle-thumb-size | 22px | 18px | Toggle-Knopf |
--gl-check-size | 24px | 20px | Checkbox, Radio |
--gl-modal-action-height | 52px | 44px | Modal-Aktionen |
Theming (Light / Dark)
Das Theme wird über data-theme am <html>-Element gesteuert.
Primärfarbe als Text
Die Primärfarbe hat zwei Aufgaben. Als Fläche trägt sie weiße Schrift: Buttons, der eingeschaltete Schalter, der aktuelle Schritt, der gewählte Tag. Als Schrift steht sie selbst auf der Seite oder dem Glas: Links in .glass-prose, Icon und Label des aktiven Tabs, die primäre Modal-Aktion, Akzent-Listenzeilen, der Wert eines Reglers, der Akkordeon-Auslöser unter dem Zeiger und der Chevron eines geöffneten Abschnitts. Seit 1.26.0 hat die zweite Aufgabe ein eigenes Token, --gl-color-primary-text. Setzt ein Projekt es nicht, ist es die Primärfarbe, und es ändert sich nichts.
Eine Marke, die ihre Primärfarbe abdunkelt, damit weiße Button-Schrift 4,5:1 erreicht, bekommt einen Ton, der für Schrift auf dunklem Hintergrund zu dunkel ist. Sie hellt die Schrift im dunklen Theme auf, und die Buttons behalten ihre Farbe:
Die helle Regel steht nach der dunklen: :root trifft auch eine Seite im hellen Theme, und von zwei passenden Regeln gewinnt die spätere. Der richtige Ton hängt vom Hintergrund ab, also dort messen. Auf GlassKits eigenem dunklen Hintergrund mit #c25028 als Primärfarbe hebt diese Mischung einen Link auf einer Glas-Card von 1,37:1 auf 5,05:1.
Seit 1.35.0 nimmt Akzenttext auf dem Glas einer Karte, eines Modals oder eines Sheets --gl-color-primary-on-glass: im dunklen Modus den Primärtext mit 40 % Weiß, weil eine Karte heller ist als die Seite. GlassKits eigenes Orange las als Link auf einer Karte im dunklen Modus 4,18:1, jetzt 5,54:1; auf der Seite bleibt es bei 5,69:1. Im hellen Modus ist der Token der Primärtext. Links und Chips der Seite auf einer Karte nutzen ihn ebenso, color: var(--gl-color-primary-on-glass). Das helle obere Ende einer .glass-card--glow bleibt für Akzenttext außer Reichweite: Setze ihn tiefer in die Karte oder nimm dort die Textfarbe.
Der aktive Tab nimmt für Icon und Label --gl-tab-bar-active-color, wo das gesetzt ist, sonst --gl-color-primary-text. Das Spotlight der Floating-Bar hellt den aktiven Eintrag stärker auf als jede andere Fläche, eine Marke braucht dort also womöglich einen helleren Ton, bis hin zu Weiß. Es wird pro Theme gesetzt wie die Textfarbe; var(--gl-color-primary-text) in der hellen Regel stellt die Vorgabe wieder her. Leuchten und Punkt bleiben in der Primärfarbe, das Spotlight in --gl-tab-bar-spotlight-color.
Seit 1.31.0 erreichen gedämpfter Text, Kartentext und Icons von Haus aus WCAG AA, in beiden Themes. Die Primärfarbe als Text nicht, mit Absicht: GlassKits eigenes Orange liegt als Text auf der hellen Seite bei 2,43:1, eine dunklere Marke besteht aber womöglich schon oder braucht viel weniger, und eine feste Mischung mit Schwarz würde jede Marke gleich stark abdunkeln. Wo das helle Theme beim Orange bleibt, dunkle es dort ab; --gl-color-primary-on-surface, die Tinte des primären Badges, erreicht 5,8:1. Auch Weiß auf dem Primary-Button gehört zum Aussehen, 2,7:1 im hellen und 2,0:1 im dunklen Theme am hellsten Punkt des Verlaufs; --gl-color-on-primary stellt auf eine dunkle Tinte um, die auf jedem Punkt 4,6:1 oder mehr erreicht:
Seit 1.32.0 haben beide Wege eigene Tokens. Wer weiße Schrift behalten will, dunkelt die Fläche ab und lässt die Markenfarbe in Ruhe, die auch Fokusringe, Rahmen, das Spotlight der Tab-Bar und den Akzent als Schrift zeichnet. --gl-color-primary-fill ist dabei die flache Akzentfläche, die Schrift trägt — der gewählte Tag von Wochenstreifen und Kalender, die Nummer des aktuellen Schritts —, ungesetzt die Primärfarbe; --gl-btn-primary-bg ist der ganze Hintergrund des Primary-Buttons, ungesetzt der bisherige Verlauf. Auf GlassKits eigenem Orange erreicht Weiß 4,5:1 ab 75 % Primärfarbe im hellen Theme und ab 65 % im dunklen, und der Verlauf unten bleibt auf jedem Punkt darüber:
Auf dem gewählten Tag des Wochenstreifens ist der Wochentag jetzt so kräftig wie die Zahl (seit 1.32.0); verblasst blieb er selbst auf einer Fläche unter 4,5:1, auf der die Zahl es erreicht.
Die dunkle Tinte erreicht jetzt auch das Radio: Sein Punkt folgt --gl-color-on-primary, solange --gl-radio-dot-color nicht gesetzt ist, wie das Häkchen der Checkbox (seit 1.32.0). Wo die Markenfarbe erst zur Laufzeit feststeht, kann der Browser die Tinte wählen: contrast-color() liefert Schwarz oder Weiß, je nachdem, was sich stärker von der Primärfarbe abhebt — für GlassKits Orange in beiden Themes Schwarz, auf jedem Punkt des Buttons 5,5:1 oder mehr. Die 17-%-Tinte bleibt der Rückfall, wo ein Browser es noch nicht kennt:
contrast-color() sieht nur die Primärfarbe an. Mit einer eigenen Fläche oder einem Verlauf, der deutlich dunkler endet, auch das andere Ende messen.
Fokusmarkierungen
Seit 1.40.0 zeigt jedes Bedienelement, wo die Tastatur steht, in einer deckenden Farbe: --gl-focus-ring. Drücke hier die Tab-Taste:
Buttons, Pills und der Theme-Schalter zeichnen sie als 2 px breite Outline mit 2 px Abstand, die Aktionen eines Modals innerhalb der Aktion, weil das Modal sie sonst abschneiden würde. Bis 1.39.0 hatten diese Teile gar keine Markierung. Alle anderen Teile nehmen den Ring aus --gl-shadow-focus oder --gl-border-focus, jetzt 2 px breit. Beide waren Tönungen der Primärfarbe und lagen unter den 3:1, die eine Fokusmarkierung gegen ihre Umgebung braucht (WCAG 1.4.11). Beide nehmen jetzt die deckende Farbe, und sie folgt der Marke:
GlassKits Orange erreicht 3:1 oder mehr auf der Seite und auf Glas. Wie hell Glas wird, entscheidet aber, was dahinter liegt, und eine dunklere Marke kann an der hellsten Stelle darunter bleiben: Glas auf einer Glow-Karte in der Seitenmitte, im Dark Mode. Eine eigene Farbe gehört in --gl-focus-ring: Halte sie deckend und miss sie dort. Ein Projekt, das --gl-border-focus oder --gl-shadow-focus selbst gesetzt hat, behält seinen Ring, bis es sie entfernt, und eine eigene Outline auf :focus-visible ist nicht mehr nötig.
In Forced Colors, dem Hochkontrastmodus von Windows, verwirft der Browser box-shadow und damit jeden Ring. Dort zeigt jedes Teil eine Outline in der Textfarbe, innerhalb der Zeilen von Listen, Akkordeons und Menüs, die abschneiden, was außerhalb liegt.
Rechts nach links
Seit 1.20.0 folgen die Komponenten der Schreibrichtung. dir="rtl" auf <html> oder einem beliebigen Container genügt: Abstände, Positionen und Rahmen sind logische Eigenschaften, also spiegeln sich Labels und Hinweise, das Such-Icon, die Trennlinien der Liste, die Popover-Anker, die Tab-Badges, die Modal-Aktionen, das × des Toasts und die Ausrichtung von Akkordeon, Liste, Tabelle und Prose. Wo zwei Werte gemeinsam wandern müssen — der Chevron des Selects und der Platz für ihn, der Knopf des Schalters und sein Weg, der Verlauf der Fortschrittsfüllung — steht die Regel unter :dir(rtl): Chrome und Edge ab 120, Safari ab 16.4, Firefox ab 49. Ein älterer Browser lässt diese Teile links nach rechts, statt sie auseinanderzureißen.
Druckdialoge lassen Hintergrundgrafiken standardmäßig weg, und manche Zustände sind nur mit einem Hintergrund gezeichnet. Seit 1.21.1 behalten diese Teile auf Papier ihre Farben — das angehakte Kästchen und sein Haken, das gewählte Radio, die Spur des Toggles, die Füllung des Fortschrittsbalkens, der aktuelle Schritt, der gewählte Tag von Datumsstreifen und Kalender, der Knopf des Schiebereglers und die Tonpunkte —, der Rest der Seite druckt sparsam. Einzustellen ist nichts. Eine dunkle Seite druckt ihre helle Schrift und ihre Flächen auf weißes Papier; eine Seite, die gedruckt werden soll, wechselt dafür ins helle Theme:
Dichte (Kompakt)
Admin-Oberflächen, Desktop-Layouts und schmale Formulare brauchen dichtere Bedienelemente. Seit 1.21.0 sind ihre Größen Dichte-Tokens, und data-density="compact" am <html>-Element setzt einen kleineren Satz: Felder und Buttons 40px hoch statt 52 und 56, kleinere Toggles, Checkboxen und Radios, dichtere Listenzeilen und Modal-Aktionen. Farben, Schrift und Abstände bleiben, wie sie sind. Ohne das Attribut behält jedes Element die Größe, die es immer hatte.
Die Vorschau setzt das Attribut auf ihre rechte Spalte. Auf einer Seite gehört es an <html>, neben data-theme: Ein Element weiter unten mit data-theme="dark" setzt die Standardgrößen wieder.
Einzug und Weg des Toggle-Knopfs — in beiden Schreibrichtungen — und die Ausrichtung von Toggle, Checkbox und Radio an der ersten Zeile leiten sich aus den Tokens ab. Jede Größe, die ein Projekt setzt, bleibt so ausgerichtet. Die Regeln lesen jede Größe mit dem bisherigen Wert als Fallback, wie --gl-modal-max-width: Eine Seite, deren Token-Sheet älter ist, behält die alten Größen.
Oberflächen (Solid, Tint)
Nicht jede Oberfläche soll Glas sein: Admin-Oberflächen, Formulare auf schlichtem Hintergrund, Designs ohne Glas. Seit 1.24.0 macht data-surface="solid" am <html>-Element jede Fläche deckend und schaltet Blur und Glanz ab. Jede Fläche nimmt die Farbe an, die das Glas über dem mittleren Hintergrund des Themes zeigt, --gl-color-bg-mid: Cards, Felder und Buttons behalten ihre Abstufung, und ein umgefärbter Hintergrund wirkt mit. Der innere Glanz (--gl-inset-*), das Licht an der Oberkante der Glow-Card und des Modals, der Schimmer auf dem Fortschrittsbalken und der Rand des Range-Knopfs sind aus. Ränder, Schlagschatten, die Tönungen von Badges und Chips und die abdunkelnde Überlagerung bleiben, wie sie sind. Ohne das Attribut ändert sich nichts.
Eine Seite mit eigenem Hintergrund — einer Markenfarbe, einem Foto, einem Muster — nimmt stattdessen data-surface="tint" (seit 1.25.0). Eine über --gl-color-bg-mid gemischte Fläche stünde dort als Fremdkörper, deshalb werden die Flächen im Fluss der Seite zu durchscheinenden Tönungen der Textfarbe, ohne Blur: Ein Feld auf einer Card bleibt so durchscheinend wie die Card, und sein Kontrast folgt dem Text. Was über anderem Inhalt liegt, behält die Solid-Werte — Modal, Sheet, Popover, Toast und die Tab-Bars samt der Felder und Zeilen darin —, ebenso der Secondary-Button, eine helle Fläche für dunkle Schrift. Blur und Glanz sind wie bei Solid aus; ein Blur hinter Dialogen bleibt, wo ein Projekt --gl-blur-overlay setzt.
Die Vorschau setzt das Attribut auf ihre zweite und dritte Card. Auf einer Seite gehört es an <html>, neben data-theme und data-density; ein Theme-Bereich weiter unten — ein Element mit eigenem data-theme — bleibt solid. Alles läuft über Tokens, ein Projekt passt das Preset also an wie ein Theme. GlassKit Elements trägt das Attribut in seine Shadow Roots, wie data-theme.
Auch der Glanz besteht jetzt aus Tokens: --gl-gloss-card, --gl-gloss-modal, --gl-gloss-progress und --gl-range-thumb-border (siehe Design Tokens). Vor 1.24.0 waren es feste Werte, die ein eigener Solid-Skin eines Projekts nicht erreichte.
Hintergrund
Der Glaseffekt braucht einen farbigen Hintergrund.
| Klasse | Beschreibung |
|---|---|
.glass-bg | Vollständiger Hintergrund mit Aurora-Lichteffekten |
.glass-bg--has-tab-bar | Modifier: Padding unten für Tab-Bar |
.glass-bg--has-tab-bar-floating | Modifier: Padding unten für Floating-Tab-Bar + Accessory |
Pill-Buttons
Runde Icon-Buttons für Navigation und Aktionen.
| Klasse | Beschreibung |
|---|---|
.glass-pill | Standard Glas-Kreis (46×46px) |
.glass-theme-toggle | Pill mit Mond/Sonne-Icon-Switch |
Tab-Bar
Fixierte Bottom-Navigation mit Glas-Hintergrund und optionalem Badge. Die Items sitzen in der Mitte der Leiste; auf einem iPhone mit viewport-fit=cover bleiben sie oben, über dem Home-Indikator (seit 1.28.0; vorher saßen sie überall oben, auf Android und am Desktop mit 26 px Leere darunter).
Icons und Tokens
Seit 1.28.0 färbt jeder Zustand die Icon-Box, und ein SVG zieht seine Linien in currentColor. Das Icon kann deshalb alles sein, was eine Farbe annimmt — ein Icon-Font wie Material Icons, ein als Maske gezeichnetes <img>, ein eigenes Element —, und es folgt aktivem Zustand und Hover, der Lupe des Tropfens und dem Ziehen. Ein Font-Icon übernimmt die 24 px der Box, solange seine eigene Klasse keine Größe setzt. Gib ihm aria-hidden="true": Sein Text würde sonst zum Namen des Tabs. Sechs Tokens, alle ungesetzt, also ändert sich nichts, bis ein Projekt sie setzt:
| Token | Ungesetzt | Wirkung |
|---|---|---|
--gl-tab-bar-color | --gl-icon-muted | Icon und Label der inaktiven Tabs |
--gl-tab-bar-hover-color | --gl-icon-default | Icon und Label eines Tabs unter dem Zeiger; mitsetzen, wenn die Farbe darüber heller ist |
--gl-tab-bar-label-size | 10px | Größe der Labels |
--gl-tab-bar-icon-size | 24px | Größe der Icon-Box und eines SVG darin (seit 1.33.0); eine kompakte Leiste nimmt 18 px |
--gl-tab-bar-active-weight | --gl-font-weight-medium | Schriftstärke des Labels am aktiven Tab (seit 1.33.0); ohne ihn ist jedes Label medium |
--gl-tab-bar-z-index | 900 | Stapelung der festen Leiste und des schwebenden Docks |
Seit 1.33.0 bewegen die Einträge nur, was ein Zustand ändert: Farbe, Fläche, Schatten, Deckkraft und das Drücken (transition-property: color, background-color, box-shadow, opacity, transform). Mit all glitten bei einer Leiste, die ihr Layout wechselte — aufrecht, schwebend, eine Rail —, Padding, Breite und Höhe 250 ms lang, und ein Eintrag, der in dieser Zeit gemessen wurde, hatte noch nicht seine Größe.
Ein Punkt ohne Zahl
Seit 1.38.0 sagt .glass-tab-bar__badge--dot „hier braucht es dich“ ohne Zahl — eine offene Zahlung am Konto-Tab: ein Punkt von 10 px an der Ecke des Icons im einfachen Fehlerrot, mit einem 2 px breiten Ring in der Farbe hinter der Leiste, der ihn vom Icon absetzt. In der Seitenleiste steht er am Ende der Zeile, wie die Zahl. Einem Screenreader sagt der Punkt nichts: Schreib den Grund in den Namen des Eintrags. Tokens setzen Zahl und Punkt gleichermaßen; die Seitenleiste behält ihren Platz am Ende der Zeile und nimmt Größe und Ring.
| Token | Ohne Wert | Wirkung |
|---|---|---|
--gl-tab-bar-badge-size | 16px | Höhe und Mindestbreite der Zahl; der Punkt ist 10 px, solange nichts gesetzt ist |
--gl-tab-bar-badge-top | -4px | Abstand zur Oberkante des Icons; der Punkt -2 px |
--gl-tab-bar-badge-end | -8px | Abstand zum Ende des Icons; der Punkt -3 px |
--gl-tab-bar-badge-ring-width | 0px | Ein Ring darum; der Punkt 2 px |
--gl-tab-bar-badge-ring-color | --gl-color-bg-mid | Die Farbe des Rings, der mittlere Seitenhintergrund |
Seitenleiste, Rail und obere Leiste
Seit 1.32.0 geht dieselbe Navigation dorthin, wo das Layout sie braucht, nicht nur an die untere Kante. Die Einträge bleiben, wie sie sind — Icon, Label, Badge, der aktive Zustand, der Tropfen —, nur das Layout der Leiste ändert sich. --vertical macht sie zur Spalte für eine Seitenleiste: platziert vom Layout der Seite, etwa einer Grid-Spalte, und so hoch wie ihr Container, ein Eintrag pro Zeile mit dem Icon vor dem Label in Fließtextgröße und dem Badge am Zeilenende. Die aktive Zeile steht auf einer eigenen Fläche, --gl-tab-bar-active-bg, wo das gesetzt ist, sonst --gl-surface-3. Mit --rail dazu zeigt die Spalte nur die Icons, --gl-tab-bar-rail-width (72 px) breit: Das Label bleibt der Name des Eintrags für assistive Technik, nur unsichtbar, also zeig es in einem Tooltip.
Mit --start oder --end ist die Spalte stattdessen an diese Kante des Viewports geheftet, über die volle Höhe und frei vom sicheren Bereich dieser Kante; Start und Ende folgen der Schreibrichtung. Das ist die Seite, die die Daumen auf einem großen Telefon im Querformat oder einem aufgeklappten Foldable erreichen, wo auch das System seine eigenen Bedienelemente an den Rand rückt. Die Seite lässt diesen Rand frei, so wie sie unten Platz für die Leiste dort lässt. Die Einträge bleiben, wenn das Layout wechselt; die Seite schaltet also nur die Klassen um — per Media Query oder nach Wahl der Nutzer:
--top legt eine waagerechte Leiste für den oberen Rand einer Seite an: im Fluss — in einen Sticky-Header setzen —, mit der Linie unten, ohne Platz für den Home-Indikator und ab einem Viewport von 640 px mit dem Icon neben dem Label.
Jede Leiste zeigt jetzt einen Ring für die Tastatur, --gl-shadow-focus am fokussierten Eintrag; bis 1.32.0 hatten die Einträge keinen. Ein Eintrag darf auch ein Link sein, <a class="glass-tab-bar__item" href="…">, sodass sich eine Ansicht auch in einem neuen Tab öffnen lässt; er sieht aus wie der Button. In GlassKit Elements sind die Layouts Attribute: <glk-tab-bar orientation="vertical"> mit rail (oder rail="labels") und dock="start" oder "end", und placement="top"; slot="leading" und "trailing" füllen die Plätze vor und nach den Einträgen.
| Klasse | Beschreibung |
|---|---|
.glass-tab-bar--vertical | Spalte für eine Seitenleiste, platziert vom Layout der Seite und so hoch wie ihr Container; scrollt selbst, wo die Einträge nicht passen |
.glass-tab-bar--rail | Mit --vertical: nur Icons, --gl-tab-bar-rail-width (72 px) breit, das Label unsichtbar, das Badge an der Ecke des Icons |
.glass-tab-bar--start, --end | Mit --vertical: an diese Kante des Viewports geheftet, volle Höhe, frei vom sicheren Bereich; von rechts nach links gespiegelt |
.glass-tab-bar--top | Waagerechte Leiste für den oberen Rand einer Seite, im Fluss, die Linie unten; ab 640 px das Icon neben dem Label |
a.glass-tab-bar__item | Ein Eintrag als Link, ohne Unterstreichung |
.glass-tab-bar--labels | Mit --rail: das Label unter dem Icon; die Einträge füllen die Breite der Rail und sind mindestens --gl-tab-bar-rail-item-height hoch, gerundet von --gl-tab-bar-item-radius (seit 1.33.0, siehe Eine Rail mit Labels) |
--floating mit --vertical und --rail | Eine Rail aus eigenem Glas: so hoch wie ihr Container, mit den Ecken einer Karte; mit --start oder --end dazu an dieser Kante des Viewports, volle Höhe abzüglich --gl-tab-bar-floating-inset an beiden Enden, so weit von ihrer Kante entfernt, frei von den sicheren Bereichen (seit 1.33.0) |
.glass-tab-bar__leading, __trailing | Plätze vor und nach den Einträgen: in einer Spalte darüber und darunter, der hintere am fernen Ende; in einer Zeile davor und danach (seit 1.33.0) |
.glass-tab-bar__accessory-item | Das Accessory über seinem Namen, .glass-tab-bar__accessory-label (seit 1.33.0) |
In der Spalte wird ein langes Label mit Auslassungspunkten gekürzt und endet vor dem Badge: Solange ein Badge zu sehen ist, hält die Zeile an ihrem Ende --gl-tab-bar-badge-room frei.
| Token | Ungesetzt | Wirkung |
|---|---|---|
--gl-tab-bar-rail-width | 72px | Breite der Rail |
--gl-tab-bar-badge-room | 32px | Platz, den eine Zeile der Seitenleiste an ihrem Ende freihält, solange sie ein Badge zeigt, damit das Label davor endet |
--gl-tab-bar-active-bg | --gl-surface-3 in einer Spalte | Die Fläche der aktiven Zeile; an der unteren Leiste heißt ungesetzt keine |
--gl-tab-bar-rail-item-height | 62px | Mindesthöhe eines Eintrags in einer Rail mit Labels (seit 1.33.0) |
--gl-tab-bar-item-radius | eine Kapsel; 16px in einer Rail mit Labels | Ecken der schwebenden Einträge, der Einträge einer Rail mit Labels und des Tropfens (seit 1.33.0) |
--gl-tab-bar-floating-inset | 16px | Abstand einer schwebenden Rail an einer Kante von dieser Kante und von den Enden des Viewports (seit 1.33.0) |
--gl-tab-bar-rail-radius | --gl-radius-card | Ecken einer schwebenden Rail, angedockt oder nicht (seit 1.33.0) |
Eine kompakte obere Leiste
Drei Tokens formen die Einträge seit 1.33.0, ohne dass sich GlassKits globale Tokens ändern: --gl-tab-bar-icon-size setzt die Größe der Icons, --gl-tab-bar-item-radius rundet den Tropfen und die schwebenden Einträge — ungesetzt eine Kapsel —, und --gl-tab-bar-active-weight setzt die Schriftstärke des aktiven Labels. Eine obere Leiste, die als kompakte Spur gezeichnet ist wie ein Segmented Control, nimmt dessen 18 px große Icons und 12 px Ecken:
Eine Rail mit Labels
Seit 1.33.0 behält --labels neben --rail das Label unter dem Icon, wie auf der Floating-Bar: eine Rail für den Desktop, die ihre Einträge benennt. Die Einträge füllen die Breite der Rail, --gl-tab-bar-rail-width, und sind mindestens --gl-tab-bar-rail-item-height (62 px) hoch; --gl-tab-bar-item-radius rundet sie und den Tropfen, ungesetzt 16 px, die Ecken eines Buttons. Ein langes Label endet mit Auslassungspunkten, und das Badge bleibt an der Ecke des Icons.
__leading und __trailing sind Plätze in der Leiste vor und nach den Einträgen: in einer Spalte darüber — ein Logo, das Accessory — und an ihrem fernen Ende — ein Fuß wie das Konto; in einer Zeile davor und danach. .glass-tab-bar__accessory-item stellt das Accessory über seinen Namen, __accessory-label. Der Name ist auch das aria-label des Buttons, deshalb ist der sichtbare aria-hidden, und ein Klick darauf sollte den Button drücken.
Mit --floating ist die Rail eine Fläche aus eigenem Glas, angedockt oder nicht: so hoch wie ihr Container, mit den Ecken einer Karte, --gl-tab-bar-rail-radius, und Raum um ihre Einträge — im Fluss eine Rasterspalte der Seite, wie in der Vorschau. Mit --start oder --end dazu steht sie stattdessen an dieser Kante des Viewports: so hoch wie der Viewport abzüglich --gl-tab-bar-floating-inset (16 px) an beiden Enden, so weit von ihrer Kante entfernt, frei von den sicheren Bereichen und von rechts nach links gespiegelt. Die kompakte aufrechte Pille des senkrechten Docks, ohne --rail, bleibt eine Kapsel.
In GlassKit Elements ist die Rail <glk-tab-bar floating orientation="vertical" dock="start" rail="labels">, mit dem Logo und einem <glk-tab-accessory show-label> in slot="leading" und dem Fuß in slot="trailing".
Tab-Bar – Floating
Pillenförmige, zentrierte, schwebende Variante im iOS-26-Liquid-Glass-Stil. Optional mit einer eigenständigen .glass-tab-bar__accessory-Kapsel daneben (z. B. Suche, Erstellen) – mit eigenem Glasmaterial. Der aktive Tab erhält einen weichen radialen Spotlight-Halo statt des Punkt-Underlines, in --gl-tab-bar-spotlight-color (der Primärfarbe). Icon und Label nehmen --gl-tab-bar-active-color, wo das gesetzt ist, sonst --gl-color-primary-text (seit 1.26.0, siehe Primärfarbe als Text).
Akzent-Varianten für das Accessory
Mit --accent, --success oder --error wird das Accessory farbig untermalt (gefüllter Hintergrund, weißes Icon). Seit 1.28.0 sitzt die Icon-Farbe am Button: Ein Font-Icon im Accessory folgt Hover und Varianten wie ein SVG, und jede Variante behält ihre Icon-Farbe auch unter dem Zeiger.
| Klasse | Beschreibung |
|---|---|
.glass-tab-bar-dock | Wrapper: fest unten zentriert, hält Tab-Bar + Accessory |
.glass-tab-bar-dock--accessory-left | Modifier: Accessory links statt rechts |
.glass-tab-bar--floating | Modifier auf .glass-tab-bar: Pillenform, max-content-Breite |
.glass-tab-bar__accessory | Eigenständige Glas-Kapsel neben der Tab-Bar |
.glass-tab-bar__accessory--accent | Gefüllt mit Primärfarbe |
.glass-tab-bar__accessory--success | Gefüllt mit Success-Farbe |
.glass-tab-bar__accessory--error | Gefüllt mit Error-Farbe |
.glass-bg--has-tab-bar-floating | Background-Padding-Helper für die Floating-Variante |
.glass-tab-bar--droplet | Modifier: Der aktive Eintrag sitzt auf einem Glastropfen, der zum nächsten gleitet (seit 1.27.0, siehe Droplet) |
.glass-tab-bar-dock--vertical | Modifier: das Dock aufrecht am Endrand, senkrecht zentriert; die Bar darin bekommt --vertical (seit 1.32.0) |
.glass-tab-bar-dock--start | Mit --vertical: stattdessen am Startrand |
Aufrecht an der Seite
Seit 1.32.0 steht die Floating-Bar auch aufrecht an einer Seite, dort, wo ein Daumen auf einem quer gehaltenen Telefon liegt. .glass-tab-bar-dock--vertical am Dock und --vertical an der Bar stapeln die Einträge so, wie sie an der unteren Kante stehen, Icon über Label, mit dem Accessory darunter (darüber mit --accessory-left), senkrecht zentriert am Endrand; .glass-tab-bar-dock--start rückt es an den anderen. Beide halten den sicheren Bereich frei und folgen der Schreibrichtung. Mit --droplet läuft der Tropfen auf und ab:
Fläche des aktiven Eintrags
Seit 1.27.0 kann der aktive Eintrag auf einer eigenen Fläche stehen, wie der gewählte Tab in iOS 26. Vier Tokens, alle ungesetzt, es ändert sich also nichts, bis ein Projekt sie setzt: --gl-tab-bar-active-bg und --gl-tab-bar-active-shadow legen eine Kapsel hinter den aktiven Eintrag, --gl-tab-bar-spotlight-opacity: 0 schaltet das Spotlight der Floating-Bar ab und --gl-tab-bar-active-glow: none das Leuchten am Icon, das auf einer hellen Kapsel wie eine Unschärfe wirkt.
Eine fast deckende weiße Kapsel, rgba(255, 255, 255, 0.9), lässt eine dunkle Markenfarbe auch im dunklen Theme die Farbe des aktiven Tabs bleiben, wo sie auf dem Spotlight unlesbar wäre. Die Kapsel ist der Hintergrund des Eintrags und deshalb gerundet wie er: eine Pille auf der Floating-Bar, 12px auf der festen. Seit 1.33.0 rundet --gl-tab-bar-item-radius die schwebenden Einträge und den Tropfen gemeinsam, ungesetzt eine Kapsel: abgerundete Quadrate in einer Rail, die 12 px eines Segmented Controls in einer kompakten oberen Leiste.
Droplet
Seit 1.27.0 macht .glass-tab-bar--droplet die Auswahl flüssig. Der aktive Eintrag sitzt auf einem Glastropfen, der ein wenig über der Bar schwebt. Ein Tipp auf einen anderen Tab schickt den Tropfen dorthin wie Wasser über eine Scheibe: Die Vorderkante läuft voraus, die Hinterkante folgt, unterwegs wird der Tropfen flacher, am Ziel wippt er kurz nach, und die Icons, über die er läuft, wachsen wie unter einer Lupe. Ein Finger kann ihn auch über die Bar ziehen; beim Loslassen wird der Tab darunter gewählt. Für eine App mit Floating-Bar ist das die deutlichste Aufwertung, die sie übernehmen kann, und sie ändert sonst nichts: Das Markup bleibt, und wo das Skript nicht läuft, behält die Bar ihr Spotlight. Probier es:
Den Tropfen zeichnet das Stylesheet. Die Bewegung kommt aus glasskit-droplet.js, einem optionalen Modul im selben Paket ohne Abhängigkeiten, etwa 4 KB minifiziert und unter 2 KB komprimiert. Es folgt .is-active, das die Seite wie gewohnt selbst setzt, und klickt den Tab an, auf dem ein Ziehen endet; die Wahl trifft also der Klick-Handler der Seite:
Der Tropfen nimmt die Fläche des aktiven Eintrags, wo ein Projekt eine gesetzt hat (--gl-tab-bar-active-bg, -shadow), sonst ein eigenes helles Glas; sein Glanz ist --gl-gloss-droplet. data-surface="solid" und "tint" machen ihn deckend wie jede andere Fläche, und mit prefers-reduced-motion springt er, statt zu gleiten. Eine Transformation an einem Vorfahren — eine App, die beim Start hineinzoomt, ein Popover, das aus scale(0.96) aufgeht — lässt ihn auf seinem Eintrag, in Ruhe und während sie läuft (seit 1.28.0). Segmentwahlen bekommen denselben Tropfen. In GlassKit Elements ist es ein Attribut: <glk-tab-bar floating droplet>.
In einer Spalte — einer Seitenleiste, der aufrechten Floating-Bar — läuft der Tropfen entlang y (seit 1.32.0). Das Skript liest die flex-direction der Reihe oder ihr aria-orientation="vertical", setzt data-droplet-axis="y" und die Richtungen "down" und "up", und ein Finger zieht den Tropfen auf und ab, während ein Wischen zur Seite beim Browser bleibt. Eine waagerechte Leiste oben auf einer Seite, statisch oder schwebend, lässt ihn laufen wie die untere. Probier die Seitenleiste:
Timing des Tropfens
Seit 1.32.0 ist die Bewegung Tokens, die das Stylesheet und glasskit-droplet.js gleichermaßen lesen. Sie werden vererbt und erreichen so auch <glk-tab-bar droplet> und <glk-segmented droplet> in GlassKit Elements. Ungesetzt lassen sie den Tropfen, wie er war: Er kommt etwa 830 ms nach einem Tipp zur Ruhe.
| Token | Ungesetzt | Wirkung |
|---|---|---|
--gl-droplet-duration | 0.3s | Die Vorderkante und die Kanten quer zum Weg |
--gl-droplet-easing | cubic-bezier(0.3, 1.2, 0.5, 1) | Ihre Kurve |
--gl-droplet-trail-duration | 0.5s | Die Hinterkante, die ihr nachgezogen wird |
--gl-droplet-trail-delay | 40ms | Wie lange die Hinterkante wartet |
--gl-droplet-trail-easing | cubic-bezier(0.5, 1.5, 0.45, 0.92) | Ihre Kurve, mit dem Überschwingen |
--gl-droplet-lift | 0.86 | Wie flach der Tropfen unterwegs läuft; 1 staucht nichts |
--gl-droplet-lift-duration | 280ms | Wie lange er flach läuft |
--gl-droplet-settle-duration | 0.55s | Das Zurückfedern in die Form |
--gl-droplet-settle-easing | cubic-bezier(0.34, 1.8, 0.5, 1) | Seine Kurve, das Wippen am Ende |
--gl-droplet-lens-duration | 0.4s | Der Eintrag unter dem Tropfen, der wie unter einer Lupe wächst |
--gl-droplet-lens-easing | cubic-bezier(0.34, 1.6, 0.5, 1) | Seine Kurve |
Ein Produkt, das seine Bewegungen bei 240 ms ease-out hält, lässt den Tropfen in 240 ms ankommen, ohne Nachlauf, in der Tab-Bar wie in der Segmentwahl. Mit der Dauer des Anhebens bei 0ms vertieft der Tropfen unterwegs auch seinen Schatten nicht, der sich sonst erst nach etwa 600 ms wieder legt:
Ein Finger, der den Tropfen zieht, behält sein eigenes kurzes Timing, und mit prefers-reduced-motion springt der Tropfen weiterhin, statt zu gleiten.
Breadcrumbs
Der Pfad durch verschachtelte Ebenen (seit 1.32.0): Meine App › Hauptmenü › Leistungen › Online-Buchung. Ein <nav aria-label="Breadcrumb"> um eine <ol>; jede Krume ist ein Link oder ein Button, die aktuelle Ebene schlichter Text mit aria-current="page". Die Trenner zeichnet CSS, assistive Technik liest sie also nicht vor, und von rechts nach links drehen sie sich um. Eine Krume, die länger ist als --gl-breadcrumbs-crumb-width (200 px), wird mit Auslassungspunkten gekürzt, und wo der Platz in der Zeile ausgeht, gibt jede Krume nach.
Wo der Pfad nicht passt, steht __overflow für die mittleren Ebenen: ein Button mit einem Namen wie „2 weitere Ebenen“, der sie in einem Menü auflistet, während die erste Krume und die letzten beiden stehen bleiben. Sein <li> trägt __item--overflow und behält seine Breite, wo die Krumen ringsum nachgeben. <glk-breadcrumbs> aus GlassKit Elements faltet sie selbst ein und aus, gemessen an der eigenen Breite, und zeigt ein gekürztes Label vollständig in einem Tooltip.
Eine Krume kann auch ein gezogenes Element in ihre Ebene aufnehmen, für eine sortierbare Liste oder einen Baum: .is-drop-target hebt sie hervor, solange das Element über ihr ist, .is-drop-refused zeigt, dass die Ebene es nicht annimmt.
| Klasse | Beschreibung |
|---|---|
.glass-breadcrumbs | Am <nav>; gibt in einer engen Zeile nach (min-width: 0) |
__list | Die <ol>: eine Zeile, die nicht umbricht |
__item | Das <li>; ab dem zweiten mit einem Chevron davor, von rechts nach links gespiegelt |
__crumb | Link oder Button zu einer Ebene, gedämpft, jenseits von --gl-breadcrumbs-crumb-width (200 px) mit Auslassungspunkten gekürzt |
__current | Die aktuelle Ebene, schlichter Text mit aria-current="page", in der Überschriftenfarbe |
__overflow | Mit __crumb: der „…“-Button, der für die eingeklappten Ebenen steht |
__item--overflow | Am <li> dieses Buttons: behält seine Breite, während die anderen Krumen nachgeben |
.is-drop-target, .is-drop-refused | An einer Krume, solange ein gezogenes Element über ihr ist: Sie nimmt es an oder nicht |
Titel
Verträge aufnehmen
& hochladen
Card
Vertrag fotografieren, Kanten prüfen und gesammelt hochladen.
| Klasse | Beschreibung |
|---|---|
.glass-card | Basis-Glasfläche |
.glass-card--glow | Hell → milchig Verlauf + Lichtstreifen |
.glass-card__icon | Zentrierter Icon-Wrapper |
.glass-card__text | Beschreibungstext |
Buttons
| Klasse | Beschreibung |
|---|---|
.glass-btn | Basis (56px, volle Breite) |
--primary | Farbiger Gradient |
--secondary | Milchig-weiß |
--tertiary | Subtiles Glas |
--sm | 44px Höhe |
--lg | 64px Höhe |
--auto | Auto-Breite |
:disabled, [aria-disabled="true"] | Gedimmt auf 0,45, Cursor not-allowed, kein Hover (seit 1.21.2) |
svg.glass-icon--fill | Bewusst gefülltes Icon (z. B. Brand-Logos) |
Auf dem Glas eines Modals oder eines Sheets ist ein tertiärer Button im dunklen Modus eine Stufe dunkler, --gl-dialog-control, und nimmt keinen eigenen Blur (seit 1.35.0): Seine gedämpfte Beschriftung las dort 3 bis 4:1.
Ein deaktivierter Button — disabled, oder aria-disabled="true" an einem a.glass-btn, der sich nicht deaktivieren lässt — ist gedimmt, zeigt den Cursor not-allowed und hebt sich beim Hover nicht mehr an (seit 1.21.2; vorher sah er genau aus wie ein aktiver). Der Link selbst navigiert weiter, wenn die Seite ihn nicht abfängt. Dasselbe gilt für Pill, Tab-Bar-Accessory, Modal-Aktionen, interaktive Listenzeilen und die Monatspfeile des Kalenders; Toggle, Checkbox und Radio dimmen Bedienelement und Label, Select, Textarea und Range dimmen wie das Input.
Buttons haben seit 1.31.0 eigene Haken. --gl-btn-radius rundet sie, ungesetzt --gl-radius-btn, das sich Listen, Statuskarte, Toasts, Akkordeon und Segmentwahl teilen: --gl-btn-radius: 9999px auf :root ergibt Buttons in Pillenform und lässt die anderen, wie sie sind. --gl-btn-padding-x ist der Raum neben der Beschriftung, ungesetzt 24 px, der Innenabstand, den bisher nur --auto hatte; jeder andere Button hatte die 6 px des Browsers, sodass ein kleiner, der seine Breite aus dem Text nahm, in einer Reihe von Aktionen den Text mit seinen Kanten berührte. --sm liest zuerst --gl-btn-radius-sm und --gl-btn-padding-x-sm, dann die Haken darüber, und behält seinen Radius von 12 px, solange keiner gesetzt ist; so formt ein Wert jede Größe.
Seit 1.32.0 ersetzt --gl-btn-primary-bg den ganzen Hintergrund von --primary, so wie Schalter und Radio ihre eigenen haben; ungesetzt ist es der Verlauf von --gl-color-primary über -mid zu -dark. Ein Produkt, das bei weißer Schrift bleibt, lässt den Verlauf so dunkler beginnen und die Markenfarbe in Ruhe; das Rezept steht unter Primärfarbe als Text.
Badge
Varianten: --primary, --success, --warning (seit 1.18.0) und --error. Jede nimmt Fläche, Rand und Schrift aus den Token -surface, -border und -on-surface ihrer Statusfarbe — wer die Statusfarbe umfärbt, färbt das ganze Badge um.
Chips
Ein Badge dient auch als Filter-Chip. --interactive macht ihn anfassbar — Zeiger, Hover-Tönung, Fokusring — und --selected zeigt, welcher Chip aktiv ist. Nimm einen echten <button> und leg den Zustand in aria-pressed, damit die Zeile per Tastatur bedienbar ist und als Umschalter angesagt wird.
--selected vertieft die Farbe, die der Badge schon hat, statt sie zu übergehen — ein Status-Chip bleibt beim Auswählen also in seiner eigenen Farbe.
Im dunklen Modus sagt ein gewählter Badge seine Beschriftung in der Textfarbe (seit 1.35.0): Der für dunkle Flächen aufgehellte Akzent las auf einem Chip über Glas 2,2 bis 3:1. Rand und Tönung zeigen die Auswahl; --gl-badge-selected-color setzt die Farbe der Beschriftung. Auf dem Glas eines Modals oder eines Sheets nimmt ein Badge keinen eigenen Blur: Der Dialog weichzeichnet schon, und Chromium zählte seinen Schimmer unter einem verschachtelten Backdrop-Filter doppelt, sodass ein Chip für Weiß auf 2,9:1 kam.
| Klasse | Beschreibung |
|---|---|
--interactive | Anklickbar: Zeiger, Hover-Tönung, Fokusring, Druck-Rückmeldung |
--selected | Der aktive Chip — vertieft die eigene Farbe des Badges |
--gl-badge-accent | Die Farbe, die beide Zustände vertiefen. Pro Badge setzbar, wenn ein Chip eine eigene Farbe bekommen soll. |
Auswahl-Chips
Seit 1.33.0 macht --md einen Chip zum Auswählen, wie in der Zeile der Branchen eines Anmeldeformulars: --gl-badge-md-height (36 px) hoch, in der kleinen Schrift eines Formulars. Mit --interactive nimmt er Berührungen auf 44 px an, 4 px über und unter seinen Kanten, die Zielgröße, die die anderen Bedienelemente einhalten. In einer umbrechenden Zeile mindestens 8 px zwischen den Zeilen lassen, damit sich die Ziele treffen und nicht überlappen.
| Klasse / Token | Beschreibung |
|---|---|
--md | Ein Chip zum Auswählen: 36 px hoch, die kleine Schrift eines Formulars; interaktiv ein Berührungsziel von 44 px |
--gl-badge-md-height | Seine Höhe, ungesetzt 36px; das Berührungsziel wächst um ihn herum auf 44 px |
In GlassKit Elements: <glk-badge interactive size="md">.
Avatar
Seit 1.37.0 setzt --gl-avatar-size jede Größe, am Avatar oder an einem Container drumherum, und --gl-avatar-font-size dazu die Größe der Initialen. In der Leading-Box einer Listen-Zeile nimmt ein Avatar die Größe der Box an, 28 px, und 40 px in --lg, den Avatar einer Kontaktliste: 44 px schnitt die Box ab, 32 px wirkten darin verloren. Der Token am Avatar selbst entscheidet weiter.
Divider
Status-Hinweis
Noch keine Verträge vorhanden.
--gl-status-color setzt die Farbe der Nachricht (seit 1.35.0), ohne Wert gedämpfter Text. Ein Wort darin in <b>, etwa ein Paketname, bekommt die Textfarbe über eine Regel der Seite. Seit 1.36.0 hat die Nachricht keinen eigenen Außenabstand. Das 1em des Browsers darüber und darunter machte die Karte 82 px statt 54 px hoch, wo kein Reset der Seite das <p> erreichte: auf einer Seite ohne Reset, im Shadow Root von <glk-status>.
Liste
Gruppierter Settings-Container für gestapelte Zeilen. Items unterstützen ein führendes Icon, Titel + optionalen Untertitel sowie ein Trailing-Element (Chevron, Wert, Button). Trennlinien zwischen Items werden automatisch gezeichnet — kein zusätzliches Markup nötig.
Settings-Stil (Icon + Titel + Untertitel + Trailing)
-
iOS 26.4 Update2,1 GB · Jetzt verfügbar
-
Apple OneFamilie — verlängert sich am 28. Apr.22,95 €
-
Mitteilungen
- Alle Abos anzeigen
Kompaktes Menü (zentrierter Text, ohne Icons)
- Vertrag teilen
- Duplizieren
- Löschen
Gruppierte Sektionen mit großen Icons
-
Geladene Medien prüfenSpare bis zu 1,38 GB ein. Prüfe alle auf deinem Gerät geladenen Videos und Audiodateien und entferne sie bei Bedarf.
-
AusweisApp BundVersion 2.5.124 MB
-
Der Geist aus der MaschineTeilweise angesehen237,1 MB
- Alle Downloads anzeigen
Klassen-Referenz
| Klasse | Beschreibung |
|---|---|
.glass-list | Gruppierter Surface-Container |
.glass-list--flush | Edge-to-Edge-Variante (kein seitlicher Rand / Radius): reicht bis an beide Kanten ihres Containers, hinausgezogen um --gl-list-flush-inset — in Card und Modal-Inhalt deren Innenabstand, sonst 20 px (seit 1.29.1) |
.glass-list--bare | Entfernt Hintergrund, Border & Shadow — für die Einbettung in .glass-popover oder .glass-card. |
.glass-list__item | Listenzeile (als <li>, <a> oder <button>) |
.glass-list__section-header | Sektionslabel oberhalb einer .glass-list — Uppercase, klein, gedämpft |
.glass-list__item--interactive | Fügt Hover- / Focus- / Active-States hinzu; für die Tastatur ein 2 px breiter Ring in --gl-border-focus innerhalb der Zeile (seit 1.32.0; vorher zeigte nur eine Tönung den Fokus) |
.glass-list__item--center | Zentrierte Single-Text-Variante mit Ellipsis-Truncation |
.glass-list__item--danger | Roter Text für destruktive Aktionen |
.glass-list__item--accent | Primärfarbener Text für Akzent-Aktionen |
.glass-list__leading | Leading-Slot (28×28, enthält ein Icon-SVG); --gl-list-leading-width verbreitert ihn (seit 1.36.0, unten) |
.glass-list__leading--lg | Großer Leading-Slot (40×40, abgerundetes Quadrat, unterstützt <img>); derselbe Token verbreitert ihn |
.glass-list__content | Flexibler mittlerer Slot — nimmt verbleibende Breite, ermöglicht Truncation |
.glass-list__title | Primärer Text (medium weight, eine Zeile mit Ellipsis, außer --gl-list-title-white-space lässt ihn umbrechen) |
.glass-list__subtitle | Sekundärer Text (klein, gedämpft, eine Zeile mit Ellipsis, außer --gl-list-subtitle-white-space lässt ihn umbrechen) |
.glass-list__title-row | Hält den Titel und __title-trailing — einen Badge, eine Marke —, das unter den Titel rückt, wo die Zeile zu schmal ist (seit 1.35.0) |
.glass-list__extra | Unter dem Untertitel: ein Link, eine Reihe Chips (seit 1.35.0) |
.glass-list__subtitle--wrap | Mehrzeiliger Subtitle (bis 3 Zeilen, mit Ellipsis-Clamp; --gl-list-subtitle-lines setzt die Grenze) |
.glass-list__trailing | Trailing-Slot — Chevron, Wert, Button, Badge |
.glass-list__value | Gedämpfter Text in .glass-list__trailing (z.B. Dateigröße) |
.glass-list__item.is-flash | Leuchtet einmal auf, 1,2 s in --gl-flash-color, für ein Element, das sich anderswo geändert hat (seit 1.32.0) |
.glass-list__item.is-selected | Die gewählte Zeile einer Liste neben ihrem Detail: eine Pille aus erhabenem Glas in der Zeile, --gl-list-item-selected-bg (ohne Wert --gl-surface-4), der Titel halbfett, das Icon im Akzent; mit aria-current="true" (seit 1.34.0, unten) |
Trennlinien zwischen Zeilen werden automatisch via ::after gerendert. Items mit Leading-Icon erhalten einen icon-aligned Inset; Items ohne — kein __leading, oder eines mit dem Attribut hidden (seit 1.20.0) — bekommen das normale Padding-Inset. Ein verstecktes __leading oder __trailing nimmt keinen Platz ein. Das letzte Item hat nie eine Trennlinie. SVG-Icon-Konvention: 24px für Leading, 18px für Trailing, stroke: currentColor, stroke-width: 2.
Seit 1.32.0 kann ein Element, das sich anderswo geändert hat — auf einem anderen Gerät, durch ein Rückgängig —, einmal aufleuchten, damit das Auge es zwischen den anderen findet: .is-flash tönt es 1,2 s lang in --gl-flash-color, ungesetzt 30 % der Primärfarbe, und unter prefers-reduced-motion leuchtet nichts. Die Klasse bei animationend wieder entfernen, damit die nächste Änderung erneut aufleuchtet.
Bündig
--flush führt die Liste von Kante zu Kante ihres Containers, ohne seitlichen Rand und Radius. Die Liste wächst auf beiden Seiten um den Innenabstand des Containers, --gl-list-flush-inset: .glass-card und .glass-modal__body setzen ihn auf ihren eigenen Innenabstand, anderswo sind es 20 px (--gl-space-lg), solange der Container ihn nicht setzt. Seit 1.29.1 — vorher behielt die Liste ihre Breite und rückte nur zum Anfang.
Umbrechender Text
Titel und Subtitle bleiben einzeilig und werden mit Ellipsis gekürzt, --wrap begrenzt den Subtitle auf drei Zeilen. Seit 1.23.0 entscheidet ein Projekt das einmal anders, auf :root, oder für eine Liste oder eine Zeile: --gl-list-title-white-space und --gl-list-subtitle-white-space nehmen nowrap (Standard) oder normal, und --gl-list-subtitle-lines setzt die Grenze von --wrap — 3, wenn nicht gesetzt, none zeigt alle Zeilen. Die Tokens werden vererbt und erreichen so auch <glk-list-item> aus GlassKit Elements. Ein Wort, das breiter ist als die Spalte, etwa eine E-Mail-Adresse, bricht dort, wo es muss, statt aus der Zeile zu laufen; Text bricht weiter an Leerzeichen. Für Trennung nach Silben hyphens auf der Liste oder der Seite setzen: Es wird ebenfalls vererbt und folgt dem lang der Seite.
Platz neben dem Titel
Eine Zeile darf mehr sagen als einen Titel (seit 1.35.0). .glass-list__title-row hält den Titel und daneben __title-trailing — einen Badge wie „KI“, eine Marke —, das unter den Titel rückt, wo die Zeile zu schmal ist, während der Titel seine Auslassungspunkte behält. __extra unter dem Untertitel nimmt einen Link („Rückgängig“) oder eine Reihe Chips auf. --gl-list-title-size, --gl-list-title-weight und --gl-list-subtitle-size setzen die Schrift einer Zeile, an der Liste oder an einer Zeile.
- NeuigkeitenGestern geändert
Seit 1.36.0 verbreitert --gl-list-leading-width den Platz __leading für mehr als ein Icon — eine Uhrzeit und einen Chip vor dem Text einer Verlaufszeile. Die Box war 28 px breit, mit --lg 40 px, das abschneidet, was nicht passt. Die Trennlinie folgt dem Token. Er nimmt eine Länge; für eine anders aufgebaute Box sagt --gl-list-item-divider-inset, wo die Linie beginnt.
- 09:41Öffnungszeiten: Samstag 7:00 bis 14:00Öffnungszeiten · Lena Hoffmann
- 08:15Neuigkeiten: SommerfestNeuigkeiten · Jonas Weber
Die gewählte Zeile
Eine kompakte Liste neben einem Editor markiert den Eintrag, der offen ist (seit 1.34.0): .is-selected an der Zeile legt eine Pille aus erhabenem Glas hinein, wie sie die gewählte Baumzeile und die aktive Zeile einer Seitenleiste haben, mit halbfettem Titel und dem Icon im Akzent. aria-current="true" sagt Hilfstechnik, welcher Eintrag es ist — aria-selected stattdessen, wo die Liste eine Listbox ist. Hover und Druck lassen die gewählte Zeile, wie sie ist, und der Tastaturring bleibt um sie herum. --gl-list-item-selected-bg setzt die Fläche der Pille, ohne Wert --gl-surface-4.
Seit 1.35.0 formen Tokens die gewählte Zeile anders: --gl-list-item-selected-inset (3 px --gl-space-xs), -radius (--gl-radius-sm), -shadow (Kantenlicht und der Schatten eines Buttons), -color (die Überschriftenfarbe) und -weight (halbfett). 0, 0 und none für Abstand, Radius und Schatten ergeben eine flache Tönung über die ganze Zeile. Seit 1.36.0 nimmt der Titel die Farbe der Zeile an, die Überschriftenfarbe oder -color; vorher behielt er seine eigene Textfarbe, und -color änderte an ihm nichts.
- Start
- ÖffnungszeitenIm Editor geöffnet
- Neuigkeiten
Die Trennlinie beginnt unter dem Text: nach dem führenden Icon, ohne eines am Innenabstand der Zeile. --gl-list-item-divider-inset (seit 1.34.0) setzt ihren Anfang für Zeilen, die anders aufgebaut sind. Eine Zeile mit einem Griff vor ihrem Icon lässt die Linie an ihrem Innenabstand beginnen, weil die Breite des Griffs Sache der Seite ist, bis das Token sagt, wo der Text beginnt.
- NeuigkeitenBaustein
- ÖffnungszeitenBaustein
- TeamBaustein
Baum
Ebenen, die auf- und zugehen (seit 1.32.0): die Struktur einer App, Menüs mit Untermenüs, Ordner. Eine Zeile pro Eintrag — ein Pfeil, der sich dreht, wenn der Eintrag aufgeht, ein Icon, das Label, etwas am Ende wie ein Badge —, eingerückt um --gl-tree-indent (20 px) pro Ebene; die Ebene ist --gl-tree-level an der Zeile. Die Kinder des Eintrags folgen in einer __group. Der Baum hat keine eigene Fläche: in eine Card oder eine Seitenleiste setzen.
-
-
-
Start
-
Leistungen
-
Über uns
- Team
-
-
Galerie Nicht geladen
-
Die Rollen sind die des WAI-ARIA-Tree-Views: role="tree" mit einem Namen an der Liste, "treeitem" an jedem Eintrag mit aria-level, aria-expanded an den Einträgen mit Kindern und aria-selected, "group" an jeder __group; hidden an einer geschlossenen. Die Zustände sind Klassen an der Zeile. Der Baum ist ein einziger Tab-Stopp: Die Pfeiltasten wandern zwischen den Einträgen — runter und hoch, rechts öffnet einen Eintrag oder geht zu seinem ersten Kind, links schließt ihn oder geht zum übergeordneten Eintrag —, und die Zeile des Eintrags mit dem Fokus bekommt .is-focus-visible, oder :focus-visible, wo die Zeile selbst den Fokus hat. Diese Tastatur bringt <glk-tree> aus GlassKit Elements mit, von rechts nach links gespiegelt wie hier der Pfeil, mit Events, bevor ein Eintrag aufgeht, zugeht oder gewählt wird, und mit Kindern, die geladen werden, wenn ein Eintrag zum ersten Mal aufgeht.
Zwei Zustände kommen von außerhalb des Baums. .is-error markiert einen Eintrag, dessen Kinder nicht laden konnten: Der Pfeil wird zu einem „!“ in der Fehlerfarbe, und erneutes Öffnen versucht es noch einmal; GlassKit Elements setzt ihn mit load-error. .is-flash lässt eine Zeile 1,2 s lang aufleuchten, wenn sie sich anderswo geändert hat — auf einem anderen Gerät, durch ein Rückgängig —, damit das Auge sie zwischen den anderen findet; --gl-flash-color tönt sie, ungesetzt 30 % der Primärfarbe, und unter prefers-reduced-motion leuchtet nichts. Die Klasse bei animationend wieder entfernen, damit die nächste Änderung erneut aufleuchtet:
| Klasse | Beschreibung |
|---|---|
.glass-tree | Die Liste; ohne eigene Fläche |
__row | Die Zeile eines Eintrags, --gl-tree-row-height (36 px) hoch, eingerückt um --gl-tree-indent (20 px) für jede Ebene von --gl-tree-level nach der ersten |
__twisty | Der Pfeil; dreht sich mit .is-expanded, verschwindet mit .is-leaf und behält seinen Platz, von rechts nach links gespiegelt |
__icon | Das Icon vor dem Label, --gl-tree-icon-size (18 px) im Quadrat, sein SVG ebenso (seit 1.34.0) — 28px für einen getönten Chip, wie ihn Listenzeilen zeigen; ein leeres nimmt keinen Platz ein |
__label | Das Label, einzeilig mit Auslassungspunkten |
__trailing | Am Zeilenende: ein Badge, ein Status, eine Aktion |
__group | Die Kinder des Eintrags unter seiner Zeile; hidden, solange er zu ist |
.is-expanded, .is-leaf | An der Zeile: offen oder ohne Kinder |
.is-selected | Die gewählte Zeile: angehobenes Glas wie die aktive Zeile einer Seitenleiste, halbfett, ihr Icon in der Akzentfarbe |
.is-loading | Kinder unterwegs: Der Pfeil wird zu einem kleinen Spinner (mit aria-busy="true" am Eintrag) |
.is-error | Die Kinder konnten nicht laden: Der Pfeil wird zu einem „!“ in der Fehlerfarbe; erneutes Öffnen versucht es noch einmal |
.is-flash | Ein Aufleuchten von 1,2 s in --gl-flash-color (ungesetzt 30 % der Primärfarbe) an einer Zeile, die sich anderswo geändert hat; keines unter prefers-reduced-motion |
.is-disabled | Gedimmt, Cursor not-allowed |
.is-focus-visible | Der Tastaturring innerhalb der Zeile, für ein Skript, das den Fokus bewegt |
Sortieren
Die Zustände eines Ziehens, das eine Liste oder einen Baum neu ordnet (seit 1.32.0). Das gezogene Element bleibt verblasst an seinem Platz (.is-sort-source), während eine angehobene Kopie, .glass-sort__ghost, dem Zeiger im Top Layer folgt. Eine Linie zeigt, wo das Element landet, vor oder hinter einem anderen (.is-sort-before, .is-sort-after an diesem), im Baum eingerückt auf die Ebene, auf der es landet; ein Eintrag, der es aufnimmt, leuchtet auf (.is-sort-inside), und einer, der es ablehnt, zeigt die Fehlerfarbe (.is-sort-refused).
- Start
- Leistungen
- Über uns
- Kontakt
Im Baum ist die Linie auf die Ebene eingerückt, auf der das Element landet. Hier zeigen sich alle drei Zustände auf einmal; ein Ziehen zeigt immer nur einen.
-
-
Start
-
Über uns
-
Impressum
-
Elemente nebeneinander — Kacheln in einem Raster — bekommen die Linie aufrecht (seit 1.34.0): .is-sort-inline mit .is-sort-before setzt sie an die Anfangskante des Elements, mit .is-sort-after an seine Endkante. Eine Kachel, die das Element aufnimmt, leuchtet auf wie eine Zeile.
Mit einem .glass-sort__handle im Element startet nur der Griff ein Ziehen, ein Tipp auf das Element wählt es also weiterhin, und ein Finger auf dem Griff zieht sofort, ohne langes Drücken. Das Ziehen selbst bringt GlassKit Elements mit: <glk-list sortable> und <glk-tree sortable> ordnen mit der Maus, per Touch nach langem Drücken und mit der Tastatur — die Leertaste hebt ein Element auf, die Pfeiltasten bewegen es, die Leertaste legt es ab, Escape bricht ab —, sagen jeden Schritt an, nehmen Breadcrumbs als Ablageziele und lassen die Elemente über --gl-sort-duration (180 ms) mit --gl-sort-easing (ease-out) an ihren Platz gleiten. Unter prefers-reduced-motion gleitet nichts.
| Klasse | Beschreibung |
|---|---|
.is-sort-source | Das gezogene Element an seinem alten Platz, auf 40 % verblasst |
.is-sort-before, .is-sort-after | Eine 2 px breite Linie in der Primärfarbe über oder unter dem Element, eingerückt auf --gl-tree-level |
.is-sort-inline | Mit .is-sort-before oder .is-sort-after: Die Linie steht aufrecht an der Anfangs- oder Endkante des Elements, für Elemente nebeneinander — Kacheln in einem Raster (seit 1.34.0) |
.is-sort-inside | Das Element nimmt das gezogene auf: getönt, mit Ring — seit 1.34.0 auch über dem Hover einer interaktiven Zeile und über dem gewählten Zustand |
.is-sort-refused | Das Element nimmt es nicht: Fehlerfläche und -ring; eine Linie wird rot |
.glass-sort__ghost | Die angehobene Kopie, die dem Zeiger folgt; [popover] im Top Layer |
.glass-sort__handle | Der Griff: Nur er startet ein Ziehen, und ein Finger darauf zieht sofort |
Modal
Zentrierter Dialog mit Blur-Overlay. Sichtbarkeit wird über die .is-active-Klasse auf dem Overlay-Element gesteuert — das Umschalten benötigt etwas JavaScript.
Vertrag löschen?
Dieser Vorgang kann nicht rückgängig gemacht werden.
Klassen-Referenz
| Klasse | Beschreibung |
|---|---|
.glass-modal-overlay | Fullscreen Blur-Overlay |
.glass-modal-overlay.is-active | Sichtbar + animiert |
dialog.glass-modal-overlay | Das Overlay als natives Dialog-Element, geöffnet mit showModal() (seit 1.20.0) |
.glass-modal | Dialog-Container, höchstens --gl-modal-max-width breit (340px, wenn nicht gesetzt) |
__header / __title | Titel-Bereich |
__body | Inhaltsbereich |
__footer / __action | Aktionsleiste |
__action--primary | Primäre Aktion |
__action--danger | Gefährliche Aktion |
Hinweis: die .is-active-Klasse gehört auf das .glass-modal-overlay, nicht auf .glass-modal selbst. Das Overlay übernimmt den Fullscreen-Backdrop, und sein :is-active-Zustand triggert sowohl das Backdrop-Fade-In als auch die Scale-Up-Animation des inneren Dialogs.
Als natives Dialog-Element
Seit 1.20.0 darf das Overlay auch ein <dialog> sein. Mit showModal() geöffnet liegt es in der Top Layer; die Seite dahinter ist für Zeiger, Tastatur und Screenreader inert; der Fokus wandert hinein und beim Schließen dorthin zurück, wo er herkam; Escape schließt. GlassKit nimmt dem Dialog seinen eigenen Kasten und Backdrop, er sieht also genau aus wie das <div>-Overlay. Seinen Namen bekommt er über aria-labelledby vom Titel. <glk-modal> aus GlassKit Elements arbeitet so.
Solange ein modaler Dialog offen ist, ist alles außerhalb inert — ein Toast, der dann erscheint, ist weder anklickbar noch wird er vorgelesen. Rückmeldungen gehören in den Dialog, oder der Dialog schließt zuerst.
Breite
Das Panel ist höchstens --gl-modal-max-width breit — 340 px, wenn nicht gesetzt (seit 1.20.0; vorher ein fester Wert). Ein Dialog mit Formular oder Tabelle darf breiter werden:
--gl-modal-bg ersetzt die Fläche des Panels (seit 1.35.0). Im dunklen Modus beginnt der Schimmer bei --gl-dialog-glow-top, dem mittleren Schimmer der Karte: Auf dem hellsten Teil eines hohen Dialogs las weiße Schrift auf Bedienelementen 2,9 bis 4,7:1 — siehe dunkles Glas.
Blur hinter dem Dialog
Die Abdunkelung hinter einem Dialog und hinter einem Sheet verschwimmt mit --gl-blur-overlay, wo ein Projekt es setzt, sonst mit --gl-blur-soft (seit 1.25.0). Die Oberflächen-Presets setzen die Blur-Tokens auf 0, lassen dieses aber in Ruhe; so behält auch eine Seite ohne Glas eine verschwommene Abdunkelung:
Toast
Sichtbar via .is-visible. Varianten: --success, --error, --warning.
Mit Aktion (seit 1.19.0): __action ist eine kleine Pille im Ton des Toasts — primär beim schlichten Toast, in der Statusfarbe bei einer Variante — und __close das × am Ende; es braucht ein aria-label. Beide haben eine Trefferfläche von 44 px. Ein Toast mit Aktion darf bis 480 px breit werden, der Text bricht um, die Knöpfe schrumpfen nie; er sollte stehen bleiben, bis einer davon benutzt wird. Der Toast sitzt --gl-toast-top vom oberen Rand (56 px, wenn nicht gesetzt) — setz ihn unter deine Kopfzeile und nimm bei viewport-fit=cover env(safe-area-inset-top) dazu. Er bleibt auch mit Aktion oben: ein Ort für jeden Toast.
| Klasse | Beschreibung |
|---|---|
.glass-toast, .is-visible | Oben fixiert, sichtbar eingeblendet |
--success, --error, --warning | Färben das Symbol; tönen die Aktion in der Statusfarbe |
__icon, __text | 22-px-Symbol, Nachricht (bricht um, gibt nach) |
__action | Eine Aktion: Pille im Ton des Toasts, 44 px Trefferfläche, schrumpft nie (seit 1.19.0) |
__close | Das ×, 28 px mit 44 px Trefferfläche (seit 1.19.0) |
--gl-toast-top | Abstand vom oberen Rand, Vorgabe var(--gl-space-4xl) (seit 1.19.0) |
In der obersten Ebene (seit 1.39.0): Ein Toast liegt unter einem Modal oder Sheet, das der Browser in die oberste Ebene legt, ganz gleich welcher z-index — unter dem verschwommenen Overlay, unlesbar. Gib ihm popover="manual" und rufe showPopover() auf — bei jedem Zeigen neu, nach hidePopover(), damit er über einem seither geöffneten Dialog liegt. .glass-toast[popover] nimmt die eigene Box des Popovers zurück; Ort und Aussehen bleiben die des Toasts. Halte ihn offen, während er versteckt ist: Er bleibt unsichtbar und lässt den Zeiger durch, und als Live-Region wird er weiter vorgelesen. Neben einem Modal ist er zu sehen, aber wie alles außerhalb des Dialogs nicht bedienbar und nicht angesagt. <glk-toast> in GlassKit Elements tut das.
Popover
Verankertes Dropdown- / Menü-Container. Trigger und .glass-popover in einem .glass-popover-anchor verschachteln. Sichtbarkeit wird über die .is-open-Klasse gesteuert — das Umschalten benötigt ein bisschen JavaScript.
Im Top Layer
Seit 1.32.0 kann ein Popover im Top Layer aufgehen. Gib ihm das Attribut popover und öffne ihn mit showPopover(): Er liegt über jedem Stacking Context, eine Box mit overflow: hidden drumherum schneidet ihn nicht mehr ab, und geschlossen nimmt er keinen Platz ein, wo die Klassen-Variante die Seite noch um ihre Box verbreiterte. Neben den Trigger setzt der Browser ihn allerdings nicht. Im Top Layer ist der Popover position: fixed: Ein Skript misst den Trigger, schreibt left und top in Viewport-Pixeln, klappt den Popover auf die andere Seite, wo der Viewport keinen Platz lässt, und hält ihn dort, während die Seite scrollt; data-side="top" lässt ihn von seiner Unterkante aus wachsen, wenn er über dem Trigger aufgeht. <glk-popover> aus GlassKit Elements erledigt all das, und Tooltip und Menü gehen genauso auf. Probier es: Die Vorschau schneidet ab, was ihre Box verlässt, den Popover im Top Layer aber nicht; ein Klick daneben oder Escape schließt ihn.
Über jedem Stacking Context: overflow: hidden an der Vorschau schneidet ihn nicht ab.
Klassen-Referenz
| Klasse | Beschreibung |
|---|---|
.glass-popover-anchor | Positionierungs-Kontext für den Popover (umschließt Trigger + Popover) |
.glass-popover | Floating Glass-Surface, ausgeblendet bis .is-open |
.glass-popover.is-open | Sichtbarer Zustand — Fade- + Scale-Animation |
.glass-popover--top | Öffnet nach oben (über dem Trigger) |
.glass-popover--start | Linke Kante am Trigger ausrichten |
.glass-popover--end | Rechte Kante am Trigger ausrichten |
.glass-popover[popover] | Im Top Layer, position: fixed: mit showPopover() geöffnet, per Skript an Viewport-Koordinaten platziert, geschlossen ohne Platzbedarf (seit 1.32.0) |
[data-side="top"] | Mit [popover]: wächst von der Unterkante aus, für einen Popover über seinem Trigger |
Hinweis: die Toggle-Funktion darf nicht togglePopover heißen — dieser Name kollidiert mit der nativen HTMLElement.togglePopover()-Methode der HTML Popover API, und Inline-onclick-Handler werfen einen NotSupportedError.
Tooltip
Ein kurzer Name oder Hinweis für ein Bedienelement, beim Überfahren und beim Tastaturfokus (seit 1.32.0): ein Button nur mit Icon, die Einträge einer Rail, eine Zeilenaktion. Kleine Schrift auf dem Glas des Popovers mit seinem Kantenlicht, so weit getönt, dass sie über allem lesbar bleibt (6,3:1 oder mehr, auch Weiß unter einem dunklen Tooltip), höchstens --gl-tooltip-max-width (240 px) breit; längerer Text bricht um. Gib ihm role="tooltip"; das Bedienelement verweist mit aria-describedby darauf, oder mit aria-labelledby, wo der Tooltip sein einziger Name ist.
Er geht im Top Layer auf wie der Popover, mit popover="hint" (ein Browser ohne hint nimmt es als manual), per Skript neben sein Bedienelement gesetzt und umgeklappt oder verschoben, damit er im Viewport bleibt. Ohne das Attribut ist er ein schlichter Block wie in der Vorschau. WCAG 1.4.13 verlangt dreierlei von einem Tooltip: Der Zeiger kann auf ihn wechseln, ohne dass er zugeht, Escape schließt ihn, ohne den Fokus zu bewegen, und er bleibt, solange das Bedienelement überfahren oder fokussiert ist. <glk-tooltip> aus GlassKit Elements bringt dieses Verhalten mit: Er erscheint nach 400 ms beim Überfahren, sofort beim Tastaturfokus und bei langem Drücken per Touch, während ein Tipp ihn nie zeigt.
| Token | Ungesetzt | Wirkung |
|---|---|---|
--gl-tooltip-max-width | 240px | Die größte Breite, bevor der Text umbricht |
--gl-tooltip-bg | --gl-color-bg-dark zu 94 % | Seine Fläche: der dunkelste Hintergrund des Themes, im hellen Theme hell |
--gl-tooltip-color | --gl-color-text | Seine Schrift |
Eine zweite Zeile (seit 1.39.0): .glass-tooltip__hint nach dem Namen sagt, was eine Wahl tut, in normaler Stärke und der gedämpften Farbe (--gl-tooltip-hint-color).
Input
Datums- und Zeitfelder — type="date", time, datetime-local, month — nehmen dieselbe Klasse. Sie verzichten auf das native Aussehen (seit 1.17.0): iOS zeichnete sie breiter als ihre Spalte, ein leeres schmaler als ein gefülltes, den Wert mittig. Jetzt sitzen sie wie jedes andere Feld in ihrer Spalte, der Wert am Anfang; der native Picker öffnet weiter.
Präfix und Suffix
Ein Icon, eine Währung, eine Einheit oder ein Button im Kasten des Feldes (seit 1.22.0): das Input in .glass-input-wrap legen und __prefix und __suffix daneben setzen. Sie liegen auf dem Feld, mittig, an seinem Anfang und Ende — von rechts nach links tauschen sie die Seiten. Das Padding des Feldes wächst um ihre Breite, --gl-input-prefix-size und --gl-input-suffix-size: 18px, ein Icon, wenn nicht gesetzt — für eine breitere Einheit setzen. Es folgt dem Modifier --prefix / --suffix, oder einem sichtbaren Affix, wo :has() unterstützt wird. Ein Klick auf Text, ein Icon oder ein deaktiviertes Bedienelement erreicht das Feld; aktive Bedienelemente, Links und Elemente mit tabindex nehmen ihren eigenen, formularassoziierte Custom Elements wie <glk-button> eingeschlossen (seit 1.22.2). Das tun sie auch in einem Container, der mit pointer-events: none gesperrt ist: ihn mit inert sperren oder sie deaktivieren. <glk-input> aus GlassKit Elements hat darauf die Slots prefix und suffix und misst die Breite selbst.
Ein Wert oder Platzhalter, der zu lang für das Feld ist, endet mit einer Ellipsis, solange das Feld nicht bearbeitet wird, und ein .glass-label ohne Text nimmt keinen Platz ein (beides seit 1.25.0). Datums- und Zeitfelder behalten den Picker-Button des Browsers; --gl-input-picker-icon: none blendet ihn in Chromium aus — etwa wenn das Präfix des Feldes der Picker ist; dann dort showPicker() aufrufen. Es blendet auch den Pfeil eines Feldes mit <datalist> aus.
Am Ende der Label-Zeile
Seit 1.33.0 hat die Label-Zeile eines Feldes einen Platz an ihrem Ende, für einen Link wie „Passwort vergessen?“ auf der Zeile von „Passwort“. .glass-input-group__label-end im Markup hinter das Feld setzen und --label-end an die Gruppe: Die Gruppe zeichnet ihn auf der Zeile des Labels, an ihrem Ende, in der kleinen Schrift des Labels, und die Tastatur erreicht ihn trotzdem nach dem Feld — E-Mail, Passwort, „Passwort vergessen?“, Anmelden, die Reihenfolge, die sich in einem Anmeldeformular am besten liest. Um eine Textarea oder ein Select funktioniert es genauso; in GlassKit Elements haben <glk-input>, <glk-textarea> und <glk-select> dafür einen Slot label-end.
Seit 1.37.0 kann der Platz einen Zeichenzähler halten, .glass-input-group__counter: „48/145“ in der gedämpften Farbe, und mit .is-over jenseits der Grenze in der Fehlerfarbe — ein per Skript gesetzter Wert kann länger sein, maxlength hält nur das Tippen auf. Aktualisiere ihn bei input und verbinde ihn über aria-describedby mit dem Feld, damit ein Screenreader ihn mit dem Feld vorliest. Nach einem Link am selben Platz hält er Abstand.
Seit 1.38.0 hält --gl-label-hidden: 1 an einer Gruppe oder einem Container um Felder jedes .glass-label als Namen seines Feldes und nimmt es aus dem Blick — gesetzt aus einer Container- oder Media-Query, der ein Attribut nicht folgen kann: Felder in einer Tabelle unter einem gemeinsamen Kopf nur, solange die Tabelle breit genug ist, mit ihren Labels darüber, wenn sie zur Liste wird. Es braucht Style Queries auf Custom Properties: Chrome 111, Safari 18 und Firefox 151. Ohne sie bleiben die Labels über ihren Feldern, jedes Feld 24 px höher — für ältere Browser setze die Regeln eines unsichtbaren Labels auf .glass-label, oder auf ::part(label) in GlassKit Elements, in dieselbe Query, wie unten. In GlassKit Elements reicht es in <glk-input>, <glk-select> und <glk-textarea>, deren label-hidden dasselbe für ein Feld tut.
Textarea
Eine Textarea, die sich nicht bearbeiten lässt, hat keinen Anfasser zum Vergrößern (seit 1.25.0). --gl-textarea-field-sizing: content lässt Textareas mit ihrem Text wachsen, in Browsern mit field-sizing; standardmäßig ist es aus, weil es rows ignoriert.
Select
Der Chevron ist --gl-select-chevron, ein SVG in der gedämpften Textfarbe des jeweiligen Themes — seit 1.20.0; vorher blieb er auch im hellen Theme weiß und war kaum zu sehen. Mit einem eigenen url(…) im Token lässt er sich ersetzen. Von rechts nach links wandern der Chevron und der Platz für ihn nach links.
Ein Platzhalter ist das native Muster: eine erste Option mit leerem Wert, disabled und hidden, gewählt, solange nichts gewählt ist. Sie lässt sich nicht auswählen, und mit required sendet das Formular nicht, solange sie steht. Seit 1.37.0 zeigt das Feld sie in der Platzhalterfarbe, wie ein Eingabefeld; eine erste echte Option, die für „nichts gewählt“ stand, ließ sich nicht wählen, weil die schon gezeigte Option zu wählen nichts ändert.
Suchfeld
Toggle Switch
Das Input ist unsichtbar, liegt aber über der Spur und nimmt den Klick selbst an (seit 1.20.0): Ein Testwerkzeug, das den Schalter über seine Rolle anklickt, erreicht es — vorher zeichnete die Spur darüber und nahm den Klick. Es deckt nur die Spur ab; der Labeltext, der auch einen Link enthalten kann, bleibt beim Label. Ein leeres __label nimmt keinen Platz ein, ein Schalter ohne Text hält also keine 12 px Lücke dafür frei. Beides gilt genauso für Checkbox und Radio Button. Von rechts nach links beginnt der Knopf rechts.
Die Spur ist --gl-toggle-track-bg, wenn aus, und --gl-toggle-track-bg-checked, wenn an (seit 1.25.0; ungesetzt --gl-surface-2 und der Primärverlauf): eine kräftigere Spur für eine Seite ohne Glas, auf der die Fläche schwer zu sehen sein kann.
Wo der Schalter steht (seit 1.39.0): .glass-toggle--label-start setzt den Text davor, und .glass-toggle--full spannt das Bedienelement über seine Zeile, sodass mit beiden der Text am Anfang der Zeile steht und der Schalter an ihrem Ende, wie in den Einstellungen von iOS — von rechts nach links gespiegelt. Die ganze Zeile ist das Label, ein Klick irgendwo darauf schaltet. .glass-checkbox--label-start, --full und dasselbe für .glass-radio tun es für Checkbox und Radio. In einer Listen-Zeile kommt der Schalter stattdessen in __trailing, mit dem Titel der Zeile als Namen.
Checkbox
Wie beim Toggle liegt das Input über der Box, und ein leeres __label nimmt keinen Platz ein (seit 1.20.0).
Radio Button
Wie beim Toggle liegt das Input über dem Kreis, und ein leeres __label nimmt keinen Platz ein (seit 1.20.0).
Fläche, Rand und Punkt sind Tokens (seit 1.25.0): --gl-radio-bg und --gl-radio-bg-checked, --gl-radio-border und --gl-radio-border-checked (ganze Border-Werte, also beiden dieselbe Breite geben), --gl-radio-dot-size (10px) und --gl-radio-dot-color (ungesetzt die Tinte auf der Primärfarbe, --gl-color-on-primary, weiß, solange ein Projekt sie nicht umstellt — seit 1.32.0; vorher immer weiß). Ein Ring in der Textfarbe, der beim Auswählen die Akzentfarbe annimmt:
Range Slider
Progress Bar
| Klasse | Beschreibung |
|---|---|
.glass-progress | Basis-Container |
--sm / --lg | Track-Höhe: 4px / 12px |
--success / --error | Farb-Varianten |
Accordion
Ein offener Eintrag nimmt die Höhe seines Inhalts an, gleich wie lang, und gleitet dorthin: __content ist ein Grid mit einer Zeile, die von 0fr auf 1fr geht (seit 1.30.0). Bis dahin endete er bei 500 px und schnitt den Rest ab, und das Gleiten lief im Tempo dieser Grenze statt in dem des Inhalts. Inhalt, der während des offenen Zustands wächst, wächst mit. Unter prefers-reduced-motion öffnet er ohne Gleiten.
Seit 1.39.0 zeigt der Trigger einen Ring für die Tastatur, inset 0 0 0 2px var(--gl-border-focus) darin, mit dem Item gerundet, wie Listen- und Baumzeilen ihn haben; vorher hatte er keinen. .glass-accordion__summary nach dem Titel hält eine Zusammenfassung des Items, die Werte eines geschlossenen Eintrags: im Raum bis zum Chevron, auf einer Zeile mit Auslassungspunkten, klein und gedämpft, im Button, sodass ein Klick darauf, Enter und Leertaste das Item öffnen wie auf dem Titel. Sie nimmt nur den Raum, den der Titel lässt. Blende sie aus, solange das Item offen ist, wo die Felder die Werte selbst zeigen.
Skeleton
Ladeplatzhalter: schimmernde Zeilen stehen für Text, der noch nicht da ist. Die Breite jeder Zeile setzt der Aufrufer; der Schimmer folgt dem Theme und steht unter prefers-reduced-motion still. Den Bereich mit aria-busy="true" markieren, damit Hilfstechnik das Laden erkennt.
| Klasse | Beschreibung |
|---|---|
.glass-skeleton | Stapel aus Zeilen, 10px Abstand |
.glass-skeleton__line | Eine Schimmerzeile (12px); Breite per Inline-Style |
.glass-skeleton__line--title | Höhere Zeile (18px) für eine Überschrift |
Tabelle
Eine gewöhnliche <table> auf Glas: Haarlinien zwischen den Zeilen, gedämpfter Kopf, Zahlen rechtsbündig in Tabellenziffern. Der Wrapper .glass-table-wrap scrollt seitlich, wo die Spalten nicht passen. Die Klasse gehört auf die Tabelle selbst — aus einem Shadow Root erreicht ::slotted() die Zellen nicht, deshalb ist das bewusst Dokument-CSS.
| Datum | Posten | Betrag |
|---|---|---|
| 2026-09-18 | Rechnung 1042 | 1.240,00 |
| 2026-09-19 | Erstattung | −80,00 |
| 2026-09-20 | Offen | – |
| Klasse | Beschreibung |
|---|---|
.glass-table-wrap | Optionaler Container mit seitlichem Scrollen |
.glass-table | Die Tabelle: Haarlinien, Hover-Hervorhebung |
.glass-table__num | Rechtsbündig, Tabellenziffern — auf th und td |
.glass-table__muted | Sekundäre Textfarbe für eine Zelle |
Sortieren, fester Kopf, Zeilenaktionen
Seit 1.32.0 bringt die Tabelle mit, was eine Liste von Rechnungen oder Nutzern braucht. Eine Kopfzelle, die sortiert, enthält einen __sort-Button mit dem Pfeil und trägt aria-sort: "ascending", "descending" oder "none". Die Seite sortiert die Zeilen, oft auf dem Server; die Klassen zeigen nur den Zustand. --sticky an der Tabelle und .glass-table-wrap--sticky an ihrem Wrap halten den Kopf sichtbar: Der Wrap scrollt in beide Richtungen, höchstens --gl-table-max-height (60vh) hoch, und die Kopfzellen haften an seinem oberen Rand, auf --gl-table-header-bg. Zellen mit __actions tragen die Aktionen der Zeile — ein Menü, Icon-Buttons mit Tooltips — und bleiben am Zeilenende, während die Tabelle seitlich scrollt; sobald sie das tut, gibt --scrolls an der Tabelle ihnen eine eigene Fläche, und ein .glass-table-frame um den Wrap schattiert jeden Rand, hinter dem weitere Spalten warten (data-more-start, data-more-end). Sortiere die Spalten, scrolle die Tabelle, mach das Fenster schmal:
| Status | Tarif | |||||
|---|---|---|---|---|---|---|
| 2026-1048 | Bäckerei Nordwind | 2026-10-27 | 1.240,00 | Offen | Business jährlich | |
| 2026-1047 | Zahnarztpraxis am Hafen | 2026-10-26 | 89,00 | Bezahlt | Starter monatlich | |
| 2026-1046 | Blumen Glockenblume | 2026-10-25 | 2.310,50 | Bezahlt | Business monatlich | |
| 2026-1045 | Studio Turmfalke | 2026-10-24 | 412,80 | Überfällig | Starter jährlich | |
| 2026-1044 | Yoga Morgenlicht | 2026-10-23 | 75,00 | Bezahlt | Starter monatlich | |
| 2026-1043 | Radwerk Nord | 2026-10-22 | 640,00 | Offen | Business jährlich | |
| 2026-1042 | Kanzlei Weber & Roth | 2026-10-21 | 3.480,00 | Bezahlt | Business jährlich |
Ein paar Zeilen Skript setzen --scrolls und die Attribute des Rahmens aus der Scrollposition des Wraps, wie in der Vorschau. <glk-table> aus GlassKit Elements erledigt all das um eine native Tabelle in seinem Light DOM, die ihre Semantik behält, Kopieren und Einfügen, die Suche auf der Seite und vom Server gerendertes Markup: data-sort an einer Kopfzelle fügt den Button und aria-sort hinzu, ein Klick sendet ein abbrechbares glk-table-sort, und sticky-header und list-below schalten die Layouts.
Als Karten
--list macht aus jeder Zeile eine Karte für schmale Stellen, mit dem Namen der Spalte vor jedem Wert aus data-label an den Zellen. Die Aktionen wandern an das obere Ende der Karte, Zahlen behalten ihre Tabellenziffern. Der Kopf bleibt für assistive Technik da, nur unsichtbar, und die Labels sind generierter Inhalt ohne eigenen Text, sodass ein Screenreader die Spalte nicht doppelt hört. Eine Tabelle, die nicht mehr als Tabelle gelayoutet wird, kann ihre Semantik verlieren; setz ihre Rollen deshalb ausdrücklich. <glk-table list-below="640px"> schaltet nach der eigenen Breite um, nicht nach der des Viewports, und schreibt Labels und Rollen selbst.
| Rechnung | Kunde | Betrag | Status | |
|---|---|---|---|---|
| 2026-1048 | Bäckerei Nordwind | 1.240,00 | Offen | |
| 2026-1047 | Zahnarztpraxis am Hafen | 89,00 | Bezahlt |
Leer
Solange keine Zeile da ist, trägt __empty unter der Tabelle einen Leerzustand, und der Kopf bleibt; hidden nimmt ihn wieder weg.
| Rechnung | Kunde | Betrag | Status |
|---|
Keine Rechnungen
Nichts passt zu diesem Filter.
| Klasse | Beschreibung |
|---|---|
__sort, __sort-icon | Button, der eine Kopfzelle füllt und nach ihrer Spalte sortiert, und sein Pfeil: nach oben für ascending, nach unten für descending, blass, solange unsortiert |
th[aria-sort] | Der Zustand: ascending, descending, none |
--sticky + .glass-table-wrap--sticky | Der Kopf haftet oben an einem Wrap, der in beide Richtungen scrollt, höchstens --gl-table-max-height hoch |
__actions | Zelle für Zeilenaktionen, am Zeilenende, dort gehalten, während die Tabelle seitlich scrollt |
--scrolls | Gesetzt, solange die Tabelle seitlich scrollt: die Aktionen auf eigener Fläche, mit Schatten |
.glass-table-frame | Um den Wrap; schattiert den Start- oder Endrand mit data-more-start, data-more-end |
__empty | Unter der Tabelle in ihrem Wrap, der Platz für einen Leerzustand |
--list | Jede Zeile eine Karte, die Labels aus data-label, die Aktionen am oberen Ende |
| Token | Ungesetzt | Wirkung |
|---|---|---|
--gl-table-cell-padding | 9px 10px | Der Raum in den Zellen des Körpers |
--gl-table-header-padding | 8px 10px | Der Raum in den Kopfzellen |
--gl-table-max-height | 60vh | Wie hoch ein haftender Wrap wird, bevor er scrollt |
--gl-table-header-bg | --gl-color-bg-mid zu 94 % | Die Fläche des haftenden Kopfs und die der Aktionen, solange die Tabelle seitlich scrollt |
Fließtext
Fließtext, den die App nicht von Hand geschrieben hat — gerendertes Markdown, Hilfe- und Infoseiten. Eine Klasse auf dem Container stylt Überschriften, Absätze, Listen, Links, Code, Zitate, Bilder und Tabellen. Bewusst Dokument-CSS: der Inhalt ist Light DOM, und ::slotted() endet auf der ersten Ebene.
Erste Schritte
glasskit.css einbinden, data-theme auf <html> setzen, fertig. Alles Weitere ist optional — siehe die Design-Tokens.
- Dark Mode ist der Standard
- Light Mode über
data-theme="light"
Der Glaseffekt braucht einen farbigen Hintergrund, um sichtbar zu sein.
Segmentwahl
Eine kleine, exklusive Auswahl als ein Bedienelement — Ampel, Vormittag / Nachmittag, Modus. Knöpfe in einer role="group"; der gewählte trägt aria-pressed="true", und genau an diesem Attribut hängt das Styling, damit Zustand und Semantik nicht auseinanderlaufen. Die Ton-Modifier setzen einen Punkt in einer Zustandsfarbe vor die Beschriftung. Probier es: Klick oder Tab auf einen Knopf und Leertaste. Mehr Optionen als Platz? Ohne Modifier bleibt die Zeile einzeilig und läuft über den Rand; --scroll lässt sie seitwärts scrollen, --wrap bricht sie um. Beide lassen sich mit --full kombinieren.
| Klasse | Beschreibung |
|---|---|
.glass-segmented | Die Gruppe: eingelassene Glas-Schiene, Knöpfe darin |
--full | Knöpfe teilen sich die Breite |
--scroll | Eine Zeile, die seitwärts scrollt, wenn die Optionen nicht passen; Scrollbar versteckt (seit 1.17.0) |
--wrap | Bricht die Zeile um, wenn die Optionen nicht passen (seit 1.17.0) |
__item | Eine Option; aria-pressed="true" markiert die gewählte, disabled dämpft |
__item--success / --warning / --error | Ton: setzt --gl-segmented-tone für den Punkt |
__dot | Der Punkt vor der Beschriftung, in der Tonfarbe |
__icon | Ein Icon vor der Beschriftung, in der Farbe der Option (seit 1.28.0) |
__badge | Eine Zahl nach der Beschriftung, in der Tonfarbe, wo ein Ton gesetzt ist; in __icon an der Ecke des Icons (seit 1.29.0) |
__badge--primary, --success, --warning, --error | Der Zähler in eigener Farbe, gleich welcher Ton, ohne Punkt (seit 1.31.0) |
--icons | Nur Icons, quadratische Optionen; die Namen stehen in aria-label (seit 1.28.0) |
__icon--color | Ein farbiges Logo behält seine eigenen Füllungen und Konturen; ohne zieht ein SVG Linien wie ein Linien-Icon (seit 1.35.0) |
--droplet | Die gewählte Option sitzt auf einem Glastropfen, der zur nächsten gleitet (seit 1.27.0) |
Icons
Seit 1.28.0 kann eine Option ein Icon in .glass-segmented__icon zeigen, vor ihrer Beschriftung: Ein SVG zieht seine Linien in der Farbe der Option, jedes andere Element — ein Font-Icon, eine <img>-Maske — übernimmt diese Farbe, ein Font-Icon auch die 18 px der Box. Unter dem Tropfen wächst das Icon wie der Ton-Punkt. --icons macht eine Zeile nur aus Icons, etwa einen Schalter Hell / Dunkel / Automatisch: Die Optionen werden quadratisch, und jede trägt ihren Namen als aria-label, als title auch für den Tooltip. Die Icon-Box bekommt aria-hidden="true", damit der Text eines Font-Icons nicht in den Namen gerät.
Ein farbiges Logo als Icon — das Zeichen einer Bildquelle — nimmt .glass-segmented__icon--color (seit 1.35.0) und behält seine eigenen Füllungen und Konturen; vorher erbten seine Formen die Kontur des Linien-Icons und standen in der Textfarbe umrandet da. --gl-segmented-bg setzt die Spur (seit 1.35.0); auf dem Glas eines Modals oder eines Sheets im dunklen Modus ist sie eine Mulde, --gl-dialog-well, mit der gewählten Option auf --gl-dialog-raised.
Fläche der gewählten Option
Seit 1.28.0 sind Fläche, Schatten und Textfarbe der gewählten Option Tokens, wie beim aktiven Eintrag der Tab-Bar: Auf einem dunklen Marken-Hintergrund ließ die helle Fläche ein weißes Label unter 4,5:1. Alle drei sind ungesetzt; der Tropfen übernimmt dieselbe Fläche und denselben Schatten, ein Wertepaar dient also beiden Darstellungen. Der Schatten steht in Schattenlisten: Abschalten mit einem Nullschatten, nicht mit none.
| Token | Ungesetzt | Wirkung |
|---|---|---|
--gl-segmented-active-bg | --gl-surface-5 (der Tropfen: ein heller Glasverlauf) | Fläche der gewählten Option und des Tropfens |
--gl-segmented-active-shadow | --gl-shadow-btn (der Tropfen: sein eigener) | Ihr Schatten |
--gl-segmented-active-color | --gl-color-text-heading | Label und Icon der gewählten Option und der Option unter einem gezogenen Tropfen |
Zähler
Seit 1.29.0 kann eine Option sagen, wie viel hinter ihr wartet — offene Rechnungen, neue Tickets —, mit .glass-segmented__badge nach ihrer Beschriftung: eine kleine Pille in Tabellenziffern, im Fluss, damit eine scrollende Zeile und der Tropfen die Option mit ihr messen. Der Ton-Punkt sagt, dass etwas da ist, das Badge, wie viel. Ohne Ton ist es neutral, eine Tönung der Textfarbe über dem State-Scrim; mit einem nimmt es die Statusfarbe der Badges. In .glass-segmented__icon gesetzt, sitzt es an der Ecke des Icons, wie bei der Tab-Bar — der Platz in einer --icons-Zeile, wo es das Icon verdeckt und deckend ist. Seine Zahl ist kein Name: Die Option bekommt ein aria-label, das sie nennt, „Tickets, 1 offen“.
Die neutrale Pille hat zwei Tokens, beide Farben und ungesetzt: --gl-segmented-badge-bg, die Tönung über dem Scrim (ungesetzt: 12 % der Textfarbe), und --gl-segmented-badge-color (ungesetzt: die Textfarbe). Gemessen in Chromium, WebKit und Firefox erreichen die Ziffern im dunklen Theme mindestens 5,6:1, im hellen mindestens 4,7:1, auf der gewählten Option und daneben, neutral und in jedem Ton.
Seit 1.31.0 kann ein Zähler eine eigene Farbe tragen, gleich welchen Ton die Option hat: .glass-segmented__badge--primary, --success, --warning und --error geben ihm das Aussehen der Badge-Varianten — die Zustandstönung über doppeltem Scrim, eine Haarlinie, die lesbare Textfarbe — ohne den Punkt, den ein Ton vor die Beschriftung setzt. Hat die Option zusätzlich einen Ton, gewinnt die eigene Farbe des Zählers. Auch seine Größe ist ein Token: --gl-segmented-badge-height (ungesetzt 16 px, zugleich seine Mindestbreite) und --gl-segmented-badge-font-size (ungesetzt 11 px). --gl-segmented-badge-border zieht eine Haarlinie in dieser Farbe um den neutralen Zähler, nach innen, sodass er seine Größe behält. Gemessen in Chromium, WebKit und Firefox erreichen die vier Farben 4,7:1 oder mehr in beiden Themes, inline und an der Ecke des Icons, auf der gewählten Option und daneben.
Droplet
Seit 1.27.0 gibt .glass-segmented--droplet der gewählten Option den Tropfen der Tab-Bar: Er läuft zur neuen Option, dehnt sich unterwegs und kommt zur Ruhe, die Schrift, über die er läuft, leuchtet auf, und ein Finger kann ihn ziehen. Deaktivierte Optionen werden übersprungen. In einer scrollenden Zeile (--scroll) scrollt ein Wischen weiterhin; gezogen wird nur der Tropfen selbst, und an den Rändern scrollt die Zeile mit. Der Tropfen folgt aria-pressed; attachDroplets() aus glasskit-droplet.js startet ihn, wie oben.
Schrittanzeige
Fortschritt durch einen kurzen Ablauf: nummerierte Kreise mit Haarlinien dazwischen, erledigte auf der Erfolgsfläche (mit SVG-Haken), der aktuelle in der Primärfarbe (--gl-color-primary-fill, wo ein Projekt sie setzt, seit 1.32.0) und mit aria-current="step".
- Tag
- Fenster
- 3Hund
- 4Bestätigen
Die Liste ist ein Größen-Container: unter 360 px behält nur der aktuelle Schritt seine Beschriftung, die anderen zeigen ihre Nummer; davor kürzen Beschriftungen mit Ellipse. Im schmalen Layout behalten die Kreise ihre Größe, und die Linien geben zuerst nach, bis auf 2 px, bevor die aktuelle Beschriftung kürzt (seit 1.28.0): Sieben Schritte behalten eine aktuelle Beschriftung von 88 px ab einer 310 px breiten Spalte ganz, und die Zeile läuft nie über ihren Rand. Maßgeblich ist die Breite des Blocks, nicht des Viewports — hier in einem 300-px-Rahmen:
- Tag
- 2Zeitfenster wählen
- 3Hund
- 4Bestätigen
| Klasse | Beschreibung |
|---|---|
.glass-steps | Die Liste; ein Größen-Container, in einer Flex-Zeile also mit Breite versehen |
__item, __item--done, __item--current | Ein Schritt und seine Zustände |
__num | Der Kreis: Nummer, oder ein SVG-Haken wenn erledigt |
__label | Die Beschriftung; unter 360 px ausgeblendet, außer am aktuellen Schritt |
__line | Haarlinie zwischen den Schritten |
Bottom-Sheet
Das Bottom-Sheet ist das mobile Geschwister des Modals: ein Overlay, das einblendet, und ein Panel, das von der Unterkante hochfährt, nur oben gerundet, mit Griff und Safe-Area-Abstand. Eigener Block statt Modal-Modifier, weil Layout, Einfahrbewegung und Geste verschieden sind. --inline bettet das Panel ohne Overlay in den Fluss ein; die Overlay-Form braucht ein wenig JavaScript, unten gezeigt und in GlassKit Elements als <glk-sheet> umgesetzt. Seit 1.30.0 darf das Overlay ein natives <dialog> sein, wie beim Modal: Mit showModal() geöffnet liegt es im Top Layer, über jedem fixierten oder transformierten Element der Seite, gleich welcher z-index, und die Seite dahinter ist inert. dialog.glass-sheet-overlay nimmt dem Dialog seine eigene Box und seinen Backdrop und schneidet ab, ohne ein Scroll-Container zu sein (seit 1.39.0: overflow: clip — mit hidden scrollte ein Fokus im Panel, während es hereinglitt, das Overlay, und das Panel stand sofort an seinem Platz oder schwang darüber hinaus und zurück); einblenden mit showModal() und dann .is-active, ausblenden durch Entfernen von .is-active und close() nach transitionend. <glk-sheet> macht es so.
Umbuchen auf …
| Klasse | Beschreibung |
|---|---|
.glass-sheet-overlay | Fixiertes Overlay: Scrim, Blur, Panel an der Unterkante; startet bei Opacity 0 |
.is-active | Overlay sichtbar, Panel hochgefahren — per Skript geschaltet |
.glass-sheet | Das Panel: Milchglas, oben gerundet, unten Safe-Area-Abstand |
--inline | Im Fluss, ohne Overlay, rundum gerundet |
__grip, __title, __body, __actions | Griff, Überschrift, Inhalt, Aktionsspalte |
__head, __heading | Der Kopf: nimmt Platz und Abstand des Titels ein; __heading hält __eyebrow, den Titel und __subtitle (seit 1.35.0). Mit hidden nimmt er keinen Platz ein (seit 1.36.0) |
__eyebrow | Eine kurze Zeile über dem Titel, kleine Versalien in der gedämpften Farbe |
__subtitle | Unter dem Titel: ein Badge, eine Zeile Text, klein in der gedämpften Farbe (seit 1.36.0) |
__leading, __trailing | Vor und nach dem Titel: eine Marke oder ein Icon-Chip, ein Badge |
__close | Ein runder Schließen-Button aus Glas, 32 px mit 44 px Trefferfläche, am Ende des Kopfs; --gl-sheet-close-size, --gl-sheet-close-icon-size (16 px) und --gl-sheet-close-icon-stroke (2) ändern ihn und sein Zeichen (seit 1.36.0) |
.glass-sheet-overlay--start, --end | Das Panel an dieser Seite, volle Höhe, von der Seite, ohne Griff, Aktionen nebeneinander (seit 1.35.0) |
.glass-sheet-overlay--modeless | Kein Scrim und kein Blur; nur das Panel nimmt den Zeiger — für ein mit show() geöffnetes Sheet |
Der Kopf
Seit 1.35.0 hält der Kopf mehr als den Titel: __eyebrow darüber („Wiederherstellen“), __leading davor (ein Icon-Chip von 56 px), __trailing danach (ein Badge) und __close an seinem Ende, einen runden Button aus Glas. __head nimmt Platz und Abstand des Titels ein; ein Titel allein darin steht wie ohne ihn. Seit 1.36.0 steht __subtitle unter dem Titel, in __heading: Ein Badge dort lässt dem Titel seine Breite, wo einer in __trailing ihn in einem schmalen Sheet zusammendrückte. Drei Tokens ändern den Schließen-Button und sein Zeichen — --gl-sheet-close-size (32 px), --gl-sheet-close-icon-size (16 px) und --gl-sheet-close-icon-stroke (2) —, und ein leerer Kopf mit hidden nimmt keinen Platz ein; vorher behielt er seine 8 px.
Version von 09:41
Bildergalerie
1× in deiner AppAn einer Seite, nicht-modal
.glass-sheet-overlay--end oder --start (seit 1.35.0) setzt das Panel an diese Seite des Fensters: so hoch wie das Fenster weniger --gl-sheet-side-inset (16 px) an beiden Enden und so weit vom Rand entfernt, --gl-sheet-side-width (440 px) breit, mit den Ecken einer Karte. Es gleitet von dieser Seite herein, von rechts nach links gespiegelt, hat keinen Griff, und seine Aktionen stehen nebeneinander an seinem Fuß — ein Seitenpanel auf dem Desktop. --modeless lässt die Seite bedienbar: kein Scrim und kein Blur, nur das Panel nimmt den Zeiger. Öffne diesen Dialog mit show() statt showModal(): Die Seite ist nicht inert, ihre gewählte Zeile bleibt sichtbar, und ein später geöffnetes Modal liegt über dem Sheet. --gl-sheet-z-index (1000) stapelt es. Seit 1.36.0 setzen --gl-sheet-side-inset-block-start und --gl-sheet-side-inset-block-end oben und unten für sich — etwa unter einer festen Kopfleiste — und fallen auf --gl-sheet-side-inset zurück, das für die Seite und den Weg herein bleibt.
Dunkles Glas
Das Glas eines Modals oder eines Sheets ist heller als die Seite, oben am meisten. Im dunklen Modus beginnt seit 1.35.0 der Schimmer beider beim mittleren Schimmer der Karte, und die Bedienelemente darauf nehmen eigene Werte, wo die Seite keine gesetzt hat: Ein Segmented Control liegt in einer Mulde mit der gewählten Option eine Stufe dunkler, ein tertiärer Button ist eine Stufe dunkler, Badges und tertiäre Buttons nehmen keinen eigenen Blur, und Akzenttext nimmt --gl-color-primary-on-glass. Oben auf einem hohen Sheet im dunklen Modus las weiße Schrift auf Badges und Segmenten in 1.34.0 2,9 bis 4,7:1 und liest jetzt 4,7 bis 7,7:1, in Chromium, WebKit und Firefox. Der helle Modus behält Schimmer und Bedienelemente. --gl-sheet-bg und --gl-modal-bg ersetzen die ganze Fläche.
| Token | Dunkler Wert | Verwendung |
|---|---|---|
--gl-dialog-glow-top | var(--gl-card-glow-mid) | Wo der Schimmer eines Modals und eines Sheets beginnt |
--gl-dialog-well | rgba(0, 0, 0, 0.10) | Die Spur eines Segmented Controls auf Dialogglas |
--gl-dialog-raised | var(--gl-surface-3) | Seine gewählte Option |
--gl-dialog-control | var(--gl-surface-1) | Ein tertiärer Button auf Dialogglas |
--gl-badge-selected-color | var(--gl-color-text) | Die Beschriftung eines gewählten Badges, überall |
Alle fünf sind im hellen Modus ohne Wert. Ein Segmented Control oder ein Badge, dessen Tokens die Seite setzt, behält sie auch auf Dialogglas.
Leerzustand
Für leere Listen und Ergebnisseiten: eine zentrierte Spalte mit runder Icon-Fläche, Titel, kurzem gedämpftem Text und Platz für eine oder mehrere Aktionen nebeneinander.
Noch keine Buchungen
Such dir einen Tag und einen Hund aus — das Team freut sich.
| Klasse | Beschreibung |
|---|---|
.glass-empty | Zentrierte Spalte |
__icon | 48-px-Kreisfläche, darin ein 24-px-Strich-Icon (::slotted(svg)-Zwilling für Elements) |
__title, __text | Überschrift und gedämpfter Text (max. 38 Zeichen breit) |
__action | Platz für eine oder mehrere Aktionen: nebeneinander mit 8 px Abstand, umbrechend und zentriert, wenn es eng wird (seit 1.17.0) |
Wochenstreifen
Eine Reihe von Tages-Chips, die seitwärts scrollt — ein Buchungshorizont, die Tage um heute. Jeder Chip ist ein <button> mit Wochentag, Tageszahl und einem Punkt, den ein Ton-Modifier einfärbt; ohne Ton bleibt der Punkt transparent, damit Chips mit und ohne Markierung gleich hoch sind. Der gewählte Chip trägt aria-pressed="true" wie in der Segmentwahl; :disabled oder aria-disabled="true" dimmt einen Tag, der nicht wählbar ist. Die Scrollbar ist versteckt. Gib jedem Knopf ein aria-label mit dem vollen Datum — das sichtbare „Di 22“ ist kein Name. <glk-date-strip> in GlassKit Elements baut das aus Daten, mit Pfeiltasten und zentriertem gewähltem Chip.
| Klasse | Beschreibung |
|---|---|
.glass-date-strip | Scrollende Reihe; versteckte Scrollbar; 4 px Innenabstand, damit der eigene Überlauf den Fokusring nicht beschneidet |
__day | Chip-Knopf, mindestens 44 px; [aria-pressed="true"] gewählt, auf --gl-color-primary-fill, wo gesetzt, sonst der Primärfarbe (seit 1.32.0), :disabled / [aria-disabled="true"] gedimmt |
__day--today | Unterstreicht die Zahl |
__wd, __num | Wochentag in Versalien, Tageszahl |
__mark | 6-px-Punkt; ohne Ton transparent |
__mark--primary, --success, --warning, --error | Ton des Punkts über --gl-date-strip-tone; auf dem gewählten Chip wird jeder Ton zur Schriftfarbe auf Primär (--gl-date-strip-ink) |
Monatskalender
Ein Monat: Titel zwischen zwei runden Navigationsknöpfen, Wochentagszeile und 42 quadratische Tages-Knöpfe mit bis zu drei Punkten unter der Zahl. Der gewählte Tag trägt aria-pressed="true", --today zeichnet einen warmen Rahmen, --other dimmt einen Tag des Nachbarmonats, :disabled oder aria-disabled="true" dimmt einen Tag außerhalb des erlaubten Bereichs — die zweite Form bleibt für Pfeiltasten fokussierbar. Der Block ist eine role="group" aus Knöpfen mit dem vollen Datum als Namen, kein role="grid". <glk-calendar> in GlassKit Elements baut ihn, mit Tastaturnavigation und Namen aus Intl.
| Klasse | Beschreibung |
|---|---|
.glass-calendar | Block; __head mit __title (Ellipse, wenn es eng wird) und zwei __nav-Knöpfen, 32 px rund, mit SVG-Chevron |
__grid | Sieben Spalten, 4 px Abstand |
__wd | Wochentags-Kopfzelle, gedämpfte Versalien |
__day | Quadratischer Tages-Knopf; [aria-pressed="true"] gewählt, auf --gl-color-primary-fill, wo gesetzt, sonst der Primärfarbe (seit 1.32.0), --today warmer Rahmen, --other gedimmter Nachbarmonat, :disabled / [aria-disabled="true"] gedimmt und nicht wählbar |
__marks, __mark | 5-px-Punkte unter der Zahl, bis zu drei; __mark--primary / --success / --warning / --error über --gl-calendar-tone, die Schriftfarbe auf dem gewählten Tag über --gl-calendar-ink |
Bildauswahl
Ein Bild wählen, mit Vorschau: eine 72-px-Fläche — das Bild mit object-fit: cover oder ein Platzhalter-Icon — und eine Spalte mit Beschriftung, Hinweis und Aktionen, die gewöhnliche .glass-btn-Knöpfe sind; der Block bringt keine eigene Knopfoptik mit. --round macht die Fläche rund für Avatare; eine lange Beschriftung bricht um und drückt die Fläche nie zusammen. Jedes Bild, nicht nur Fotos. <glk-image-picker> in GlassKit Elements ergänzt Dateidialog, EXIF-Drehung und Verkleinerung.
| Klasse | Beschreibung |
|---|---|
.glass-image-picker | Zeile: Fläche links, Spalte rechts, 14 px Abstand |
__preview | 72-px-Fläche; img füllt sie, svg ist der 28-px-Platzhalter in der gedämpften Icon-Farbe |
__preview--round | Kreis, für Avatare |
__meta | Spalte, die nachgibt (min-width: 0) |
__label, __hint | Beschriftung im Look von .glass-label, bricht überall um; kleiner gedämpfter Hinweis |
__actions | Umbrechende Reihe aus .glass-btn-Knöpfen |
Utilities
Stack (vertikal)
.gl-stack
.gl-stack--xs (8px)
.gl-stack--sm (12px)
.gl-stack--md (16px)
.gl-stack--lg (20px)
.gl-stack--xl (24px)
Row (horizontal)
.gl-row
.gl-row--xs (8px)
.gl-row--sm (12px)
.gl-row--md (16px)
Margin Top
.gl-mt-sm (12px)
.gl-mt-md (16px)
.gl-mt-lg (20px)
.gl-mt-xl (24px)
Margin Bottom
.gl-mb-sm (12px)
.gl-mb-md (16px)
.gl-mb-lg (20px)
.gl-mb-xl (24px)
Text
.gl-text-center
.gl-text-muted
.gl-text-sm
Layout
.gl-px (padding horizontal)
.gl-w-full (width: 100%)
.gl-flex-1 (flex: 1)
📋 Alle Klassen auf einen Blick
| Komponente | Klassen | Modifier / States |
|---|---|---|
| Hintergrund | .glass-bg | --has-tab-bar |
| Navigation | .glass-nav | – |
| Pill-Button | .glass-pill | :disabled |
| Theme-Toggle | .glass-theme-toggle | – |
| Titel | .glass-title | – |
| Card | .glass-card | --glow |
| Button | .glass-btn | --primary, --secondary, --tertiary, --sm, --lg, --auto, :disabled |
| Badge | .glass-badge | --primary, --success, --warning, --error, --interactive, --selected, --md |
| Avatar | .glass-avatar | --sm, --lg; --gl-avatar-size (seit 1.37.0) |
| Divider | .glass-divider | – |
| Status | .glass-status | – |
| Liste | .glass-list | --flush, --bare, __item--interactive, __item--center, __item--danger, __item--accent, __leading--lg, __subtitle--wrap, __value, __section-header, .is-flash |
| Baum | .glass-tree | __row, __twisty, __icon, __label, __trailing, __group, .is-expanded, .is-leaf, .is-selected, .is-loading, .is-error, .is-flash, .is-disabled, .is-focus-visible, --gl-tree-level |
| Sortieren | .glass-sort__, .glass-sort__ | .is-sort-source, .is-sort-before, .is-sort-after, .is-sort-inside, .is-sort-refused |
| Skeleton | .glass-skeleton | __line, __line--title |
| Tabelle | .glass-table | -wrap, -wrap--sticky, -frame, __num, __muted, __sort, __sort-icon, [aria-sort], __actions, __empty, --sticky, --scrolls, --list |
| Fließtext | .glass-prose | – |
| Segmentwahl | .glass-segmented | --full, --scroll, --wrap, --icons, __item, __item--success/--warning/--error, __dot, __icon, __badge, [aria-pressed], --droplet |
| Schrittanzeige | .glass-steps | __item, __item--done, __item--current, __num, __label, __line |
| Bottom-Sheet | .glass-sheet-overlay + .glass-sheet | .is-active, --inline, __grip, __title, __body, __actions |
| Leerzustand | .glass-empty | __icon, __title, __text, __action |
| Wochenstreifen | .glass-date-strip | __day, __day--today, __wd, __num, __mark, __mark--primary/--success/--warning/--error, [aria-pressed], :disabled |
| Monatskalender | .glass-calendar | __head, __title, __nav, __grid, __wd, __day, __day--today, __day--other, __marks, __mark--primary/--success/--warning/--error, [aria-pressed], [aria-disabled] |
| Bildauswahl | .glass-image-picker | __preview, __preview--round, __meta, __label, __hint, __actions |
| Popover | .glass-popover | --top, --start, --end, .is-open, [popover], [data-side="top"] |
| Tooltip | .glass-tooltip | [popover]; __hint, eine zweite Zeile (seit 1.39.0) |
| Menü | .glass-menu | __item, __item--danger, __check, __icon, __label, __trailing, __separator, __group-label, [aria-checked], [aria-disabled], .is-checked, .is-focused, .is-focus-visible, [popover] |
| Input | .glass-input | --error, :disabled; .glass-input-wrap mit __prefix / __suffix; .glass-input-group--label-end mit __label-end und __counter (seit 1.37.0) |
| Textarea | .glass-textarea | :disabled |
| Select | .glass-select | :disabled; eine Platzhalter-Option in der Platzhalterfarbe (seit 1.37.0) |
| Suchfeld | .glass-search | – |
| Toggle | .glass-toggle | :checked, :disabled; --label-start, --full (seit 1.39.0) |
| Checkbox | .glass-checkbox | :checked, :disabled |
| Radio | .glass-radio | :checked, :disabled |
| Range | .glass-range | :disabled |
| Progress | .glass-progress | --sm, --lg, --success, --error |
| Modal | .glass-modal-overlay | .is-active |
| Toast | .glass-toast | --success, --error, --warning, .is-visible, __action, __close; [popover] in der obersten Ebene (seit 1.39.0) |
| Tab-Bar | .glass-tab-bar | __item mit .is-active, __icon, __label, __badge (--dot seit 1.38.0), __leading, __trailing, --droplet, --vertical, --rail, --labels, --start, --end, --top |
| Tab-Bar Floating | .glass-tab-bar-dock + .glass-tab-bar--floating | __accessory, __accessory--accent/--success/--error, __accessory-item, __accessory-label, --accessory-left, -dock--vertical, -dock--start |
| Breadcrumbs | .glass- | __list, __item, __crumb, __current, __overflow, __item--overflow, .is-drop-target, .is-drop-refused |
| Accordion | .glass-accordion | .is-open auf Items; __summary neben dem Titel (seit 1.39.0) |
🤖 KI / LLM-Referenz
GlassKit liefert eine SKILL.md mit – eine strukturierte, maschinenlesbare Komponenten-Referenz für KI-Assistenten, LLMs und Code-Generierungs-Tools.
| Feature | Beschreibung |
|---|---|
| Copy-Paste HTML | Alle 38 Komponenten mit exakter Verschachtelung und BEM-Hierarchie |
| Design-Token-Tabellen | Farben, Surfaces, Blur, Radii, Spacing, Shadows, Typography |
| State-Klassen-Mapping | is-active, is-open, is-visible, :checked – wo was hingehört |
| Composition Patterns | 6 fertige Seiten-Layouts: Login, Dashboard, Formular, Modal, Einstellungen, Fortschritt |
| Häufige Fehler | Typische Fehler und deren Korrekturen |
Anhängen oder referenzieren Sie SKILL.md, wenn Sie eine KI bitten, GlassKit-HTML zu generieren – für produktionsreife Ergebnisse.
🧩 Die GlassKit-Familie
GlassKit ist das CSS-Fundament einer dreischichtigen Familie – drei Schichten, eine Designsprache. Für alles jenseits einzelner Komponenten sind die Schwesterprojekte der vorgesehene Weg.
| Schicht | Projekt | Einsatz |
|---|---|---|
| CSS-Fundament | 🧊 GlassKit (Sie sind hier) | Die Designsprache: Pure-CSS-Komponenten, Design Tokens, Dark & Light. |
| App-Schicht | GlassKit Elements | Drop-in Web Components (glk-button, glk-card, …) für App-UIs. |
| Website-Schicht | GlassKit Web | Eine komplette Website bauen – das offizielle Astro-Template mit Sections, i18n und SEO auf dem GlassKit-Fundament. |