Apple Liquid Glass design system. Use when building UI with translucent, depth-aware glass morphism following Apple's design language. Provides CSS tokens, component patterns, dark/light mode, and animation specs.
Apple 风格半透明玻璃 UI:纵深、折射、环境光响应。
@import 'references/tokens.css'; — 详见 references/tokens.css
| 类别 | 前缀 | 示例 |
|---|---|---|
| 玻璃底 | --lg-bg-* | --lg-bg-primary |
| 模糊 | --lg-blur-* | --lg-blur-md |
| 边框 |
--lg-border-* |
--lg-border-color |
| 阴影 | --lg-shadow-* | --lg-shadow-elevated |
| 圆角 | --lg-radius-* | --lg-radius-lg |
| 动画 | --lg-duration-* | --lg-duration-normal |
| 饱和 | --lg-saturate | 1.8 |
| 特性 | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
backdrop-filter | 76+ | 103+ | 9+(-webkit-) | 79+ |
filter: saturate() | 53+ | 35+ | 9.1+ | 79+ |
linear() easing | 113+ | 112+ | 17.2+ | 113+ |
须附 -webkit-backdrop-filter。saturate() 支持广泛,但 linear() easing 较新,回退用 cubic-bezier。
/* Card — hover 上浮加深影 */
.glass-card { background: var(--lg-bg-primary);
backdrop-filter: blur(var(--lg-blur-md)) saturate(var(--lg-saturate));
-webkit-backdrop-filter: blur(var(--lg-blur-md)) saturate(var(--lg-saturate));
border: 1px solid var(--lg-border-color); border-radius: var(--lg-radius-lg);
box-shadow: var(--lg-shadow-elevated);
transition: transform var(--lg-duration-normal) var(--lg-easing-spring); }
.glass-card:hover { transform: translateY(-2px); box-shadow: var(--lg-shadow-high); }
/* Toolbar */
.glass-toolbar { background: var(--lg-bg-toolbar);
backdrop-filter: blur(var(--lg-blur-lg)) saturate(var(--lg-saturate));
-webkit-backdrop-filter: blur(var(--lg-blur-lg)) saturate(var(--lg-saturate));
border-bottom: 1px solid var(--lg-border-subtle);
position: sticky; top: 0; z-index: 100; }
/* Button — active 缩放 */
.glass-btn { background: var(--lg-bg-interactive);
backdrop-filter: blur(var(--lg-blur-sm));
-webkit-backdrop-filter: blur(var(--lg-blur-sm));
border: 1px solid var(--lg-border-color); border-radius: var(--lg-radius-md);
transition: all var(--lg-duration-fast) var(--lg-easing-spring); }
.glass-btn:hover { background: var(--lg-bg-hover); }
.glass-btn:active { transform: scale(0.97); background: var(--lg-bg-pressed); }
.glass-btn:focus-visible { outline: 2px solid var(--lg-accent); outline-offset: 2px; }
/* Modal */
.glass-overlay { background: var(--lg-bg-scrim); backdrop-filter: blur(var(--lg-blur-xl));
-webkit-backdrop-filter: blur(var(--lg-blur-xl)); }
.glass-modal { background: var(--lg-bg-elevated); border: 1px solid var(--lg-border-color);
border-radius: var(--lg-radius-xl); box-shadow: var(--lg-shadow-high); }
/* Tab Bar */
.glass-tabs { display: flex; gap: 0; background: var(--lg-bg-primary);
backdrop-filter: blur(var(--lg-blur-md)) saturate(var(--lg-saturate));
-webkit-backdrop-filter: blur(var(--lg-blur-md)) saturate(var(--lg-saturate));
border-radius: var(--lg-radius-lg); padding: 4px; }
.glass-tab { flex: 1; text-align: center; padding: 0.5rem 1rem;
border-radius: var(--lg-radius-md); transition: background var(--lg-duration-fast); }
.glass-tab[aria-selected="true"] { background: var(--lg-bg-elevated);
box-shadow: var(--lg-shadow-elevated); }
/* Notification */
.glass-toast { background: var(--lg-bg-elevated);
backdrop-filter: blur(var(--lg-blur-lg)) saturate(var(--lg-saturate));
-webkit-backdrop-filter: blur(var(--lg-blur-lg)) saturate(var(--lg-saturate));
border: 1px solid var(--lg-border-subtle); border-radius: var(--lg-radius-lg);
box-shadow: var(--lg-shadow-high); padding: 0.75rem 1.25rem; }
半透明底上文字易失对比。策略:
/* 文字底加半透明垫层,保证最低对比度 */
.glass-text-safe { text-shadow: 0 0 8px rgba(0,0,0,0.3); }
/* 或用伪元素垫底 */
.glass-label::before { content: ''; position: absolute; inset: -2px -6px;
background: rgba(0,0,0,0.25); border-radius: 4px; z-index: -1; }
暗色模式下用 rgba(0,0,0,0.5) 垫层 + 白字;亮色用 rgba(255,255,255,0.6) + 深字。
Token 经 prefers-color-scheme 自动切换。亮用白调玻璃,暗用深调配更强模糊。
:root { --lg-bg-primary: rgba(255,255,255,0.45); --lg-blur-md: 20px;
--lg-saturate: 1.8; }
@media (prefers-color-scheme: dark) {
:root { --lg-bg-primary: rgba(0,0,0,0.35); --lg-blur-md: 28px;
--lg-saturate: 2.0; --lg-border-color: rgba(255,255,255,0.08); }
}
弹簧缓动,物理质感:
@keyframes glass-enter {
from { opacity: 0; transform: scale(0.95) translateY(8px); }
to { opacity: 1; transform: scale(1) translateY(0); }
}
.glass-animate-in {
animation: glass-enter var(--lg-duration-normal) var(--lg-easing-spring) both;
}
backdrop-filter + saturate() 叠加开销大。
@media (hover: none) and (pointer: coarse) 减 blur 或用纯色will-change: transform 仅动画期间设置saturate() 单独开销低,可保留;主要瓶颈在 blur()contrast-ratio ≥ 4.5:1,用 text-shadow 或垫层兜底prefers-reduced-motion: reduce 禁弹簧动画,仅保留 opacityprefers-contrast: more 将半透明底替换为实色@media (prefers-reduced-motion: reduce) {
.glass-card, .glass-btn { transition: none; }
.glass-animate-in { animation: none; opacity: 1; }
}
@media (prefers-contrast: more) {
.glass-card { backdrop-filter: none; -webkit-backdrop-filter: none;
background: var(--lg-bg-solid, #fff); border: 2px solid var(--lg-text); }
}