← ClaudeAtlas

safari26-liquid-glasslisted

How iOS 26 / iPadOS 26 Safari's "Liquid Glass" translucent status & address bars interact with web content, the viewport/keyboard facts behind them, and what to watch for when a design gets creative (immersive/edge-to-edge layouts, custom drawers/modals, gesture panning, themeable backgrounds, canvas). Use when an iPhone/iPad web page shows black/grey bars, content "cut off" at the bar edge, cropped shadows, the top status bar turning opaque/tinted under a sticky or fixed header, a drawer/modal that breaks the layout, an inner scroll that won't scroll, the page jumping after the soft keyboard closes, or a canvas blur that won't render on iOS — or before building any full-screen/immersive iOS web UI.
stealth-engine/skills · ★ 2 · Web & Frontend · score 76
Install: claude install-skill stealth-engine/skills
# Safari 26 "Liquid Glass" — facts, gotchas, and what to do ## 1. The model iOS 26 and iPadOS 26 gave Safari a "Liquid Glass" chrome: the **status bar** (top) and the **address/tab bar** (bottom) are **translucent overlays** that show whatever the page paints **behind them**, live, as you scroll. Apple **dropped `theme-color`** as the bar tint — the bars just reflect the page now. This is the **iPhone Safari layout model**. It also applies on **iPadOS** — and there it's gated by the **browser window width**, not the device: a narrow Safari window (Split View, Slide Over, a portrait small iPad, or just a narrow window) gets the iPhone model with the glass bars; a wide one gets the desktop-ish model. **So decide "is this the glass model?" by width, not by user-agent** (e.g. `innerWidth <= 760`), because the same iPad flips between the two. Think of the screen as **two viewports**: - **Layout / large viewport** — the full physical screen, *including* behind both bars. `100vh`, `100lvh`, and `window.innerHeight` all measure **this large viewport**. **`innerHeight` is constant** — it does NOT change when the bars show/hide or the keyboard opens. - **Visual / small viewport** — only the area *between* the bars. `window.visualViewport.height` and `100svh` measure this; **`100dvh`** tracks it dynamically (it shrinks when the keyboard opens). So on this model **`innerHeight` = the large viewport** (constant), while `visualViewport.height` = the small viewport (changes)