Apple liquid glass iOS navigation components

By Ubaid Desai · Published August 7, 2026

10 cells1 experiment20 views0 forks

Inside this notebook

# iOS 26 Liquid Glass — 1-to-1 web recreation This notebook builds a single self-contained `liquid-glass.html`: Apple's Liquid Glass material (iOS 26 / WWDC 2025) applied to a **floating glass tab bar**, a **glass top nav bar**, and a full component set — buttons, segmented control, toggles, slider, tilt cards, settings list, menu, drag-to-dismiss sheet, ⌘K palette, toasts, tooltips — with Apple-grade motion (interruptible springs, rubber-banding, velocity inheritance) implemented from the `emilkowalski/skills` playbooks used as the baseline. No frameworks, no CDNs, no build step: one HTML file with all CSS/JS/SVG inlined. This sandbox is Python-only (no browser), so the artifact is **statically verified** here and runs in your browser via the platform's HTML preview. Grounded in: the Liquid Glass definition from liquidglassdesign.com [^1], the refraction/highlight technique controls from the Liquid UI generator [^2], the clear/regular/frosted material tiers from OpenGlass UI [^4], and the `skills` baseline (apple-design, animate recipes, review-animations standards).

## Design spec — material anatomy & motion system ### What "Liquid Glass" is > "Liquid Glass is the translucent interface material Apple introduced at WWDC 2025 and shipped across iOS 26, iPadOS 26, and macOS 26 Tahoe — its biggest visual change since iOS 7. Rather than simply blurring what sits behind it, [the material] refracts content like a real lens, picks up specular highlights as the device moves, adapts its tint to whatever passes underneath" [^1]. So a faithful web recreation needs **four simultaneous effects** — not just a blurred card: 1. **Blur + saturation** of real content behind the surface (`backdrop-filter`). 2. **Refraction** — a lens-like distortion layer over the backdrop (SVG `feDisplacementMap` lens filter + slight magnification) [^2]. 3. **Specular highlights** — a bright top-edge light line + a sheen that moves with the pointer/device. 4. **Dynamic tint** — the material's hue washes with what's under/around it (implemented as a spring-driven accent-hue layer that follows the active tab/segment). ### The 5-layer CSS recipe (per glass component) | Layer | Technique | |---|---| | 1 · Frosted backdrop | `backdrop-filter: blur(var(--blur)) saturate(var(--sat))` | | 2 · Tint fill | translucent gradient (light/dark) **+** dynamic `hsl(var(--accent-h) …)` wash | | 3 · Hairline rim | 1px gradient border via `background: … padding-box, … border-box` (bright top-left → soft bottom-right) | | 4 · Specular edge | `::after` radial top sheen; cursor-following `-…

# ============================================================
# CSS part 1 — design tokens + glass materials
# Defines CSS_TOKENS: palette (light/dark), wallpaper, the 5-layer
# glass material (.lg + tiers), refraction filter, keyframes,
# reduced-motion / reduced-transparency handling.
# ============================================================

CSS_TOKENS = r"""
/* ============ Liquid Glass — design tokens & materials ============ */
*, *::before, *::after { box-sizing: border-box; }

:root {
  color-scheme: light;

  /* ---- core palette ---- */
  --bg: #eef2f8;
  --ink: #1b1d24;
  --ink-2: rgba(27, 29, 36, .56);
…
# ============================================================
# CSS part 2 — nav bars & every component
# Defines CSS_COMPONENTS: top bar, tab bar, buttons, segmented,
# toggle, slider, tilt cards, list rows, menu, sheet, palette,
# toast, tooltip, layout + responsive.
# ============================================================

CSS_COMPONENTS = r"""
/* ============ Layout ============ */
.content {
  max-width: 860px; margin: 0 auto;
  padding: 148px 22px 150px;
  position: relative; z-index: 1;
}
section { margin-bottom: 26px; }
.sec-t {
  font: 700 12.5px var(--font); letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-3); margin: 30px 4px 12px;
…
# ============================================================
# HTML markup + inline SVG icon set (SF-Symbol-style paths)
# Defines HTML_BODY: wallpaper, top bar, tab bar, all component
# instances, overlays, and the hidden SVG defs (lens filter +
# icon symbols).
# ============================================================

HTML_BODY = r"""
<div class="bg" aria-hidden="true"></div>
<div class="orb orb-a" aria-hidden="true"></div>
<div class="orb orb-b" aria-hidden="true"></div>
<div class="grain" aria-hidden="true"></div>
<div class="veil" id="veil" aria-hidden="true"></div>

<header class="topbar lg" id="topbar">
  <div class="lg-refract" aria-hidden="true"></div>
  <div class="tb-row">
    <div class="tb-titles">
…
# ============================================================
# JS — spring engine & all interactions
# Defines JS_APP: interruptible spring solver, tab pill, sheet
# drag with rubber-band + velocity dismiss, tilt cards, palette,
# menu, tooltip, toasts, theme, dynamic tint, keyboard, ambient
# parallax, reduced-motion handling.
# ============================================================

JS_APP = r"""
(() => {
'use strict';

/* ---------- helpers ---------- */
const $  = (s, r) => (r || document).querySelector(s);
const $$ = (s, r) => Array.from((r || document).querySelectorAll(s));
const clamp = (v, a, b) => Math.max(a, Math.min(b, v));
const RM = matchMedia('(prefers-reduced-motion: reduce)').matches;
const FINE = matchMedia('(pointer: fine)').matches;
…
# ============================================================
# Assemble → liquid-glass.html (single self-contained file)
# Joins the CSS/HTML/JS parts and writes /home/user/liquid-glass.html
# (auto-persisted to outputs after this cell runs).
# ============================================================
from pathlib import Path

CSS_ALL = CSS_TOKENS + CSS_COMPONENTS

DOC = """<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark">
<title>Liquid Glass — iOS 26 design system</title>
<style>
""" + CSS_ALL + """
…
liquid-glass.html written: 64.2 KB, 1408 lines
  css    29.3 KB   html   15.9 KB   js   18.7 KB
saved to /home/user/liquid-glass.html → auto-persisted to outputs
# ============================================================
# Static verification of liquid-glass.html
# No browser in this sandbox, so we verify structurally:
# tag balance, zero external references, JS brace/paren balance,
# every referenced id/symbol resolves, all components present.
# ============================================================
import html.parser
import re
from pathlib import Path

src = Path('/home/user/liquid-glass.html').read_text(encoding='utf-8')
issues = []

# 1) size / shape
size_kb = len(src.encode('utf-8')) / 1024
print(f"size: {size_kb:.1f} KB · {src.count(chr(10)) + 1} lines · doctype: {'<!DOCTYPE html>' in src}")

# 2) no external references (everything must be inline)
…
size: 64.2 KB · 1408 lines · doctype: True
external http refs: 0 · @imports: 0 · external css urls: 0
tag balance errors: 0 · unclosed at EOF: none
ids defined: 61 · referenced by JS: 32 · missing: none
svg symbols: 27 · static uses: 23 · js icon refs: 6 · missing: none
js balance errors: 0 · unclosed: none · open string at EOF: none
components: 21/21 present · missing: none

ALL CHECKS PASSED ✓  —  open liquid-glass.html in a browser to render it

> **Note:** a temporary diagnostic probe was used here during verification to debug the static checker (a `\b`-in-non-raw-string regex bug and a string-mode bug in the JS balance checker). Both were fixed in the verification cell — the artifact itself was never affected, and the final file passes every check.

## Summary — what's inside & how to tune it **Deliverable:** `liquid-glass.html` — one self-contained file (64 KB, 0 dependencies, 0 external requests), statically verified above. **Nav bars (the core ask):** - **Floating glass tab bar** — iOS-26-style pill with a spring-driven sliding indicator (k=460), specular top edge, refraction layer, per-tab dynamic tint (Home 215° → Browse 265° → Music 330° → Wallet 160° → Settings 28°). - **Glass top nav bar** — large-title → compact on scroll (continuous scale/fade, 1:1 with scroll), glass toolbar with search field, ⌘K and theme buttons, avatar. **Component set:** primary/glass/soft/danger buttons (sheen sweep on primary, 160ms press), segmented control with spring indicator (also drives the accent tint), iOS toggles, draggable slider (keyboard arrows too), 3D-tilt cards with cursor-tracking glare, settings-style list rows with badges, origin-anchored menu, **drag-to-dismiss sheet** (1:1 drag → rubber-band → velocity-inheriting spring), ⌘K command palette with keyboard nav, toasts, tooltips. **The material:** 5 layers per surface — `backdrop-filter` blur+saturation, translucent tint + dynamic hue wash, 1px hairline rim, specular top sheen, and SVG-`feDisplacementMap` refraction with pointer parallax; clear/regular/frosted tiers; light/dark themes; `prefers-reduced-motion` (snap, no springs) and `prefers-reduced-transparency` (frostier, no blur) respected. **Tuning knobs:** spring stiffness/damping in the `springSet(...)` calls…

Apple liquid glass iOS navigation components | Clusy