button · glass-apple · 灵感来源:Apple Vision Pro / iOS 26 Liquid Glass
Liquid Glass Button · 液态玻璃按钮 · 按钮 / Glass
做一个 Liquid Glass Button(液态玻璃按钮):
- 半透明底 + 1px 细边框 + 背景模糊,做出玻璃厚度
- 双阴影:外阴影抬起,内高光做顶部反光
- sm / md / lg 三档尺寸 + pill 变体 + disabled
- 按压缩放 0.97、悬停放大 1.02(全站统一值)
用这些 CSS 变量:--color-text --color-text-muted --color-text-subtle --dur-fast --ease-standard --glass-bg --glass-border --glass-highlight --glass-inset --glass-recess --shadow-md --text-base --text-xs
灵感参考:Apple Vision Pro / iOS 26 Liquid Glass--color-text --color-text-muted --color-text-subtle --dur-fast --ease-standard --glass-bg --glass-border --glass-highlight --glass-inset --glass-recess --shadow-md --text-base --text-xs
焦点 / 按压 / 禁用
/r/button--glass-apple.json
免外壳的 markdown 版:/llms/components/button--glass-apple.md.press-hover)、按压回落 0.97(.press-feedback)——全站只有这两个缩放值变量:--glass-bg(surface 28%)/ --glass-border(ink 7%)/ --glass-highlight(surface 85%)——都从 base 层派生,改一处全站跟着变。
2026-08 调轻:暗色玻璃 → 浅色白磨砂(Light Liquid Glass),阴影换冷灰 --shadow-md。
import { type ButtonHTMLAttributes, type ReactNode } from 'react';
import { Spinner } from '~/components/Feedback';
type Variant = 'default' | 'pill';
type Size = 'sm' | 'md' | 'lg';
interface GlassAppleButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
children: ReactNode;
variant?: Variant;
size?: Size;
/** 加载中:转圈 + 禁用 + aria-busy(宽度不变,内容变淡) */
loading?: boolean;
}
const sizeClasses: Record<Size, string> = {
sm: 'px-4 py-1.5 text-sm',
md: 'px-6 py-2.5 text-base',
lg: 'px-8 py-3.5 text-lg',
};
const variantClasses: Record<Variant, string> = {
default: 'rounded-2xl',
pill: 'rounded-full',
};
export function GlassAppleButton({
children,
variant = 'default',
size = 'md',
loading = false,
className = '',
...rest
}: GlassAppleButtonProps) {
const spinnerSize = size === 'lg' ? 16 : size === 'md' ? 14 : 12;
return (
<button
{...rest}
aria-busy={loading || undefined}
disabled={loading || rest.disabled}
className={`
relative
${sizeClasses[size]}
${variantClasses[variant]}
font-medium
text-[var(--color-text)]
bg-[var(--glass-bg)]
border border-[var(--glass-border)]
backdrop-blur-xl
shadow-[var(--shadow-md),var(--glass-inset)]
press-feedback press-hover
transition-[background-color,border-color,box-shadow,transform,opacity] duration-[var(--dur-fast)] ease-[var(--ease-standard)]
hover:bg-[var(--glass-highlight)]
hover:border-[rgba(29,31,38,0.14)]
disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:scale-100
cursor-pointer
${className}
`}
>
{loading && <Spinner size={spinnerSize} className="mr-2 align-[-0.125em]" label="加载中" />}
<span className={loading ? 'opacity-60' : ''}>{children}</span>
</button>
);
}
src/components/button/glass-apple/