把 Apple HIG 翻译成 Web 的 design tokens

Apple 的 Human Interface Guidelines 是为原生 app 写的,但其中的很多原则——层级清晰、内容优先、尊重用户的系统设置——在 Web 上一样成立。难点在于把 pt、Dynamic Type、语义色这些概念翻译成 CSS。
字号:Dynamic Type → rem
iOS 的默认字号以 pt 为单位,在 Web 上直接除以 16 换算成 rem:
| 样式 | iOS (pt) | Web (rem) |
|---|---|---|
| Large Title | 34 | 2.125 |
| Title 1 | 28 | 1.75 |
| Title 2 | 22 | 1.375 |
| Body | 17 | 1.0625 |
| Footnote | 13 | 0.8125 |
用 rem 而不是 px 的好处是:用户在浏览器里调大默认字号时,整个站点会等比放大。这差不多就是 Web 版的 Dynamic Type。
语义色
组件里不写 #000,而是写 var(--color-label)。深色模式只需要在一个地方重新定义变量:
:root {
--color-label: #000000;
--color-background: #ffffff;
}
@media (prefers-color-scheme: dark) {
:root {
--color-label: #ffffff;
--color-background: #000000;
}
}
一个和 HIG 冲突的地方
iOS 的 secondaryLabel 在白底上的对比度只有 3.4:1 左右,达不到 WCAG AA 要求的 4.5:1。原生 app 可以靠系统的“增强对比度”选项兜底,网页没有这个开关,所以这里把它的透明度从 0.6 提到了 0.75。
同理,#007AFF 作为正文链接颜色也只有约 4.0:1,链接文字单独用了更深一点的 #0066CC。
动效:弹簧曲线
CSS 的 linear() 函数可以用一串采样点描述任意曲线,于是可以把真实的阻尼弹簧方程采样后写进 CSS,而不是用 cubic-bezier 去近似。
弹簧在终点附近有约 1.4% 的回弹,幅度很小,但正是这一点让按压反馈显得“有弹性”。
评论