Glassmorphism

iart-ai/web-animation-skills/skills/glassmorphism

作者 iart-aib6dba3eb7597無授權條款34 個星標收錄於 2026年10月9日更新於 2026年10月8日儲存庫3 個月前更新

This skill should be used when the user asks to "add a glassmorphism effect", "frosted glass UI", "Apple liquid glass style", "frosted blur card", "translucent glass panel animation", "make a frosted nav bar", "build a glass modal/dialog", "animate a glass card on hover", or "add a refracting liquid-glass hero". Covers frosted translucent panels with backdrop-filter blur, edge/specular highlights, SVG liquid-glass refraction, motion on hover/scroll/enter, and accessible reduced-transparency fallbacks.

僅含說明Design & Creative
AI 產生的概覽

用獨立 HTML 打造磨砂與液態玻璃擬態介面效果,包含 CSS 模糊、邊緣高光、動效與無障礙回退。

功能
此技能提供製作半透明磨砂玻璃介面元素(例如卡片、導覽列、模態框與主視覺面板)的指引與可直接複製的配方。內容涵蓋可信玻璃的四個要素(磨砂、半透明、邊緣高光、層次深度)、鏡面高光、抗色帶雜訊、懸停與進場動效,以及用於液態玻璃效果的 SVG feDisplacementMap 折射。它也規定交付物為單一自包含 HTML 檔案,並附上凍結測試框架以便產生確定性截圖,同時說明效能限制以及減少透明度、減少動態效果與 @supports 回退方案。
適用情境
當使用者要求加入玻璃擬態效果、磨砂玻璃介面、Apple 液態玻璃風格、半透明面板動畫,或磨砂導覽列、模態框、主視覺時使用。它適合需要漂浮在複雜或照片背景之上且保持可讀性的面板。
執行需求
交付物不需要建置步驟或套件,只需一個包含內嵌 CSS 與選用內嵌 SVG 的獨立 HTML 檔案。驗證範例引用 npx playwright screenshot 與無頭瀏覽器算繪;文件也提到封裝的輔助指令碼(scripts/seek-shot.sh、scripts/contact-sheet.sh)與 scripts/README.md,但提供的檔案清單中僅有 README.md 和 references/glass-recipes.md。

Glassmorphism (Frosted & Liquid Glass)

Translucent, frosted UI: panels you can see through, blurred so the backdrop reads as soft color, rimmed by a bright edge of light, floating on layered shadow. The 2026 "liquid glass" evolution adds refraction — the background visibly bends through the panel — plus moving specular highlights. The goal is depth and material, not just opacity.

When to use

  • Frosted cards, nav bars, sidebars, modals/dialogs, and toolbars over busy/photo backgrounds
  • Login/hero panels and overlays that should feel layered above the page
  • Apple-style "liquid glass" heroes: refracting, slowly churning surfaces with a specular sweep
  • Hover/scroll/enter motion on glass — frost deepening, highlight brightening, the panel lifting
  • Any place where content needs to read as floating glass while staying legible

The four ingredients of believable glass

Glass is never one property. Every panel needs all four, or it reads as a plain translucent box:

  1. Frost — backdrop-filter: blur() plus saturate() to keep backdrop color vivid through the blur.
  2. Translucency — a background with alpha (~0.08–0.18), never fully opaque, never fully clear.
  3. Edge of glass — a hairline border brighter than the fill, ideally a lit top-left → dim bottom-right highlight, so the rim catches light.
  4. Depth — layered box-shadow: an ambient drop shadow to float it, plus an inset top highlight and bottom shade to round the surface.
css
.glass {  background: rgba(255, 255, 255, 0.12);  backdrop-filter: blur(16px) saturate(160%);  -webkit-backdrop-filter: blur(16px) saturate(160%); /* Safari needs the prefix */  border-radius: 20px;  border: 1px solid rgba(255, 255, 255, 0.25);  box-shadow:    0 8px 32px rgba(0, 0, 0, 0.25),     /* float */    inset 0 1px 0 rgba(255, 255, 255, 0.35), /* top highlight */    inset 0 -1px 0 rgba(0, 0, 0, 0.12);      /* bottom shade */}

Frost tiers: light UI chrome blur(8–12px) / alpha 0.08–0.14; heavy modal/login blur(24–40px) / alpha 0.10–0.18. Dark glass: fill rgba(0,0,0,0.3), softer top highlight.

backdrop-filter only blurs content that sits behind the element. Over a flat background color it does nothing visible — glass needs a busy backdrop (image, gradient, video) to frost.

Specular edge highlight and anti-banding grain

A flat border is dead. Draw a masked 1px ring with a lit corner via ::before, and dither away gradient banding (stepped contour lines under heavy blur) with a faint feTurbulence noise overlay via ::after at opacity ≤ 0.06. Full masked-border and inline-noise recipes are in references/glass-recipes.md.

Motion: animate the glass, not the geometry

Animate the qualities of the glass — frost deepening, highlight brightening, the panel lifting — so it reads as the surface "leaning into the light."

css
.glass {  transition: backdrop-filter .4s ease, background .4s ease,              box-shadow .4s ease, transform .4s cubic-bezier(.16,1,.3,1);}.glass:hover {  backdrop-filter: blur(24px) saturate(180%);  background: rgba(255,255,255,.18);  transform: translateY(-4px);  box-shadow: 0 16px 48px rgba(0,0,0,.3), inset 0 1px 0 rgba(255,255,255,.5);}
  • Entrance (frost resolving from clear): pair a [data-enter] transition with @starting-style { backdrop-filter: blur(0); opacity: 0; transform: translateY(16px) }.
  • Specular sweep: a skewed white gradient animated across the surface on hover or as a slow ambient loop.
  • Caveat: animating the blur radius is the most expensive thing here — the backdrop is re-blurred every frame. If hover janks, animate transform/box-shadow/background (cheap) and keep the blur delta small or snap it.

Liquid glass — SVG refraction (the 2026 look)

Bend the background through the panel like a thick lens: drive feDisplacementMap from animated feTurbulence, applied via filter (it distorts the element's own pixels) layered over a backdrop-filter frost.

html
<svg width="0" height="0" style="position:absolute"><filter id="liquid-glass">  <feTurbulence type="fractalNoise" baseFrequency="0.008 0.012" numOctaves="2" seed="3" result="n">    <animate attributeName="baseFrequency" dur="18s"             values="0.008 0.012;0.012 0.008;0.008 0.012" repeatCount="indefinite"/>  </feTurbulence>  <feDisplacementMap in="SourceGraphic" in2="n" scale="22" xChannelSelector="R" yChannelSelector="G"/></filter></svg>

scale = refraction strength (8–14 subtle, 20–30 pronounced, >40 molten). Lower baseFrequency = larger, slower waves (more liquid). Keep the animate dur long (12–20s) so it breathes. These filters are heavy — use on one hero element, not a grid.

Performance — backdrop-filter is expensive

  • Each glass element re-samples and blurs everything behind it. Limit the count; a dozen on screen tanks scroll FPS.
  • Promote heavy glass to its own layer (transform: translateZ(0) or will-change: transform), and remove will-change after the animation.
  • Don't stack backdrop-filter elements over each other — nested blur re-blurs the blur (quadratic cost).
  • Big radii (>40px) over large areas are the worst case; cap radius and panel size.

Accessibility — non-negotiable

Glass is decoration; content must stay legible and the effect must be defeatable.

css
@media (prefers-reduced-transparency: reduce) {  .glass { background: #1a1a2e; backdrop-filter: none; -webkit-backdrop-filter: none; }  .glass::after { display: none; }            /* drop grain */}@media (prefers-reduced-motion: reduce) {  .glass { transition: none; }  .liquid { filter: none; }                   /* stop the refraction churn */}@supports not (backdrop-filter: blur(1px)) {  .glass { background: rgba(30,30,50,.85); }  /* opaque-enough fallback */}

Contrast over busy backgrounds: translucent panels over photos can drop text below WCAG. Add a semi-opaque scrim or darkening gradient under the text, optionally text-shadow: 0 1px 2px rgba(0,0,0,.4), and verify ≥ 4.5:1 body / ≥ 3:1 large against the brightest region of the backdrop.

Deliver & verify (standalone HTML)

Packaged helper (scripts/): scripts/seek-shot.sh anim.html 0 1.5 3 freezes the ?t=N harness and screenshots each moment; scripts/contact-sheet.sh sheet.png frame-*.png tiles them for one-glance review. See scripts/README.md.

For a self-contained glass demo (card, nav, modal, liquid-glass hero) the deliverable is one HTML file that opens directly in a browser — markup, CSS, and (if liquid) one inline SVG filter, no build step. A single file is the right tier for a glass surface; don't reach for a bundler. The panel must overlap a real backdrop (drop in a photo or gradient) or there is nothing to frost and the demo lies.

Output contract:

  • One .html file: a busy backdrop, your glass markup, the CSS (frost + edge highlight + grain + shadows), and any inline SVG feDisplacementMap filter.
  • A way to land on the resolved state and a frozen frame of any loop — glass verifies by both state (rest/hover/enter) and time (the sweep/refraction).
  • Include the freeze harness below so any moment can be pinned for inspection.

Seek harness — pin a deterministic state + frame. ?state=hover forces the hover look; ?t=N freezes CSS animations and the SVG refraction at N seconds, so a screenshot lands on a still, deterministic frame:

html
<script>  const p = new URLSearchParams(location.search);  const state = p.get("state");  if (state) document.documentElement.dataset.state = state;   // CSS keys off :root[data-state="hover"]  const t = p.get("t");  if (t !== null) {    document.getAnimations().forEach(a => { a.currentTime = parseFloat(t)*1000; a.pause(); }); // freeze CSS sweep    const svg = document.querySelector("svg");    svg?.pauseAnimations?.(); svg?.setCurrentTime?.(parseFloat(t));                            // freeze refraction  }  window.__ready = true;</script>

Verify loop — render → set state/freeze → screenshot → check: open each meaningful state (?state=rest, ?state=hover) and a frozen loop frame (?t=2), screenshot, and confirm the glass reads as glass — blur and edge highlight visibly present, no color banding, text contrast holds over the backdrop — plus check artifacts (flat box because the backdrop is plain color, missing -webkit- prefix in Safari, refraction too strong/molten, jank from animating blur). Then load prefers-reduced-transparency and confirm the solid fallback renders legibly. Any headless tool works:

bash
npx playwright screenshot --wait-for-timeout=500 "file://$PWD/glass.html?state=hover" hover.pngnpx playwright screenshot --wait-for-timeout=500 "file://$PWD/glass.html?t=2"          loop.png

To check the fallback headlessly, emulate the media feature (e.g. Playwright --color-scheme-style flags, or a ?reduced=1 query that toggles a class mirroring the media query) and screenshot that the panel is solid and readable.

Before you finish:

  1. Opens standalone — no console errors; the glass overlaps a real busy backdrop, not a flat color.
  2. Reads as glass — blur + bright edge highlight both visible, layered shadow floats it, no banding (grain present).
  3. Text contrast holds over the brightest part of the backdrop (≥ 4.5:1 body).
  4. ?state= / ?t=N freeze lands a deterministic, settled frame.
  5. prefers-reduced-transparency → solid opaque panel; prefers-reduced-motion → refraction/sweep stopped; @supports fallback for no backdrop-filter.
  6. Performance sane — glass count limited, blur not animated on a janky path, liquid refraction on one element only.

Quick reference

NeedApproach
Base frostbackdrop-filter: blur(16px) saturate(160%) + alpha bg
Edge of glassbrighter border + masked ::before lit-corner ring
Float / depthbox-shadow drop + inset top highlight & bottom shade
Kill bandingfeTurbulence noise ::after, opacity ≤ .06
Hover motiontransition transform/box-shadow/background, small blur delta
Entrance@starting-style { backdrop-filter: blur(0); opacity:0 }
Liquid refractionfeDisplacementMap ← animated feTurbulence, via filter
Specular sweepskewed white gradient animated across surface
Safarialways pair -webkit-backdrop-filter
Reduced transparencysolid opaque panel, drop grain
No backdrop-filter@supports not (...) opaque-enough fallback

Reference files

  • references/glass-recipes.md — full copy-paste recipes: base glass card with tiers, the masked specular edge ring, anti-banding grain, hover/enter/scroll motion, the specular sweep, the SVG feDisplacementMap/feTurbulence liquid-glass filter with tuning knobs, performance rules, the reduced-transparency/reduced-motion/@supports fallbacks, contrast defenses, and the standalone freeze harness.

來源與署名

來源:iart-ai/web-animation-skills位於skills/glassmorphism提交b6dba3e

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架