我花72小时、写了18700行代码,只为搞清楚Claude的界面为什么用起来比GPT舒服

同样是AI对话,同样的回复内容,放在Claude界面里读起来就是比GPT顺。

这种感觉你有没有?我有,而且一直想搞清楚为什么。

三个月前,我决定不再靠"感觉"说话——干脆把Claude的设计系统从头到尾拆一遍,逆向分析、复刻、跑通。72小时,18700行代码,最后我不仅找到了答案,还发现这套答案普通开发者完全可以直接拿去用

这篇文章就是这段过程的完整记录。

---

第一章:为什么偏偏是Claude值得研究?

在聊复刻之前,先解释一个问题:市面上AI产品那么多,为什么单挑Claude的设计系统下手?

我做过一个不严谨但直观的测试:把同一段AI回复——一篇800字的技术分析——分别放进GPT、Gemini、Claude三个界面截图,然后让10个朋友盲测"哪个读起来最舒服"。结果8个人选了Claude。

这不是Claude回答得更好,是界面让回答"显得"更好

具体差在哪里?我总结了三个维度:

① 信息层级感

Claude的Markdown渲染有一套极其克制的视觉权重系统。标题、正文、代码块、引用,每一层的字号、行高、颜色对比度都经过精细调校。GPT的渲染相对"扁平",Gemini则有时过度强调标题,导致长文读起来像PPT。

② 等待时的体验设计

流式输出是现在所有AI产品的标配,但处理方式差别很大。Claude的光标动画有一种"它在思考"的节奏感,而不是机械的闪烁。这个细节让等待从"煎熬"变成"期待"。

③ 错误和边界状态的文案

当Claude遇到无法回答的问题,它的提示文案是有温度的,而不是冷冰冰的系统错误。这背后有一套完整的文案逻辑,不是随便写的。

这三点加在一起,就是为什么Claude用起来"感觉更好"——它的设计系统在系统性地降低用户的认知摩擦

---

第二章:72小时复刻全纪录

第一阶段(0-24小时):拆解CSS变量体系

逆向分析的第一步,打开Chrome DevTools,开始扒CSS。

Claude的设计系统有一个非常清晰的特征:大量使用CSS自定义属性(Custom Properties),而不是把颜色、间距硬编码在组件里。这意味着整套系统是"可主题化"的,深色模式切换不是靠覆盖样式,而是靠切换根变量。

我写了一个简单的Chrome扩展脚本,把页面上所有--开头的CSS变量批量提取出来,大概拿到了200+个变量,涵盖颜色、字体、间距、圆角、阴影。

踩坑点1:部分变量是动态计算的,直接提取拿到的是计算后的值,而不是原始定义。解决方法是去看:root下的变量声明,而不是computed styles。 踩坑点2:深色模式的变量不是简单的颜色反转,而是一套独立的色彩系统。Claude在深色模式下用的不是纯黑背景,而是一个带有轻微暖色调的深灰(#1a1a1a附近),这个细节直接影响长时间阅读的舒适度。

第二阶段(24-48小时):组件拆解与流式输出

这是整个复刻过程中技术难度最高的阶段。

流式输出的实现看起来简单,实际上有很多细节要处理:

  • Markdown需要增量渲染,不能等全部内容到了再解析
  • 代码块在流式状态下要有特殊处理,避免未闭合的代码块导致渲染错乱
  • 光标动画要和内容输出节奏同步,而不是独立运行

我在这个阶段卡了将近8个小时,主要是在处理"流式状态下的Markdown解析"。最后的解决方案是用一个状态机来追踪当前是否在代码块内,在代码块结束标记\\\出现之前,暂时把这部分内容当纯文本处理。

踩坑点3:移动端键盘弹出时,输入框会被键盘遮挡。Claude处理这个问题的方式不是简单地监听resize事件,而是用visualViewport API来精确获取可见区域高度,然后动态调整布局。这15行代码让我在移动端测试时少踩了很多坑。

第三阶段(48-72小时):细节打磨与整合

最后24小时基本是在做"让它从70分变成90分"的工作:错误状态处理、代码块复制交互、消息气泡的自适应宽度。

18700行代码的大致模块分布:

  • 核心组件库:约6200行
  • 样式系统(CSS变量+主题):约3800行
  • 流式输出引擎:约2100行
  • Markdown渲染层:约3400行
  • 工具函数与状态管理:约3200行

---

第三章:五个可以直接拿走的设计细节

这是本文最有价值的部分。我从18700行里挑出最值得迁移的五个模式,每个都给你能跑的代码。

① 流式输出的光标动画

/ 流式输出光标 /

.streaming-cursor {

display: inline-block;

width: 2px;

height: 1.2em;

background-color: currentColor;

margin-left: 1px;

vertical-align: text-bottom;

animation: cursor-blink 0.8s ease-in-out infinite;

}

@keyframes cursor-blink {

0%, 100% { opacity: 1; }

45% { opacity: 1; }

55% { opacity: 0; }

}

// 流式输出控制器

class StreamingController {

constructor(container) {

this.container = container;

this.cursor = document.createElement('span');

this.cursor.className = 'streaming-cursor';

this.isStreaming = false;

}

start() {

this.isStreaming = true;

this.container.appendChild(this.cursor);

}

append(text) {

// 在光标前插入文本

this.container.insertBefore(

document.createTextNode(text),

this.cursor

);

}

stop() {

this.isStreaming = false;

this.cursor.remove();

}

}

为什么这样设计:光标的闪烁节奏(0.8s,非对称的亮暗比)模拟了人类打字时的思考停顿感,比机械的0.5s等间隔闪烁更有"生命感"。

② 消息气泡的自适应宽度

.message-container {

display: flex;

flex-direction: column;

gap: 16px;

}

.message-bubble {

max-width: min(85%, 720px); / 关键:双重约束 /

width: fit-content;

padding: 12px 16px;

border-radius: 12px;

line-height: 1.6;

}

.message-bubble.user {

align-self: flex-end;

background: var(--color-user-bubble);

}

.message-bubble.assistant {

align-self: flex-start;

max-width: 100%; / AI回复不限制宽度 /

background: transparent;

}

为什么这样设计:用户消息用min(85%, 720px)双重约束,在宽屏上不会撑太宽(避免阅读时眼球移动距离过长),在窄屏上保留足够边距。AI回复不限宽,因为长内容需要充分展开。

③ 错误状态的"温柔提示"文案逻辑

Claude的错误提示有一个固定模式:承认问题 → 解释原因(用户能理解的语言)→ 给出下一步

const ErrorMessages = {

rate_limit: {

title: "稍等一下",

body: "请求有点多,让我喘口气。几秒后可以继续。",

action: "稍后重试"

},

context_too_long: {

title: "对话太长了",

body: "这段对话已经很长了,我可能需要开始一个新的对话才能继续帮你。",

action: "开启新对话"

},

network_error: {

title: "网络好像出了点问题",

body: "检查一下网络连接,然后再试试?",

action: "重新发送"

}

};

function renderError(type) {

const msg = ErrorMessages[type] || ErrorMessages.network_error;

return

⚠️
${msg.title}

${msg.body}

;

}

④ 代码块的一键复制(带Toast反馈)

function initCodeBlockCopy() {

document.querySelectorAll('pre code').forEach(block => {

const wrapper = block.parentElement;

const btn = document.createElement('button');

btn.className = 'copy-btn';

btn.textContent = '复制';

btn.addEventListener('click', async () => {

await navigator.clipboard.writeText(block.textContent);

btn.textContent = '已复制 ✓';

btn.classList.add('copied');

setTimeout(() => {

btn.textContent = '复制';

btn.classList.remove('copied');

}, 2000);

});

wrapper.style.position = 'relative';

wrapper.appendChild(btn);

});

}

⑤ 移动端键盘弹出时的布局保护

// 用 visualViewport API 替代 resize 事件

function initMobileKeyboardProtection(inputArea) {

if (!window.visualViewport) return;

window.visualViewport.addEventListener('resize', () => {

const viewportHeight = window.visualViewport.height;

const windowHeight = window.innerHeight;

const keyboardHeight = windowHeight - viewportHeight;

if (keyboardHeight > 100) {

// 键盘弹出

inputArea.style.paddingBottom = ${keyboardHeight}px;

// 滚动到最新消息

scrollToBottom({ behavior: 'instant' });

} else {

// 键盘收起

inputArea.style.paddingBottom = '0';

}

});

}

---

第四章:拆完之后我发现的底层逻辑

从"怎么做"退一步,看"为什么这么做"。

复刻完整套系统之后,我提炼出Claude设计系统的三条隐性原则:

原则一:减少用户的决策负担

Claude的界面几乎没有多余的按钮和选项。它做的每一个"简化"背后,都是把决策权从用户手里拿走——不是剥夺,是替你做了。字体大小不让你选,行高不让你调,因为它已经调到了最优解。

原则二:让AI的不确定性变得可预期

AI的回答是不可控的,但界面可以让这种不可控"看起来可控"。流式输出的光标、渐进式的内容展示、清晰的"正在思考"状态——这些都在告诉用户:系统在正常工作,只是需要一点时间

原则三:把等待时间变成信任建立时间

这是最反直觉的一条。大多数产品把"等待"视为需要消灭的负体验,Claude的设计却把等待变成了一种仪式感——你看着内容一个字一个字出现,反而会觉得"它在认真思考"。这种感知上的"努力感",直接影响用户对回答质量的评价。

---

第五章:普通开发者的最短路径

学了这么多,怎么真正跑起来?

我建议的最小技术栈:

  • 前端框架:React 或 Vue(组件化是必须的,原生JS维护成本太高)
  • Markdown渲染marked.js + 自定义渲染器(处理代码块和流式状态)
  • 样式方案:CSS Variables + Tailwind(前者管主题,后者管布局)
  • 流式请求fetch + ReadableStream(不需要额外库)

最关键的一步,是接入真正的AI API。

设计系统是皮,API能力是骨。你可以把Claude的界面做得一模一样,但如果后端接的是一个反应迟钝的模型,所有的"光标动画"和"温柔提示"都会显得像在说谎。

我在测试这套复刻系统时,用的是 [api.884819.xyz](https://api.884819.xyz) ——注册即用,不需要邮箱验证,新用户直接有体验token,国产模型(Deepseek、千问等)完全免费。我自己跑这套设计系统的demo验证,稳定性和响应速度都没有问题,省去了很多环境配置的麻烦。

今晚就能做的事

1. 把第三章的流式光标代码跑起来(10分钟)

2. 用fetch接一个流式API,把内容接进StreamingController`(30分钟)

3. 加上代码块复制按钮(15分钟)

一个小时内,你就能看到一个有Claude质感的对话界面在自己的浏览器里跑起来。那种成就感,比看100篇教程都管用。

---

写在最后

复刻Claude设计系统这件事,给我最大的收获不是18700行代码,而是一个认知转变:

好的AI产品体验,70%是设计的功劳,30%才是模型的功劳。

这意味着,作为开发者,你比你想象的更有能力影响用户体验——不需要训练自己的大模型,只需要认真对待每一个交互细节。

复刻完Claude的设计系统之后,我做了一件更有意思的事:把这套系统接上不同的模型,测试"同样的设计外壳,换不同的AI大脑,用户体验差异有多大"

结果有点出乎意料——某些国产模型在这套界面下的"感觉",比我预想的好很多。甚至有一个模型,在特定任务类型上,用Claude的界面包装之后,用户根本感觉不出来"这不是Claude"。

下一篇我会把完整的测试数据和结论写出来。如果你也好奇是哪个模型,记得关注。

---

本文由8848AI原创,转载请注明出处。关注8848AI,带你从零开始学AI。

#AI教程 #前端开发 #Claude #设计系统 #8848AI #AI产品 #开发者工具 #ChatGPT