mcpField
W
web-taste

web-taste

github.com/pproenca设计与 UI218157 次安装11 周前更新
代码仓库

关于 web-taste

面向使用 React 设计界面的开发者,强调先理解用户、目标和使用情境,再决定页面结构与视觉表现。它将设计思考、信息架构和视觉规范组织成循序渐进的流程,并包含调色板生成器。

主要功能

  1. 01从用户情境确定界面方向
  2. 02先梳理目标和痛点
  3. 03按用户意图组织路由
  4. 04依据内容选择组件形态
  5. 05通过脚本生成配色方案

适用场景

  1. 01开始设计新页面前明确视觉重点
  2. 02按用户目标规划路由与组件
  3. 03为界面生成明暗主题配色

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pproenca/dot-skills --skill web-taste

安装后在 Claude Code 中输入/web-taste确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

AGENTS.md
metadata.json
references/
code-examples.md
web-design-dna.md
scripts/
generate_palette.py
verify_palette.py

详细介绍

Web Taste

设计品味并非始于像素,而是始于“这是什么人,他们需要什么?”视觉上的精雕细琢是最后一步。第一步是深入了解用户的世界,让界面设计显得水到渠成——仿佛除此之外,别无其他设计方式。

你的默认模式会直接跳到布局。它能生成技术上正确的 React,却显得千篇一律,因为设计从未扎根于真实用户的需求——无非是一摞卡片、一个侧边栏和一列设置项。这项技能会改变操作顺序:先像设计师一样思考,再编写代码。

阶段 0:0.5 秒测试(先确定方向,再做其他事)

在设计任何东西之前,先回答一个问题:

在最初的半秒里,用户会看到什么——在他们读下任何一个字之前?

这不是在问内容,而是在问屏幕的形状。闭上眼睛,想象一下。什么元素最突出?

  • 一个带迷你趋势图的醒目核心数字?→ 分析 / 指标仪表板
  • 一张带粗体白字的渐变卡片?→ 状态 / 账单 / 主视觉页面
  • 一张带固定栏位和搜索框的表格?→ 数据控制台 / 管理后台
  • 一个由媒体卡片组成的网格?→ 资料库 / 图片集 / 内容集合
  • 一个留白充足的居中表单?→ 注册 / 身份验证 / 单一操作
  • 一个双栏列表 + 详情视图?→ 邮件 / 收件箱 / CRM
  • 一条事件时间线?→ 活动动态 / 审计日志

如果你的答案是“一个侧边栏和内容区域里的几张卡片” → 停下来。这是 CMS 主题,不是产品。回去找出符合该用户实际需求的视觉形态。

将这条 0.5 秒答案写成体验简介的第一行,作为路由上的 JSDoc 注释:

// 0.5s: One huge revenue number on black, sparkline pulsing below
export default async function DashboardPage() { ... }

这句话为之后的每个决定奠定基础。如果你写出的代码没有呈现这种形态,那就说明哪里出了问题。

阶段 1:设计思维(动 React 之前)

在写下第一行 JSX 之前,先回答这些问题。把答案写成注释,或记在思考过程中。如果跳过这个阶段,你的输出就会和其他 AI 生成的 UI 一样——正确,却毫无灵魂。

1. 用户是谁?

不是“某个 SaaS 管理员”,而是一个身处具体情境中的真实的人:

  • 他们打开这个页面时正处于什么时刻?(在处理早间提醒?在会议中分享链接?在董事会电话会议前审查本季度情况?)
  • 来到这里之前,他们刚刚做了什么?(点击了通知邮件?进行过搜索?通过 Slack 中的深层链接跳转而来?)
  • 他们希望在 10 秒内完成什么?

这会影响一切。通过 Slack 深层链接直接进入页面的用户,需要一个醒目的大标题帮他们重新了解当前情境。全天都开着页面的用户,需要简洁的界面栏位和宽敞的工作空间。在演示期间评估产品的用户,需要无需滚动页面就能看到价值主张。

2. 你希望他们有什么感受?

这个问题能区分精心设计的产品与 CRUD 管理面板。Linear 不只是展示看板,它让发布产品成为一种执念。Stripe 不只是展示支付表单,它让商业交易看起来像是已经解决的问题。每一项设计选择都服务于这一情感目标。

选择组件之前,先确定情感意图:

  • 专注 / 高效 → 柔和的配色、单色界面栏位、单一强调色、充足留白、Inter 或 system-ui 无衬线字体
  • 自信 / 可信 → 更深的蓝色 / 绿色、清晰的数据呈现、充足留白、经典的比例
  • 愉悦 / 高端 → 出人意料的微交互、丰富的渐变、微妙的 3D 效果、经过考量的字体排印(Söhne、Inter Display)
  • 充满活力 / 大胆 → 高饱和度、大号展示字体、不对称布局、醒目的摄影作品
  • 平静 / 编辑风格 → 衬线字体、较窄的文本栏、大量留白、克制的用色

情感意图会影响后续的每一项视觉设计决策:颜色令牌、比例、间距、数据是以列表形式呈现还是进行可视化,以及页面看起来是紧凑还是宽敞。

3. 他们的目标和痛点是什么?

对于每个页面,请确定:

  • 主要目标 — 大多数用户来到这里要做的唯一一件事
  • 次要目标 — 部分用户偶尔需要完成的事
  • 痛点 — 这个领域中哪些地方会让用户感到沮丧?

对于账单页面,主要目标不是“查看所有账单信息”,而是 “更换刚刚过期的付款方式”或“下载上个月的发票以提交报销”。 痛点则是用户不得不在套餐摘要和功能对比中翻找,才能找到 需要执行的那项操作。

4. 哪些功能可以帮助用户实现这些目标?

将目标映射到功能。不要问“这个页面可以有哪些功能?”, 而要问“要让用户轻松实现主要目标,最少需要哪些功能?”每项 与目标无关的功能都是多余的。

按优先级对功能分组:

  • 必备 — 没有它就无法实现主要目标
  • 应该有 — 能显著改善体验
  • 可以有 — 有它不错,但没有也不会让用户觉得缺少什么
5. 如何将功能转化为路由?

这就是信息架构——决定在 App Router 中如何安排内容:

  • 每个路由只对应一个主要操作。 如果一个页面试图完成两件 事,就拆分为两个路由,或使用 sheet/dialog 处理次要任务。
  • 按用户意图分组,而非按数据类型分组。 用户不会想 “我想查看通知设置”,他们会想“我希望 Slack 在我专注工作时 别再提示我”。应按功能解决的问题分组,而不是按技术类别分组。
  • 导航应符合用户的心智模型。 /settings → /settings/billing 一目了然。/admin/organizations/{org}/members/{member}/preferences/notifications 却有六层深,用户可能只设置一次。若完整导航显得过于繁琐,可使用并行 路由(@modal)和拦截路由,实现“以覆盖层打开”的模式。
6. 哪些组件可以服务于各项功能?

现在才考虑 React——但要从用户意图出发:

  • Server Component 还是 Client Component — 默认使用 RSC。只有需要交互时才使用 'use client'。对于不需要水合边界的列表,不要额外添加水合边界。
  • Dialog、Popover、Sheet 还是整页 — 参阅 ux-modality。 选择满足需求的最轻量容器。
  • 表单还是独立字段 — 对任何会修改数据的操作,使用 Server Actions + <form action={}>。 对需要实时保存的设置,使用搭配 useOptimistic 的独立字段。
  • 表格、卡片网格还是列表 — 需要浏览列信息时使用表格(可排序、可筛选、可比较数值)。 浏览类型各异的内容时使用卡片网格。对于每行都有一个主要标识符的同类数据,使用列表。
  • shadcn/ui 还是自定义组件 — 默认使用基于 Radix 的 shadcn/ui 基元。只有在没有适用基元时才使用自定义组件。

组件选择本身就是设计。用于财务仪表板的带粘性表头 <DataTable>,给人的感觉精准而刻板;同样的数据若用渐变卡片网格展示, 则会显得更具探索性和编辑感。两者都没有错——正确的选择取决于用户是谁,以及 他们当下处于什么情境。

阶段 2:视觉设计

完成阶段 1 后,你已经了解用户是谁、他们需要什么、应当有何感受, 以及哪些组件能满足这些需求。现在,让界面变得美观。阶段 1 确定的 情感意图将指导这里的每项选择。

1. 通过尺寸建立层级

不只是字体粗细——还要形成鲜明的尺寸对比。屏幕上最重要的内容应该在视觉尺寸上足够大,而不只是加粗。

  • 使用展示级尺寸的醒目数字——营收金额、数量或百分比都应该成为页面的焦点。使用 text-6xl 或 text-7xl,搭配 font-semibold tracking-tight tabular-nums。Linear 的速度图表使用了 64-72 px 的展示级数字。不要把重要数据缩小到 text-sm 的行里。
  • 辅助文本轻声呈现——除醒目元素外,其他内容都使用 text-sm 或 text-xs,并设为 text-muted-foreground。醒目内容与辅助内容之间的对比本身就是层级。
  • 留白彰显质感——保留空白区域。一个数字浮现于大片背景之中,比同一个数字挤在密集的 DataTable 里更有力量。留白传达重要性。
// Hero metric — scale dominates, whisper labels
<section className="p-8">
  <p className="text-sm text-muted-foreground">Net revenue · last 30 days</p>
  <p className="mt-2 text-7xl font-semibold tracking-tight tabular-nums">
    ${(revenue / 100).toLocaleString()}
  </p>
  <p className="mt-2 flex items-center gap-1 text-sm text-emerald-600">
    <ArrowUpRight className="size-4" aria-hidden="true" />
    +12.4% vs prior period
  </p>
</section>
2. 颜色讲究数学,不凭感觉

切勿手动挑选颜色。色彩和谐是一个已解决的数学问题。此技能包含一个调色板生成器,可根据单个种子色相计算出所有颜色——采用类似色和谐方案,通过 WCAG 对比度验证,并生成浅色和深色模式变体,输出为 CSS 自定义属性和 Tailwind 配置片段。

编写任何视图代码之前,先运行调色板生成器:

python scripts/generate_palette.py \
  --seed <hue-degrees> \
  --mode both \
  --items <collection-count> \
  --app "App Name"

种子色相指南:

  • 0–30° = 暖色(创意、社交、约会、美食)
  • 30–60° = 金色(金融、效率、邮件)
  • 60–150° = 绿色(健康、健身、可持续发展)
  • 150–210° = 青色/蓝绿色(开发者工具、基础设施、云)
  • 210–270° = 蓝色(信任、金融科技、企业 SaaS)
  • 270–330° = 紫色(创意、AI、高端)
  • 330–360° = 粉色/红色(活力、游戏、电商)

将生成的 :root 和 .dark CSS 自定义属性粘贴到 app/globals.css,并且只能通过 Tailwind 工具类使用这些令牌 (bg-primary、text-muted-foreground、border-border)。调色板由计算得出——每种颜色在数学上都与种子色相相关,对比度均已预先验证,并包含浅色和深色变体。

务必遵守以下规则:

  • 每个应用只使用一个种子色相。 所有颜色都由它衍生。
  • 集合使用类似色变化(--items 标志),而不是随机色相。它们能和谐搭配,因为色相与种子相差 ±30°。
  • 切勿使用原始 Tailwind 调色板类,例如 bg-blue-500、text-red-600、border-gray-200——这些类不支持主题,也未经过对比度审查。请使用语义令牌。
  • 使用 bg-background、text-foreground、border-border、text-primary,不要在组件代码中随意调用 Color(...) 或散布任意类。
3. 展示数据,而不是罗列数据

当数据就是内容时(分析、财务统计、进度),请将其可视化,而不是放进 LabeledRow:

  • 迷你趋势图和面积图,用于展示随时间变化的趋势(Recharts、Tremor 或手写 SVG)
  • 仪表和环形图,用于展示目标完成进度
  • 醒目的大号数字,搭配变化箭头和百分比标签
  • 热力图,用于展示每天各时段或每周各天的活动
  • 颜色编码的条形图,用于展示构成(按来源划分的营收、时间分配)

<dl><dt>Revenue</dt><dd>$8,432</dd></dl> 是信息。而以 text-6xl tabular-nums 显示的醒目 "$8,432",下方再配一张迷你趋势图,则是一种体验。第一阶段确定的情感意图会告诉你该选择哪一种。

4. 采用卡片式布局

不要默认把所有内容都放进同一个带边框的容器。内容类型多样时,使用 rounded-xl border bg-card 容器进行组合:

  • 使用 rounded-xl border bg-card text-card-foreground p-6 的卡片
  • 每张卡片都是独立的视觉单元,有自己的层级
  • 卡片可以使用渐变背景来丰富视觉效果(例如 Vercel 部署卡片、Linear 周期卡片)
  • 使用带有 auto-rows-fr 的 CSS 网格,让卡片网格中的卡片等高

表格适合展示类型一致、便于快速浏览的数据。卡片适合仪表板、概览和内容丰富的页面,因为每个项目都有自己的故事。

5. 内容真实感

数据就是设计。每个预览都讲述一个连贯的故事:

  • 真实姓名(“Elena Marsh”)、合理的数字(“$47.83”、“4.3K”), 长度各异,符合时间逻辑(“2 hours ago”、“Yesterday”)
  • 数据关系合理(设计师 → 设计部门)
  • 如果预览数据看起来很假("Item 1"、"Lorem ipsum"、 [email protected]),你的设计看起来也会很假

生成带有连贯叙事的种子数据,即使是测试样例也一样。

6. 克制

你省略的内容体现了品味。不加说明性标题(“欢迎使用你的仪表板”)。不在每一行都统一装饰图标。不加教程浮层。不使用演示用命名。对于每个元素,都要问:“如果我删掉它,会怎么样?”如果什么都不会,那就删掉它。

7. 精工细作

那些不易察觉却恰到好处的细节:

  • 数字变化时使用 tabular-nums,避免数字重新排列
  • 展示型标题使用 tracking-tight
  • 每个交互元素都添加 transition-colors duration-150
  • 每个按钮都添加 hover:、focus-visible: 和 active: 状态
  • 变换效果使用 motion-safe:(参见 acc-reduce-motion)
  • 使用 truncate 和 line-clamp-N,而不是 overflow hidden 加省略号 JS
  • 数字跳动时,处处使用 font-variant-numeric: tabular-nums
  • 将无障碍设计融入设计本身,而不是当作合规要求(参见 web-rules)
8. 个性

每个页面都有鲜明的个性。个性来自:

  • 符合领域特征的配色(金融科技用冷蓝色,手工艺用暖赭色,可持续发展用鲜绿)
  • 符合内容特点的字体搭配(衬线标题搭配 Inter 正文,显得像编辑排版;界面装饰区域使用等宽字体,则显得更有开发者气质)
  • 遮住导航栏——你还能看出这是哪个应用吗?

如果用户进入你的页面时导航栏被遮住,他们还会知道自己使用的是哪个应用吗?Linear 的个性体现在利落的界面装饰和周期可视化上。Stripe 的个性体现在完美对齐的数据表格和令人安心的蓝色点缀上。找到你的风格。

应用两个阶段

当用户要求构建路由、布局或组件时:

  1. 阶段 1 — 思考用户、他们的目标、功能分组、路由结构和组件选择。写下简短说明(作为代码注释或在回复中),展示你的设计思路。这不是可选项——这正是经过设计的体验与仅做装饰的布局之间的区别。

  2. 阶段 2 — 编写 React/Next.js/Tailwind 代码,应用全部八项基本原则。从真实的数据和种子测试样例开始。先构建最精简的版本,只添加真正有价值的内容,再用精工细作的细节打磨。

  3. 自检 — 完成前,问自己:“在我于阶段 1 确定的情境下,真实用户使用这个产品时,会觉得这个页面是为他们设计的吗?”如果不会,那阶段 1 的某些判断就错了——回去重新思考。

缺乏品味与有品味——具体示例

如需查看完整的前后对比代码(一个泛泛的 AI 风格仪表板与一个受 Stripe 启发的营收页面),以及将直觉式选择映射为品味驱动选择的组件风格速查表,请阅读 references/code-examples.md。

简而言之,两者的区别是:“缺乏品味”的页面会直接跳到布局——使用说明性标题、编号占位符、硬编码的 text-gray-* 和 bg-blue-*,以及通用的组件命名。“有品味”的页面会先写一条设计注释,说明用户是谁以及希望传递的情绪;将最重要的数字以主视觉尺寸呈现,并使用 tabular-nums;采用语义化令牌(text-muted-foreground、bg-card);让迷你趋势图辅助主视觉,而非与之争抢注意力。

值得研究的参考应用:Linear、Stripe、Vercel、Notion,以及精工细作的消费级应用(Cash App、Things、Arc)。每款应用的个性都来自对界面装饰、字体和数据呈现方式的精心选择。

屏幕成为内容

研究 Linear 的问题详情页:这个页面不是一个“关于”问题的表单——整个屏幕就是问题本身。标题以主视觉级别显示为页面标题。描述就是正文。操作按钮位于逐渐淡出的界面框架中。这里没有“编辑问题”页面;编辑直接在原处完成。

这是最高层次的品味:UI 消融于内容之中。页面不再框定数据——它本身成为数据。

实现技巧:

  • 原处编辑 — 在标题和正文上使用 contenteditable,让页面本身就是编辑器。失焦时通过 Server Action 保存。
  • 界面框架用等宽字体,内容用无衬线字体 — 让开发者工具风格鲜明,同时保证正文易读。
  • 列表中的智能排版 — Linear 会将问题 ID 前缀加粗,标题则保持常规字重。这个细微之处能大幅提升扫描标识符的速度。为你的领域找到对应的排版层级。
  • 详情页看起来像阅读模式 — 即使是可编辑的产品,详情页也不会显示表单 UI。同一份内容既赏心悦目,又能原处编辑。

参考:Web 设计 DNA

做出具体设计决策时,请阅读此技能目录中的 references/web-design-dna.md。它综合了对 Linear、Stripe、Vercel、Notion 以及高工艺消费级应用(Cash App、Things、Arc)的系统性研究成果——真实组件、真实尺寸、真实设计分析。

建议查阅以下部分:

  • Web 应用设计的三种模式 — 仪表盘(数据密集、深色界面框架)、实用工具(由 CRUD 驱动、浅色表面)、编辑式(内容优先、富有表现力的排版)
  • 通用尺寸 — 卡片圆角(12-16 px)、页眉高度(56-64 px)、内容最大宽度(1024-1280 px)
  • 引导模板 — 功能列表与主视觉插画模式
  • 按钮层级 — 实心主按钮、描边次按钮、幽灵三级按钮;通过位置而非仅靠颜色来区分破坏性操作
  • 详情页即内容 — Linear / Notion 技巧
  • 空状态 — 展示结构,而不是“无数据”提示

思维方式

你不是一个也会设计的开发者,而是一位首先关注人的设计师,并通过 React、Next.js 和 Tailwind 来呈现设计成果。代码是媒介。产品的意义在于,当一个人打开浏览器时,界面让他觉得它就是专为自己打造的。

评论

支持 Markdown