11 KiB
WorkBuddy 对话区前端布局实测
2026-10-08补充:最新原生内层文字与布局审计。下文外层用户气泡13px、输入容器14px不是实际文字字号;本机Slate内层两处实际均15px,应以最新审计为准。
验证对象:WorkBuddy AI 5.7.6、Windows、主窗口 1200 × 762 CSS px、DPR 1。 证据来自真实页面 CDP computed style、元素矩形、内联样式及安装包 CSS。 这是一个窗口与会话下的实测,不代表所有分辨率和用户字号设置。
字体规则
对话正文不是每级字号各自写死 px。Markdown 先接入根字号和行高 token,再由段落与标题按相对比例排版;运行时显示出来的像素值只是当时 token 的计算结果。输入框属于另一套控件样式,当前 CSS 确实单独声明了 14px。
| 元素 | 运行时实测 | CSS 规则 |
|---|---|---|
| Markdown 根节点 | 当前解析为 17.143px / 30px | font-size: var(--cr-md-root);行高 var(--cr-md-line-height, 1.75) |
| Markdown 段落 | 当前解析为 15px / 26.25px | font-size: .875em,继承 1.75 行高 |
| Markdown 一级标题 | 由 token 控制 | font-size: var(--cr-md-h1-font-size, 1.25em) |
| Markdown 行内代码 | 按父级字号 | font-size: 1em |
| Markdown 表头 | 当前解析为 15px / 26.25px,字重 600 | 单元格横向 padding 12px;浅色表头实测 #f7f7f7 |
| 输入区 | 当前解析为 14px / 21px | .cr-input-box 声明 font-size:14px; line-height:1.5 |
| 输入编辑器 | 高度 64px,padding 横向 16px | .cr-input-editor-host min-height:64px; overflow-y:auto |
Markdown 组件声明 --cr-md-root: var(--cb-md-root, 16px),当前主题解析为
--cb-md-root: 17.143px。HTML 根字体为 16px,页面 zoom 和 visual viewport scale 均为 1。
本次 15px 段落是根字号乘 .875em 的计算结果,不能反推为源码把段落固定写成 15px,
也不能归因于 viewport 缩放。字号变量的上游已在组件 bundle 中找到,具体的六级调节规则见下节。
实际正文段落间距为 12px;代码块实测使用 monospace、12.857px / 22.5px 行高、 横向 padding 16px,并限制内部滚动。Ygent 当前默认档的 Markdown 根字号、段落比例、 行高与代码字号已按上述规则设置;用户气泡仍单独采用 13px / 19px。
全局字号控制
renderer/assets/ui-docs-viewer-veG3wQhz.js 中有统一的字号级别管理器,作用超过 Markdown:
正文、标题、说明文字、代码、按钮文字和按钮高度都接入它。
级别保存在 localStorage 的 agent-ui-font-size-level:v2,并同步到
config.preference.fontSizeLevel。有效级别为 1 到 6;没有有效保存值时默认为 2。
每级同时更新根 Markdown 字号和全局偏移量:
| 级别 | 根字号 token --cb-md-root |
全局字号偏移 |
|---|---|---|
| 1 | 16px | -1px |
| 2(默认) | 17.143px | 0px |
| 3 | 18.286px | +1px |
| 4 | 20.571px | +2px |
| 5 | 22.857px | +2px |
| 6 | 26.286px | +2px |
--wb-font-body-size、--wb-font-caption-size、标题和代码等设计 token 用各自的 base size
加全局偏移计算。全局 token 偏移夹在 -1 至 +2px,避免级别 5、6 把紧凑控件撑大过多;
按钮高度再按更新后的行高和垂直 padding 重算。
旧 CSS 中直接写为 font-size: 13px 的规则也会参与字号调节。管理器扫描可读的样式表,
按级别注入 max(8px, calc(13px + var(--cb-font-size-offset) * 1px)) 覆盖规则。
它保留 @media 分组,观察后续新增的样式表,并排除 .cb-font-size-fixed 及其子孙节点,
以便明确声明固定字号的控件不随全局级别改变。
Windows 上可用 Ctrl+- 降一级、Ctrl++ 升一级、Ctrl+0 恢复默认。级别限制在 1 到 6。
切换时派发 cb-font-size-change 和 cb-font-size-level-change 事件,让组件刷新。
源码会同时出现字体 token、相对 em 和少量固定 px:全局设置更新设计 token,
并兼容旧组件里的固定字号。
宽度与主布局
在当前 1200px 窗口中,左侧栏为 280px,主内容区为 920px。对话历史和输入区各自在主内容区居中,并使用相同的 832px 上限:
.cr-message-list__content运行时内联max-width: 832px,源码使用width:100%; max-width:100%; margin-inline:auto。- 对话内容区左右 padding 为主题变量
--cr-message-list-content-inline-padding:40px。832px 外框扣除 80px 后,消息正文列为 752px。 - 输入区外框上限同为 832px,外框左右各 padding 24px,输入控件宽度为 784px。
- 小于 832px 的可用主列时,
width:100%收缩外框,正文与输入仍分别保留自己的横向 padding。布局跟随内容区宽度,不依靠 viewport 单位设定字体。 - 对话主列是 flex 布局。消息列表
flex:1; min-height:0; overflow-y:auto,输入区flex-shrink:0固定在底部;这样滚动发生在历史列表内部,长内容不会把输入区挤出窗口。 - 输入编辑区设置最小高度,并通过纵向滚动承载增长内容;工具栏单独 flex 布局、
flex-shrink:0,操作项不会跟着编辑内容收缩。
Ygent 对应使用同一内容列:在 1200 × 762 窗口、280px 侧栏和 10px 消息滚动条下,832px 对话外框居中后,消息正文列落在 x=359..1111(752px)。助手头像行、回答正文和用户气泡均对齐这条列;输入框外框落在 x=348..1132(784px),其编辑器和工具栏分别保留 64px 与 56px 高度。窗口窄于内容上限时,消息列跟随可用宽度收缩,窄屏左右内边距为 16px。
实测 DOM 层级中,对话列和输入区都受 832px 居中容器约束,但消息、输入和工具栏是独立组件。这个边界让两边 padding 与窄窗收缩策略各自清晰。
响应策略
- 主列采用
width:100% + max-width + margin:auto;用可用宽度与最大宽度自然收缩。 .cr-message-list声明container-type:inline-size,具备查询容器的能力。当前对应 CSS 文件没有@container规则,不能仅凭声明推断对话区已有完整的容器断点体系。- 对话输入工具栏有
width <= 320px的局部断点,在极窄宽度下隐藏次要 context-usage 标记,给常用操作留空间。 - 主内容 CSS 的另一个欢迎页容器
.chat-container--welcome默认上限 848px,在 viewport 至少 1681px 时扩到 1008px;这是不同容器的规则,不能跟本次运行页面的 832px 对话列混为一谈。 - 组件 CSS 使用
prefers-reduced-motion减少消息列表进出动画。
消息气泡、widget 与输入区
同一窗口的当前会话快照实测:
| 元素 | 运行时规格 |
|---|---|
助手头部 .cr-agent__header |
752px 内容宽;24.5px 高;24px 圆形标识、10px 间距;名称 14px / 24.5px、字重 600;下方间距 12px |
完成状态 .cr-collapse__header |
文案 已完成 3m2s;15px / 26.25px、三级文字色、宽度随内容;12px 箭头与 8px 间距 |
Markdown 根 .cr-markdown |
字号 17.143px / 行高 30.0002px(当前 2 级);段落按 .875em,实测 15.0001px / 26.2502px |
列表 .cr-markdown ul |
15.0001px / 26.2502px;左缩进 21.4502px;列表后间距 16px;列表项间距 4px |
表格单元格 .cr-markdown th/td |
15.0001px / 26.2502px;padding 8px 12px;表头底色 #f7f7f7 |
代码块 .cr-markdown pre |
12.8573px / 22.5002px;padding 12px 16px |
用户气泡 .cr-self-bubble |
13px / 19px;#f2f2f2;padding 8px 12px;圆角 16px 16px 0;最小宽 40px、最大宽 100%、最大高 310px,内部滚动 |
用户消息工具栏 .cr-toolbar |
相对用户气泡框架绝对定位在底部;默认透明;时间 14px / 20px,含复制和编辑按钮 |
表格操作 .cr-message-quote-table-menu |
hover 时显示于表格右上角;菜单 116×38px,按钮 106×28px;点击把原表格 Markdown 加入输入草稿 |
widget 卡 .cr-widget-card |
正文列宽 752px;边框 1px solid #ebebeb、圆角 16px、纵向 margin 8px |
widget 内容 .cr-widget-body |
padding 12px 16px;当前 iframe 宽 718px,高度随内容变化 |
| widget iframe | sandbox="allow-scripts",不含 allow-same-origin;CSP 允许内联脚本与指定 CDN |
输入容器 .cr-input-container |
x=348, y=592, 784×134px;白底、1px solid #e6e6e6、24px 圆角、两层轻阴影 |
输入编辑区 .cr-input-editor-host |
x=349, y=605, 782×64px;横向 padding 16px;字号 14px / 21px |
输入工具栏 .cr-input-toolbar |
x=349, y=669, 782×56px;padding 12px;按钮 32px |
| 禁用发送按钮 | 32px 圆形;图标圆底填充 rgba(0,0,0,.2) |
widget 的高度由 iframe 内容决定。SVG 根据自身 viewBox 呈现比例,HTML 图表按内部容器高度扩展;iframe 向父层报告尺寸,宿主验证来源并限制最大值。
对 Ygent 的参考价值
- 给对话消息和输入区一个共享的居中最大宽度,再分别配置内边距。避免消息列与输入框在宽屏各自漂移。
- 用
min-width:0、min-height:0、flex shrink 和列表内部overflow-y:auto明确滚动容器。窄窗或长内容时,输入区仍留在底部。 - 把 Markdown 基准、段落倍率、行高、输入区字号做成角色明确的 token。Ygent 的默认 Markdown 规则与本次实测一致;用户气泡和输入区按各自控件规格管理。全局字号应明确级别、上下界、持久化、组件更新方式及固定字号例外。Ygent 六档根字号跟随 WorkBuddy,常规控件偏移在第 5、6 档封顶为 +2px。
- 在真正受限的控件上做局部响应。窄宽时优先收起次要工具标记,别先整体缩小所有字号。
- 以运行时 computed style 验收主题变量、Electron zoom 和实际像素;只读静态 CSS 很容易漏掉主题宿主注入的 token。computed
px是实测结果,不是 token 定义本身。
证据与局限
- 运行时快照与截图保存在用户私有目录
%USERPROFILE%/.ygent/imports/workbuddy-debug-20261008/,不放进仓库。 - 主要组件 CSS:
renderer/assets/lib-chat-ui-B-axvvx6.css。 - 字号管理器:
ui-docs-viewer-veG3wQhz.js,包括级别表、存储键、快捷键和旧式px样式覆盖。 - 正文段落规则:
.cr-markdown使用主题根字号和 1.75 行高,.cr-markdown p使用.875em,标题也使用相对字号 token。 - 输入布局规则:
.cr-input-box14px / 1.5;编辑器最小高 64px;输入容器运行时 inlinemin-height:96px。 - 当前会话主体宽度 832px 来自运行时 inline style;CSS 文件里
.cr-message-list__content只声明max-width:100%。具体控制该 inline 值的组件逻辑尚未追踪。 - DOM 是虚拟列表,仅包含当前已挂载部分。离开视口的消息矩形可以是负坐标,不能按快照节点数估算完整会话。
- 点击窗口不同宽度进行重复采样前,先另建输出目录。复测时同时记录 viewport、DPR、Electron zoom、主题与相关主题变量。