chapter[9] · part 2 / 程序员的界面美学

Web App 的 UI/UX

Web 的本质是弹性。控制每个像素的想法,是从印刷带过来的乡愁。 约翰·奥尔索普(John Allsopp),《Web 之道》(A Dao of Web Design),2000

所有平台里,Web 是唯一一个不知道自己画布多大的。一幅画有画框,一个 iPhone App 有几种已知尺寸,而同一个网页要同时活在 320px 宽的旧手机和 5120px 的带鱼屏上,用户还会随手缩放窗口、调大字号。所以 Web 美学的核心命题与画布美学不同:不是设计一个完美的版面,而是设计一套在任何尺寸下都能产出体面版面的规则。这正是上一章"系统思维"的主场。

9.1栅格与断点:弹性中的秩序

Web 排版的主流方案是十二列栅格。十二不是随便选的:它能被 2、3、4、6 整除——同一套栅格可以摆两栏、三栏、四栏、六栏,是组合自由度最大的小数字(古腾堡选 42 行也是同类考虑)。元素不再用像素定位,而是声明"我占几列":

桌面 ≥1024px:12 列全开 header=12col · nav=3col · main=6col · aside=3col 平板 ~768px:8 列 侧栏降为底部并排:8col 容不下三栏 手机 ~375px:4 列单栏 一切堆叠:顺序=重要性 同一套内容 改变的不是设计,是栅格的列数
图 9-1 · 响应式栅格的三种状态 · 本书绘制 一套规则,三种版面 注意手机版的关键决定不是"缩小",而是重排:侧栏内容掉到主内容之后——单栏世界里,文档流顺序就是视觉层级(7.1),所以移动端设计的第一问题是排序,不是缩放。

断点(breakpoint)放在哪?错误答案:按设备型号("iPad 是 768")——设备名单永远追不完。正确答案是内容优先(content-out):从最窄开始拉宽窗口,哪里开始变难看,哪里就是断点。最常触发断点的信号正是第四章的行长——正文超过 75 字符/40 汉字时,要么锁住 max-width,要么分栏。本书的 720px 版心就是这样定下的(你可以拉宽浏览器验证:正文永远不会变成一行一百字)。

9.2表单:Web 的核心仪式

Web App 的灵魂交互是表单——注册、下单、配置,钱都是在表单里付的。表单美学的特殊性在于:它的美几乎完全等于低摩擦。没人欣赏表单,人只想穿过它。规则相应非常收敛:

双列 + 占位符当标签 姓名 电话 邮箱 身份证号 格式错误! 详细地址 提交 重置

双列迫使视线走 Z 字;占位符即标签——开始输入后标签消失,回头检查时每个框都成了谜语;错误信息只说"错误"不说怎么改;"重置"按钮和提交同等显眼,等着用户误触清空一切。

单列 + 标签在上 手机号 138 0013 8000 验证码 已发送 (52s) 验证码是 6 位数字,请检查最新一条短信 登录

单列一条路走到底;标签永远在场;错误信息出现在出错字段的正下方,并且告诉用户怎么改;唯一的主按钮文案写动作本身。每屏只问必要的问题——字段是有成本的,每个字段都在流失转化。

程序员视角

表单是错误处理的 UI 化,可以直接套 API 设计的好品味:错误要就地抛出(字段下方,不是页顶汇总弹窗)、要可恢复(说明怎么改,保留已填内容)、要尽早校验(失焦即验,而不是提交后整页报错——相当于编译期检查 vs 运行时崩溃)。还有一条纯工程的美德:用对 input typeautocomplete 属性,让浏览器自动填充能工作——最美的表单是用户根本不用打字的表单。

9.3数据密度:仪表盘的美学

消费类产品的留白哲学(7.5)搬到管理后台和数据工具上会失灵:交易员、运营、医生需要的是一屏看到尽量多的信息。这不是七原则失效,而是参数变了——信息设计大师爱德华·塔夫特(Edward Tufte)给过这类界面的北极星:数据墨水比(data-ink ratio)——图表中用于呈现数据的墨水,占总墨水的比例,越高越好。装饰性的网格线、边框、底纹、立体效果都是"非数据墨水",逐项审判,能删则删:

装饰淹没数据 产品销量环比 智能手表12,480↑8% 无线耳机9,032↓3% 充电宝7,651↑12% 手机壳21,007↑1%

深色表头、斑马纹、全套内外边框三件套全上:每行数据被五条线包裹。数字本身(数据墨水)只占总墨水的一小半,而且数字左对齐——位数没法竖向比较。

墨水还给数据 产品 销量 环比 智能手表12,480+8% 无线耳机9,032−3% 充电宝7,651+12% 手机壳21,007+1%

只剩两条横线:一条分隔表头(粗),一条收尾(细)。行的分隔交给行距(亲密性!),数字改用等宽字体右对齐——千位竖向对齐,扫一列就能比大小。同样数据,密度反而更高了。

9.4暗色模式:语义层的成人礼

暗色模式是检验你第八章作业的考场——如果界面代码全部引用语义 token,暗色模式就是重写一张映射表;如果到处硬编码,那就是一场灾难。但映射表怎么写也有讲究,三条规则全部来自第一部分:

9.5时间维度:感知性能也是美学

Web 美学有一个画布没有的维度:等待。研究反复确认:用户对"快"的感受只和感知相关,与毫秒数关系松散——有反馈的 2 秒比死寂的 1 秒更"快"。所以加载体验值得当成版面一样设计:骨架屏胜过转圈(它承诺了即将出现的版面结构,等待变成了"正在显影");乐观更新(点赞先变红再发请求)把网络延迟从体验里整段删除;超过数秒的操作给真实进度而不是无限转圈。一个处处即时响应的朴素界面,体验上"美"过一个每次点击都卡 800ms 的精美界面——流畅是美感的入场券。

9.6无障碍:把可用性扩展到所有人

第一章那条"美即可用性"还有一个常被跳过的推论:可用性的分母是"所有用户",不是"视力正常、用鼠标、不晕动画的那部分用户"。无障碍(accessibility,常缩写 a11y)不是合规负担,也不是慈善,它是可用性的逻辑完成。有个词叫缘石坡道效应(curb-cut effect):为轮椅修的斜坡,最后推婴儿车、拉行李箱、骑滑板的人都在用——为边缘情况做的设计,几乎总能让所有人受益。给聋人做的字幕,今天在地铁里、在深夜不便外放时,人人都在用。对程序员来说,无障碍尤其友好,因为它的大部分要求是可量化、可自动检测的,跟 lint 一样。四根支柱:

① 对比度:正文 ≥ 4.5:1(WCAG AA) 这行浅灰字几乎飘在纸上 ≈2.2:1 ✗ 中灰字勉强能读,但仍不达标 ≈3.5:1 ✗ 次要墨色,达标且不刺眼 ≈7:1 ✓ 正文墨色,最稳的选择 ≈13:1 ✓ 同样四行字,你能亲眼看出上两行有多费劲——这就是 4.5:1 想消灭的东西 ② 不只靠颜色(约 8% 男性红绿色弱) ✗ 只用颜色区分对错: 密码已保存 密码已保存 色弱用户眼里这两行可能 几乎一模一样——信息丢失 ✓ 颜色 + 图标 + 文字: 成功 失败 形状和文字承载了同样的 信息,颜色只是加成
图 9-2 · 无障碍的两根可视支柱 · 本书绘制 看得见的无障碍:对比度与冗余编码 左边的对比度阶梯请用身体感受——上两行不是"风格淡雅",是真的让一部分人读不了。设计师爱用浅灰细字追求"高级感",常常一脚踩进 ✗ 区(回链第三章:界面显脏是饱和度,显费劲常是对比度)。右边复刻第三章的色弱铁律:颜色永远只能是冗余信息,绝不能是唯一信息——加一个对钩/叉的形状,色弱用户和黑白截图里的所有人都得救了。

另外两根支柱看不见,但同样是硬指标:③ 焦点可见——能用 Tab 键走完整个流程吗?每个可聚焦元素都有清晰的焦点环吗(就是 8.7 状态矩阵里那一列,别用 outline:none 删掉它)?这是键盘用户和读屏用户的唯一导航方式。④ 尊重动效偏好——有些用户会因动画产生眩晕(前庭功能障碍),操作系统给了他们一个"减少动态效果"的开关,你的 CSS 要听:@media (prefers-reduced-motion: reduce) 里把非必要动画关掉。第十二章那些华丽的转场,在这个开关下应当优雅退化为瞬时切换。

程序员视角

无障碍是少数"投入产出比高到离谱"的设计工作,因为大半是免费的副产品:用语义化 HTML<button> 而不是 <div onclick>)就自动获得键盘可聚焦、可回车触发、读屏可识别——你每用一个正确的标签,就替三类用户解决了问题。给图片写 alt、给图标按钮加 aria-label、表单 <label> 关联 for,加起来不到几分钟。再配上工具链:Lighthouse / axe 能自动扫出对比度和缺失标签,扔进 CI 就像跑测试。无障碍的反面不是"没做特性",是"亲手用 div 拆掉了浏览器免费送你的可用性"。

核心概念

Web 平台的四个特有美学维度:弹性(为规则设计而不是为版面设计)、密度(数据墨水比,按用户任务校准)、时间(感知性能是体验的一部分)、可达(可用性的分母是所有人)。七原则在这四个维度上全部继续成立,只是从"一幅画"推广成了"一族画,给所有人看"。

鉴赏练习 9

三连查。① 弹性:把你的项目(或任意常用网站)从 320px 拉到 2560px,记录每个"开始变难看"的宽度,对照它实际的断点——断点是 content-out 还是 device-in?② 密度:找一张你后台里的数据表格,数一数非数据墨水(边框、底纹、斑马纹),按 9.3 的减法重画一版。③ 时间:用 DevTools 把网络限到 Slow 4G,走一遍你产品的核心流程,记下每个"死寂时刻"(无任何反馈的等待)——每个死寂时刻都是一个未实现的骨架屏。④ 可达:对一个页面做三件事——用 Lighthouse / axe 跑一遍对比度与标签;收起鼠标只用 Tab 键走一遍核心流程(卡住的地方就是键盘用户的死路);在系统设置里打开"减少动态效果",看你的动画有没有退化。三项里任意一项不及格,你的产品就把一部分人挡在了门外。