Theme
A few properties, then the parts.
Accent, appearance, and the typeface first, then a knob per component. The material itself stays physical: frost, rim light, and refraction are options, not a stylesheet.
Properties
Set them on any ancestor. Every glass element inside inherits them.
:root {
--glass-accent: #0a84ff; /* prominent buttons, sliders, tabs */
--glass-appearance: light; /* light, dark, or leave it on auto */
--glass-font: "Outfit", system-ui;
}--glass-accenttints prominent buttons and the filled portion of sliders and switches. Text on that fill is shifted so it stays readable.--glass-appearanceis read when an element isappearance="auto". After that, the pagecolor-schemeis used. The operating system scheme is not consulted on its own.--glass-fontis the typeface inside every control. This site sets it to Outfit so the UI does not inherit the display serif.--glass-foregroundoverrides the text color inside glass. It falls back to--gl-fg, which glass sets on the host for its appearance.--glass-text-shadowoverrides the text shadow. It falls back to--gl-text-shadow.--glass-focusis the focus ring color.
For content you color yourself inside glass, use color: var(--gl-fg). Every glass element also sets data-appearance="light" or data-appearance="dark". After changing --glass-appearance or color-scheme on an element other than <html> or <body>, call updateAppearance().
Component knobs
Each control reads its own custom properties and has a built-in default for every one. Set them on the element or on any ancestor.
- Button:
--glass-button-height,--glass-button-padding,--glass-button-font-size,--glass-on-accent,--glass-accent-text - Switch:
--glass-switch-on,--glass-switch-off,--glass-thumb - Slider:
--glass-slider-track,--glass-slider-off,--glass-thumb - Tab bar:
--glass-tab-bar-height,--glass-tab-selection,--glass-tab-selected - Segmented control:
--glass-segmented-height,--glass-segmented-track,--glass-segmented-backdrop,--glass-segmented-selected,--glass-segmented-thumb - Tab bar and segmented items:
--glass-selector-padding,--glass-item-direction,--glass-item-gap - Menu:
--glass-menu-highlight,--glass-destructive - Search:
--glass-search-height - Sheet:
--glass-scrim,--glass-sheet-inset,--glass-sheet-max-width,--glass-sheet-padding - Group and toolbar:
--glass-group-padding,--glass-toolbar-gap
Try it
:root {
--glass-accent: #0a84ff;
}Parts
Reach into a control with ::part(). The shared stack is ::part(glass). Layers inside that stack stay in the engine.
| Element | Parts |
|---|---|
glass-surface | glass |
glass-button | label, glass |
glass-switch | track, fill, thumb, glass |
glass-slider | track, fill, ticks, thumb, glass |
glass-tab-bar | indicator, lens, glass |
glass-segmented | track, indicator, lens, glass |
glass-tab | content |
glass-segment | content |
glass-menu | panel, content, glass |
glass-menu-item | label |
glass-group | glass |
glass-search | icon, input, clear, glass |
glass-sheet | scrim, sheet, grabber, body, glass |
glass-scene | backdrop |
glass-scene::part(backdrop) { object-position: 50% 20%; }
glass-search::part(input) { font-size: 17px; }Materials
regular is milky and legible over anything. clear is for photographs and video, where you want the picture to stay present. Both exist in light and dark. Per-surface options such as refraction, blur, tint, and specular are easier to feel than to describe: that is what the playground is for.
Sheet tint
glass-sheet applies material, blur, and tint to the card. Set them as attributes, or as the same props in React, Vue, and Svelte. Changing them updates an open sheet.
<glass-sheet tint="#c4622d" blur="14" material="clear" detents="medium large" aria-label="Details"> Copper glass, a little more frost. </glass-sheet>
glass-sheet::part(glass) {
border-radius: 28px;
}The shared stack is glass-sheet::part(glass). tint, blur, and material already drive that part. Use the selector when you want an extra outline or radius on top.