Skip to content
JUNGHERZPublic

About

A modern glassmorphism CSS component library inspired by iOS 26 Liquid Glass. 24 components, Dark & Light Mode, Design Tokens – no dependencies.

Topics

Resources

Stars

14 stars

Watchers

0 watching

Forks

Repository files navigation

Version CSS only Components License Changelog npm jsDelivr

🧊 GlassKit

GlassKit Preview

A modern glassmorphism CSS component library.
34 Components · Dark & Light Mode · No Dependencies · Design Tokens

Installation · Quick Start · Components · Theming · Web Components · Docs · Changelog · License

Part of the GlassKit family: GlassKit Elements (web components for app UIs) · GlassKit Web (Astro website template)


✨ What is GlassKit?

GlassKit is a complete CSS component library with glassmorphism aesthetics – inspired by iOS 26 Liquid Glass and visionOS. Apple fundamentally redefined glass design with iOS 26: deeper blur effects, luminous borders, and dynamic light reflections on surfaces. GlassKit brings exactly this look to the web – for apps and UIs that feel modern and native.

One CSS file. No build tools. No dependencies.

GlassKit is the CSS foundation of a three-layer family: GlassKit Elements builds web components for application UIs on top of it, and GlassKit Web is the official Astro template for complete websites – three layers, one design language.


Why GlassKit?

  • 🎨 Pure CSS – no JavaScript framework required
  • 🌗 Dark & Light Mode – toggle with a single attribute
  • 🎛️ Design Tokens – all values controlled via CSS Custom Properties
  • 📱 Mobile-first – optimized for touch devices and safe-area-inset
  • 🔌 Framework-agnostic – works with React, Vue, Svelte, plain HTML, or any other stack
  • 🧩 Shadow DOM ready – Constructable Stylesheet for Web Components included
  • 🪶 Lightweight – 51 KB raw / 39 KB minified / 6.5 KB gzipped, no external dependencies
  • 🎯 BEM-like naming convention – glass-* prefix, no conflicts with existing CSS
  • 🤖 AI-ready – ships with SKILL.md, a structured reference for LLMs & AI copilots

📥 Installation

GlassKit can be included in several ways – choose the one that best fits your project:

CDN (recommended for quick start)

No download, no build tool – just include and go:

<!-- jsDelivr – Minified -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/glasskit@1.22/glasskit.min.css">

<!-- jsDelivr – Unminified (for reading/debugging) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/glasskit@1.22/glasskit.css">

<!-- unpkg – Alternative -->
<link rel="stylesheet" href="https://unpkg.com/@jungherz-de/glasskit@1.22/glasskit.min.css">

Tip: Replace @1.22 with @latest for the newest version – or pin to a specific version for maximum stability.

npm / yarn / pnpm

For projects with a build pipeline:

# npm
npm install @jungherz-de/glasskit

# yarn
yarn add @jungherz-de/glasskit

# pnpm
pnpm add @jungherz-de/glasskit

Then import in your CSS or build tool:

/* In your CSS file */
@import '@jungherz-de/glasskit/glasskit.css';
// Or in JS (Webpack, Vite, etc.)
import '@jungherz-de/glasskit/glasskit.css';

Direct Download

Download the files directly from the GitHub Release:

<!-- Include locally -->
<link rel="stylesheet" href="glasskit.min.css">

<!-- Optional: custom theme -->
<link rel="stylesheet" href="theme-override.css">

🚀 Quick Start

1. Set the theme

<!-- Dark Mode (default) -->
<html data-theme="dark">

<!-- Light Mode -->
<html data-theme="light">

2. Start building

<div class="glass-bg">

  <nav class="glass-nav">
    <button class="glass-pill">
      <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
    </button>
  </nav>

  <h1 class="glass-title">Hello World</h1>

  <div class="glass-card glass-card--glow">
    <p class="glass-card__text">This is GlassKit.</p>
  </div>

  <button class="glass-btn glass-btn--primary">
    Get Started
  </button>

</div>

📦 Components

Navigation & Layout

Component Class Description
Background .glass-bg Aurora gradient with light effects
Nav Bar .glass-nav Transparent navigation
Pill Button .glass-pill Round glass icon button (46×46)
Tab Bar .glass-tab-bar Fixed bottom navigation
Tab Bar – Floating .glass-tab-bar--floating + .glass-tab-bar-dock Pill-shaped Liquid-Glass tab bar with optional .glass-tab-bar__accessory capsule
Accordion .glass-accordion Collapsible content sections
Divider .glass-divider Fading separator line

Content

Component Class Description
Title .glass-title Page title with text shadow
Card .glass-card Glass container for content
Card (Glow) .glass-card--glow Card with light-to-milky gradient
Badge .glass-badge Tags, labels & filter chips
Avatar .glass-avatar Glass circle (sm/md/lg)
Status .glass-status Notice card with icon
List .glass-list iOS-style grouped settings list with auto dividers
Skeleton .glass-skeleton Shimmer lines while content loads
Table .glass-table Plain <table> on glass — hairline rows, tabular numbers
Prose .glass-prose Rendered Markdown / running text with one class
Segmented .glass-segmented Small exclusive choice as one control, with tone dots; scrolls or wraps when crowded
Steps .glass-steps Progress through a short flow; container-query aware
Sheet .glass-sheet Bottom sheet — the mobile sibling of the modal
Empty state .glass-empty Icon, title, text and one action for empty lists

Actions & Feedback

Component Class Description
Button (Primary) .glass-btn--primary Colored gradient – primary action
Button (Secondary) .glass-btn--secondary Milky white – secondary action
Button (Tertiary) .glass-btn--tertiary Subtle glass – tertiary action
Modal .glass-modal Centered dialog with blur overlay
Toast .glass-toast Temporary notification, optionally with one action and a close button
Popover .glass-popover Anchored dropdown / menu with fade & scale animation

Form Elements

Component Class Description
Input .glass-input Text field with glass background
Textarea .glass-textarea Multi-line input
Select .glass-select Dropdown with custom chevron
Search .glass-search Input with search icon
Toggle .glass-toggle iOS-style switch
Checkbox .glass-checkbox Animated checkmark
Radio .glass-radio Animated dot
Range Slider .glass-range Slider with gradient thumb
Progress Bar .glass-progress Progress bar with shimmer
Date strip .glass-date-strip Scrolling row of day chips with tone dots
Calendar .glass-calendar One month of day buttons, up to three dots each
Image picker .glass-image-picker Preview plate, label, hint and actions for choosing one image

🌗 Theming

Dark / Light Mode

GlassKit supports two themes out of the box. Toggle via the data-theme attribute:

// Toggle
function toggleTheme() {
  const html = document.documentElement;
  const current = html.getAttribute('data-theme');
  html.setAttribute('data-theme', current === 'dark' ? 'light' : 'dark');
}

There's also a ready-made Theme Toggle component:

<button class="glass-theme-toggle" onclick="toggleTheme()">
  <svg class="icon-moon" viewBox="0 0 24 24">
    <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
  </svg>
  <svg class="icon-sun" viewBox="0 0 24 24">
    <circle cx="12" cy="12" r="5"/>
    <!-- ... rays ... -->
  </svg>
</button>

Custom Brand Colors

Create a theme-override.css and load it after the base library:

/* theme-override.css */
:root {
  --gl-color-primary:      #007AFF;
  --gl-color-primary-dark: #0055CC;
}

Since 1.11.0 that is the whole job. The gradient midpoint, the warm rim, the focus ring, the glow under the primary button and the range slider thumb are all mixed from those two — before 1.11.0 they were fixed amber, so a re-branded button came with an orange halo and an amber focus ring. Declare the brand on :root: a custom property is substituted where it is declared, so a brand set on a subtree does not re-derive the tokens inherited from :root. Every derived token is still a plain default and loses to a later declaration if you want to bend one.

The theme-override.css template comes with 4 example themes:

  • 🔵 Ocean Blue
  • 🟢 Emerald Green
  • 🌹 Rose
  • 🎨 Custom (empty, ready to fill)

Density

Admin screens, desktop layouts and narrow forms want denser controls. Set data-density="compact" on <html>, next to data-theme:

<html data-theme="dark" data-density="compact">
// Switch at runtime
document.documentElement.setAttribute('data-density', 'compact');
document.documentElement.removeAttribute('data-density');   // back to the default

Since 1.21.0 the control sizes are tokens, and the attribute swaps in a denser set. Without it every control keeps the size it has always had. Colours, type and spacing stay as they are, so nothing outside the controls moves:

Token Default Compact
--gl-control-height (input, select, search) 52px 40px
--gl-control-padding-x (input, select, textarea) unset → var(--gl-space-md) var(--gl-space-sm)
--gl-btn-height / -sm / -lg 56px / 44px / 64px 40px / 32px / 48px
--gl-textarea-min-height 120px 88px
--gl-list-item-min-height 56px 48px
--gl-list-item-padding-y unset → var(--gl-space-md) 10px
--gl-toggle-width × --gl-toggle-height 52px × 30px 44px × 26px
--gl-toggle-thumb-size 22px 18px
--gl-check-size (checkbox, radio) 24px 20px
--gl-modal-action-height 52px 44px

Every token can also be set on its own, for one density or both — the toggle's thumb and the first-line alignment of toggle, checkbox and radio follow whatever size you give:

:root                    { --gl-btn-height: 48px; }   /* default density */
[data-density='compact'] { --gl-btn-height: 36px; }   /* compact only */

Like data-theme, keep data-density on <html>: an element further down that carries data-theme="dark" re-declares the dark block, the default sizes included.

Printing

Print dialogs leave out background graphics by default, and some states are drawn with a background only. Since 1.21.1 those parts keep their colours on paper — the checked box and its tick, the chosen radio, the toggle's track, the progress fill, the current step, the chosen day of date strip and calendar, the slider thumb and the tone dots — while the rest of the page prints economically. Nothing to set.

A dark page prints its light text and surfaces on white paper. A page meant for printing switches to the light theme for it:

let printTheme = null;
addEventListener('beforeprint', () => {
  printTheme = document.documentElement.getAttribute('data-theme');
  document.documentElement.setAttribute('data-theme', 'light');
});
addEventListener('afterprint', () => {
  if (printTheme) document.documentElement.setAttribute('data-theme', printTheme);
  else document.documentElement.removeAttribute('data-theme');
});

🎛️ Design Tokens

All visual values are controlled via CSS Custom Properties:

/* Colors */
--gl-color-primary        /* Primary color */
--gl-color-text           /* Text color */
--gl-color-text-muted     /* Secondary text */

/* Glass surfaces (gradations) */
--gl-surface-1 … --gl-surface-5

/* Blur */
--gl-blur                 /* 24px – default */
--gl-blur-light           /* 16px */
--gl-blur-heavy           /* 40px */

/* Radii */
--gl-radius-card          /* 24px */
--gl-radius-btn           /* 16px */
--gl-radius-input         /* 14px */

/* Spacing */
--gl-space-xs … --gl-space-4xl

/* Density – control sizes, denser with data-density="compact" */
--gl-control-height       /* 52px – input, select */
--gl-btn-height           /* 56px; -sm 44px, -lg 64px */
--gl-check-size           /* 24px – checkbox, radio */
--gl-toggle-width … --gl-modal-action-height

/* Shadows & Insets */
--gl-shadow-card
--gl-inset-strong

/* Component hooks */
--gl-modal-max-width      /* 340px */
--gl-select-chevron       /* url(…) per theme */
--gl-toast-top            /* distance of the toast from the top */
--gl-input-prefix-size    /* room for an input prefix, 18px */
--gl-input-suffix-size    /* room for an input suffix, 18px */

The full token reference can be found in the Documentation.


🛠️ Utility Classes

/* Flex Layout */
.gl-stack              /* Vertical stack */
.gl-stack--sm          /* Gap: 12px */
.gl-row                /* Horizontal row */
.gl-row--sm            /* Gap: 12px */

/* Spacing */
.gl-mt-md              /* Margin-top: 16px */
.gl-mb-lg              /* Margin-bottom: 20px */
.gl-px                 /* Horizontal padding */

/* Text */
.gl-text-center
.gl-text-muted
.gl-text-sm

/* Layout */
.gl-w-full
.gl-flex-1

🧩 Web Components / Shadow DOM

The Shadow DOM encapsulates styles – external stylesheets like glasskit.css are not automatically inherited into the shadow tree. GlassKit therefore ships a ready-made Constructable Stylesheet that you can use directly in Web Components.

The Problem

  • CSS classes (.glass-card, .glass-btn, etc.) do not work inside the Shadow DOM
  • Only CSS Custom Properties (--gl-*) penetrate the shadow boundary automatically
  • Without a solution, each component would need to load and parse the CSS itself

The Solution: glasskit-styles.js

GlassKit provides an ES module that exports the minified CSS as a Constructable Stylesheet. The stylesheet is held once in memory and can be shared across any number of shadow roots – without duplicate parsing.

import { glassSheet } from '@jungherz-de/glasskit/glasskit-styles.js';

// In a Web Component:
class MyCard extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: 'open' });
    shadow.adoptedStyleSheets = [glassSheet];
    shadow.innerHTML = `
      <div class="glass-card glass-card--glow">
        <p class="glass-card__text"><slot></slot></p>
      </div>
    `;
  }
}
customElements.define('my-card', MyCard);

Example: Hybrids.js

GlassKit works great with lightweight Web Component frameworks like Hybrids:

import { define, html } from 'hybrids';
import { glassSheet } from '@jungherz-de/glasskit/glasskit-styles.js';

define({
  tag: 'my-card',
  render: () => html`
    <div class="glass-card glass-card--glow">
      <p class="glass-card__text">
        <slot></slot>
      </p>
    </div>
  `.css(glassSheet),
});

Example: Lit

import { LitElement, html } from 'lit';
import { glassSheet } from '@jungherz-de/glasskit/glasskit-styles.js';

class MyCard extends LitElement {
  static styles = [glassSheet];

  render() {
    return html`
      <div class="glass-card glass-card--glow">
        <p class="glass-card__text"><slot></slot></p>
      </div>
    `;
  }
}
customElements.define('my-card', MyCard);

Exports

Export Type Description
glassSheet CSSStyleSheet Ready-made Constructable Stylesheet – use directly with adoptedStyleSheets
css string CSS as string – fallback for environments without Constructable Stylesheet support

Theming in the Shadow DOM

Since CSS Custom Properties penetrate the shadow boundary, theme switching works automatically. Set data-theme on the <html> element as usual – all GlassKit tokens will be updated across all shadow roots:

// Works globally – including all Web Components
document.documentElement.setAttribute('data-theme', 'light');

data-density="compact" reaches the shadow roots the same way: the preset only sets tokens, and tokens cross the shadow boundary by inheritance.

Tip: For maximum performance with many component instances, import glassSheet once and share it across all components. The browser keeps the stylesheet in memory only once.


📁 Project Structure

glasskit/
├── glasskit.css            # Core library (all components + tokens)
├── glasskit.min.css        # Minified version (auto-generated on release)
├── glasskit-styles.js      # Constructable Stylesheet for Shadow DOM (auto-generated)
├── theme-override.css      # Template for custom themes
├── build-styles-js.mjs     # Build script for glasskit-styles.js
├── package.json            # npm package definition
├── index.html              # Landing page with iPhone wireframe
├── showcase.html           # Interactive showcase of all components
├── docs.html               # Full documentation
├── de/                     # German translations (index, docs, showcase)
├── SKILL.md                 # AI-optimized component reference (for LLMs & copilots)
├── LICENSE                  # MIT License
└── README.md               # This file

📖 Documentation

The full documentation with live previews, copy-paste code blocks, and class reference tables is available in docs.html:

  • Sidebar navigation to all 34 components
  • Live previews on a real glassmorphism background
  • Design token reference
  • Theming guide
  • Complete class overview at the end

Live pages:

🧩 The GlassKit Family

GlassKit is the CSS foundation of a three-layer family – three layers, one design language.

GlassKit Elements – the app layer

If you want to use GlassKit through drop-in Web Components instead of writing the full HTML structure yourself, take a look at GlassKit Elements.

GlassKit Elements builds on top of GlassKit CSS and provides a set of vanilla JavaScript custom elements like glk-button, glk-card, or glk-input.

Useful links:

GlassKit Web – the website layer

If you want to build a complete website rather than assemble components yourself, GlassKit Web is the intended path: the official Astro template with sections, i18n, SEO, and tests on top of the GlassKit foundation.

Useful links:


🤖 AI / LLM Reference (SKILL.md)

GlassKit ships with an AI-optimized component reference in SKILL.md. This file is designed for LLMs, AI copilots, and code-generation tools to produce correct GlassKit markup without parsing docs.html.

What it provides

  • Copy-paste-ready HTML for all 34 components with exact nesting rules
  • Complete design token tables (colors, surfaces, blur, radii, spacing, shadows, typography)
  • State class reference – which class goes where (is-active, is-open, is-visible, :checked)
  • 6 composition patterns – full page layouts (Login, Dashboard, Form, Modal, Settings, Progress)
  • Common mistakes & corrections – prevents the most frequent AI-generated errors
  • Quick reference table – all components with their modifiers at a glance

Usage with AI assistants

Attach or reference SKILL.md when asking an AI to generate GlassKit HTML. It provides the structured context needed for production-ready output – correct BEM hierarchy, proper modifier usage, and idiomatic component composition.

Tip: While docs.html is built for humans browsing with live previews, SKILL.md is built for machines generating code. Both are kept in sync.


🌐 Browser Compatibility

The floor is set by color-mix(), which derives the brand, state and focus tokens on :root (since 1.11.0):

Browser Version
Chrome / Edge 111+
Safari (iOS/macOS) 16.4+
Firefox 113+
Samsung Internet 22+

A few refinements arrive later and fall back quietly where they are missing:

  • The first-line alignment of toggle, checkbox and radio uses the lh unit (Firefox 120); without it the control sits at the top of its label.
  • List rows without a leading icon move their divider in with :has() (Firefox 121); without it the divider keeps the icon inset.
  • Right to left, the pairs that must move together — select chevron and padding, toggle thumb and travel, progress gradient — sit under :dir(rtl) (Chrome 120); without it they stay left to right.

Note: In browsers without backdrop-filter support, elements will be rendered with the defined background colors – the UI remains usable, just without the blur effect.


📋 States & Modifiers – Cheat Sheet

Page Attributes (on <html>):
  data-theme="dark" / "light"
  data-density="compact"          (denser controls)

Interactive States:
  .is-active          → Tab Bar item, Modal Overlay
  .is-open            → Accordion item, Popover
  .is-visible         → Toast
  :checked            → Toggle, Checkbox, Radio
  :focus              → Input, Textarea, Select, Range
  :disabled           → Input, Select, Textarea, Range, Toggle, Checkbox, Radio,
                        Button, Pill, Tab Bar Accessory, Modal action, list row
  [aria-disabled]     → a.glass-btn and the other buttons (link still navigates)

Button Modifiers:
  .glass-btn--primary / --secondary / --tertiary
  .glass-btn--sm / --lg / --auto

Card Modifiers:
  .glass-card--glow

Progress Modifiers:
  .glass-progress--sm / --lg
  .glass-progress--success / --error

Badge Modifiers:
  .glass-badge--primary / --success / --warning / --error
  .glass-badge--interactive / --selected   (chips)

Avatar Modifiers:
  .glass-avatar--sm / --lg

Toast Modifiers:
  .glass-toast--success / --error / --warning
  .glass-toast__action / __close   (offer with a button)
  --gl-toast-top                   (distance from the top)

Modal:
  .glass-modal__action--primary / --danger
  dialog.glass-modal-overlay       (native <dialog>, opened with showModal())
  --gl-modal-max-width             (panel width, 340px unless set)

Select:
  --gl-select-chevron              (the chevron, per theme)

Input affixes:
  .glass-input-wrap > __prefix / __suffix · --prefix / --suffix
  --gl-input-prefix-size / --gl-input-suffix-size   (room in the field, 18px unless set)

List Modifiers:
  .glass-list--flush / --bare
  .glass-list__item--interactive / --center

Popover Modifiers:
  .glass-popover--top / --start / --end

Skeleton:
  .glass-skeleton__line / __line--title

Table:
  .glass-table-wrap · .glass-table__num / __muted

Prose:
  .glass-prose   (styles the rendered content beneath it)

Segmented:
  .glass-segmented--full / --scroll / --wrap · __item[aria-pressed] · __item--success / --warning / --error · __dot

Steps:
  .glass-steps__item--done / --current · __num · __label · __line

Sheet:
  .glass-sheet-overlay.is-active · .glass-sheet--inline · __grip / __title / __body / __actions

Empty state:
  .glass-empty__icon / __title / __text / __action

Date strip:
  .glass-date-strip__day[aria-pressed] / --today / :disabled · __wd / __num · __mark--primary / --success / --warning / --error

Calendar:
  .glass-calendar__nav · __wd · __day[aria-pressed] / --today / --other / [aria-disabled] · __marks · __mark--primary / --success / --warning / --error

Image picker:
  .glass-image-picker__preview / --round · __label / __hint / __actions

Background Modifiers:
  .glass-bg--has-tab-bar
  .glass-bg--has-tab-bar-floating

Tab Bar – Floating:
  .glass-tab-bar-dock
  .glass-tab-bar--floating
  .glass-tab-bar__accessory
  .glass-tab-bar__accessory--accent / --success / --error

Right to left:
  dir="rtl" on <html> or a container – the components mirror

🤝 Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-idea)
  3. Commit your changes (git commit -m 'feat: New component XY')
  4. Push the branch (git push origin feature/my-idea)
  5. Open a Pull Request

Guidelines

  • Follow the BEM-like naming convention (glass-* prefix)
  • Use existing Design Tokens instead of hard-coded values
  • Make sure new components work in both Dark and Light Mode
  • Test on mobile (touch targets at least 44px)

📄 License

GlassKit is released under the MIT License. See LICENSE for details.

Free to use for personal and commercial projects.


📋 Changelog

All changes, bugfixes, and design decisions are documented in the CHANGELOG.md.


🏢 Credits

Developed by Jungherz GmbH


Built with 🧊 and lots of attention to detail.

About

A modern glassmorphism CSS component library inspired by iOS 26 Liquid Glass. 24 components, Dark & Light Mode, Design Tokens – no dependencies.

Topics

Resources

Stars

14 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages