代码块用户界面系统 是做什么的?
目的
代码块用户界面系统为显示源代码片段、API请求/响应负载、多文件代码示例、终端命令行和代码差异比较提供了一个标准化、可访问且高可读性的布局框架。代码块是技术文档、开发者工具营销网站、API门户、工程博客和SaaS平台中的关键交互组件。
设计有效的代码界面需要平衡等宽字体可读性、跨亮色和暗色主题的高对比度语法令牌高亮、粘性头部操作工具栏(语言徽章、标签式文件导航、复制到剪贴板触发器)、行号、行级高亮/聚焦、换行与水平滚动行为以及可访问的屏幕阅读器体验。该技能为代码UI呈现建立了空间规则、令牌颜色对比标准、交互机制和WCAG AA合规指南。
使用案例
- 开发者文档和API参考门户: 呈现多语言SDK示例(例如,cURL, Node.js, Python, Go, Rust)和API响应。
- 开发者工具落地页: 展示主打代码片段、CLI安装命令和交互式产品演示块。
- 工程博客和教程: 渲染行内和块级代码示例,带有特定行标注、逐步代码高亮和行内注释。
- 版本控制和代码审查界面: 显示代码差异(
+添加,-删除)、行内评论和提交片段。 - 代码游乐场和片段分享工具: 构建多标签文件编辑器、预览面板和可嵌入的片段卡片。
何时不使用
- 完整的浏览器内代码编辑器(IDE): 对于需要Canvas渲染、虚拟化AST树、多光标编辑和语言服务器协议(LSP)集成的复杂交互式Web IDE(例如,Monaco Editor, CodeMirror),请使用专门的编辑器实现。
- 通用表单文本输入: 对于没有语法高亮或行号的多行纯文本字段,请使用
form-design-system。 - 行内文本代码徽章: 对于正文段落中简短的单词代码引用(例如,
npm install),请在article-layout-system中使用行内<code>样式。 - 结构化数据表格: 对于格式化为行列的表格键值数据或数据库查询,请使用
data-table-ui-system或property-and-attribute-system。
输入
- 代码内容和语法类型: 语言分类法(例如,TypeScript, JSON, Bash, YAML, GraphQL, SQL)和结构特征(单文件、多文件标签、差异)。
- 主题上下文: 亮色模式和暗色模式下(来自
accessible-color-system和dark-theme-design-system)用于表面背景、边框和语法令牌的活动调色板令牌。 - 等宽字体排版令牌: 首选字体栈(例如,
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace)、字体大小和行高(来自fluid-typography-system)。 - 操作触发器: 每个块所需的特定交互功能(例如,一键复制按钮、行号切换、自动换行切换、全屏展开、外部沙箱链接)。
输出
- 代码容器和头部工具栏规范: 代码块容器、粘性头部栏、语言指示器、文件路径标签和操作按钮组的空间布局。
- 可访问的语法令牌调色板: 跨亮色和暗色主题的、符合WCAG AA(最小对比度4.5:1)的令牌颜色映射,用于关键字、字符串、函数、变量、注释、运算符和类型。
- 行级层次结构和注释系统: 行编号、行高亮/聚焦覆盖、差异指示器(
+/-)和行级锚点链接的蓝图。 - 可访问的屏幕阅读器和键盘导航模型: ARIA角色属性、键盘焦点路径、行号遮蔽(
aria-hidden="true")和aria-live复制状态公告。 - 响应式溢出和滚动策略: 水平滚动条、粘性操作工具栏、自动换行切换和移动端视口适配的规则。
工作流程
1. 构建代码块外壳和头部栏
将容器和头部操作栏设计为一个统一的、连贯的整体:
- 容器架构: 设置圆角容器(
border-radius: 8px; border: 1px solid var(--border-subtle); overflow: hidden; background: var(--surface-code);)。使用鲜明的表面背景(通常默认使用暗色模式或匹配主题的表面)。 - 头部工具栏布局: 渲染一个粘性顶部头部栏(
display: flex; align-items: center; justify-content: space-between; padding: 8px 16px; background: var(--surface-code-header); border-bottom: 1px solid var(--border-subtle);)。 - 头部左侧部分(标签和元数据):
- 单文件: 显示文件路径/名称(例如,
src/auth/jwt.ts)并带有微妙的文件类型图标,或一个大写的语言徽章(例如,TYPESCRIPT)。 - 多文件/多语言: 渲染标签按钮(
role="tablist")。活动标签具有高对比度文本和底部边框/指示器(border-bottom: 2px solid var(--brand-primary))。
- 单文件: 显示文件路径/名称(例如,
- 头部右侧部分(操作): 分组实用操作触发器:
- 复制按钮: 32x32px图标按钮(
aria-label="Copy code to clipboard"),带有清晰的复制图标,并在较宽视口上显示标签。 - 换行/滚动切换(可选): 图标按钮,用于在软换行(
white-space: pre-wrap)和水平滚动(white-space: pre)之间切换。 - 展开/沙箱链接(可选): 在StackBlitz、CodeSandbox或全屏中打开片段的触发器。
- 复制按钮: 32x32px图标按钮(
2. 建立等宽字体排版和布局网格
确保技术阅读和代码扫描的最佳可读性:
- 字体栈: 定义一个清晰、高可读性的等宽字体栈:
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace。确保字体特性设置能够清晰区分0(零)和O(大写O),以及1(一)、l(小写L)和I(大写I)。 - 字体大小和行高: 设置
font-size: 0.875rem(14px) 并配合适当的行高(line-height: 1.6/ 22.4px)。避免过紧的行高导致代码括号和运算符重叠。 - 代码正文容器: 使用
<pre class="code-block"><code class="language-typescript">,并设置display: block; overflow-x: auto; padding: 16px 0; margin: 0; font-family: var(--font-mono);。
3. 设计行号、行高亮和差异
构建行级元素,而不影响复制粘贴或屏幕阅读器行为:
- 行结构: 将每行格式化为一个独立的块容器(
display: table-row;或display: flex; width: 100%;)。 - 行号: 在左侧沟槽中渲染行号(
display: table-cell; text-align: right; width: 40px; padding-right: 16px; user-select: none; color: var(--text-code-muted);)。- 无障碍规则: 将行号包裹在
<span aria-hidden="true">中,或使用CSS计数器内容(content: counter(line)),这样在选择文本时不会复制行号,且屏幕阅读器在阅读代码语句之间不会朗读行号。
- 无障碍规则: 将行号包裹在
- 高亮/聚焦行: 为了在教程或差异中吸引对关键行的关注:
- 应用显式的行高亮背景(
background: var(--surface-code-highlight); border-left: 3px solid var(--brand-primary);)。 - 确保高亮覆盖层跨越代码容器的整个滚动宽度(
min-width: 100%)。
- 应用显式的行高亮背景(
- 差异视图行(
+添加 /-删除):- 已添加行: 微妙的绿色背景(
background: rgba(34, 197, 94, 0.15); border-left: 3px solid var(--color-success);)。在沟槽中显示+符号,并用<span class="sr-only">添加:</span>包裹以供屏幕阅读器识别。 - 已删除行: 微妙的红色背景(
background: rgba(239, 68, 68, 0.15); border-left: 3px solid var(--color-danger);)。在沟槽中显示-符号,并用<span class="sr-only">删除:</span>包裹以供屏幕阅读器识别。
- 已添加行: 微妙的绿色背景(
4. 创建可访问的语法令牌调色板
语法令牌必须满足针对代码块背景(var(--surface-code))的WCAG AA对比度(最小4.5:1):
- 基础文本/变量: 中性浅色(例如,
#E2E8F0在#0F172A背景上;对比度约12.5:1)。 - 关键字(
const,import,return,async): 鲜艳的紫色/品红色(例如,#C084FC;对比度约7.2:1)。 - 函数和方法(
fetchData,useState): 亮蓝色/青色(例如,#38BDF8;对比度约8.5:1)。 - 字符串(
"https://api.example.com"): 柔和的绿色/翠绿色(例如,#4ADE80;对比度约9.1:1)。 - 数字和布尔值(
404,true): 暖橙色/琥珀色(例如,#FB923C;对比度约7.8:1)。 - 注释(
// Handle token response): 柔和的冷灰色,符合WCAG AA要求(例如,#94A3B8;对比度约5.1:1)。切勿对注释使用低对比度灰色(例如,2:1)。 - 运算符和标点(
=>,{,},;): 中等中性色(例如,#CBD5E1;对比度约10.2:1)。
5. 构建复制到剪贴板和操作反馈状态
为复制操作提供即时反馈可以防止重复点击和用户挫败感:
- 默认状态: 显示带有复制图标(两个重叠矩形)的图标按钮和可选标签("复制")。
- 悬停/聚焦状态: 提升的表面背景或边框高亮(
background: var(--surface-hover); outline: 2px solid var(--focus-ring))。 - 活动/成功状态: 点击时,将图标更改为勾选图标,将按钮标签更新为"已复制!",并应用成功颜色色调(
color: var(--color-success))。 - 屏幕阅读器通知: 通过一个不可见的
aria-live="polite"区域动态宣布复制状态:"代码已复制到剪贴板"。 - 超时重置: 2000ms后将按钮重置为默认状态。
6. 移动端和响应式适配
确保较长的代码片段在小视口上保持功能:
- 水平滚动包含: 允许在移动设备上对长行进行水平滚动(
overflow-x: auto),而不会触发页面级水平滚动条溢出。 - 粘性头部工具栏: 保持头部工具栏固定(
position: sticky; top: 0; z-index: 10;),以便在滚动超过100行代码时,复制按钮和活动文件标签仍然可访问。 - 移动端点击目标: 确保复制按钮、换行切换和多文件标签满足触摸设备上最小44x44px的点击目标。
决策规则
语法令牌对比度和主题模式
| 语法类别 | 推荐令牌角色 | 亮色主题颜色(在 #F8FAFC 上) | 暗色主题颜色(在 #0F172A 上) | 最低对比度 |
|---|---|---|---|---|
| 关键字 | --token-keyword | 深紫色(#6B21A8) | 亮紫色(#C084FC) | ≥ 4.5:1 |
| 函数 | --token-function | 深青色(#0369A1) | 天蓝色(#38BDF8) | ≥ 4.5:1 |
| 字符串 | --token-string | 森林绿(#15803D) | 亮翠绿(#4ADE80) | ≥ 4.5:1 |
| 数字/布尔值 | --token-number | 深琥珀色(#C2410C) | 亮琥珀色(#FB923C) | ≥ 4.5:1 |
| 注释 | --token-comment | 柔和石板灰(#475569) | 柔和石板灰(#94A3B8) | ≥ 4.5:1 |
| 基础/变量 | --token-base | 炭黑色(#0F172A) | 清爽亮色(#F8FAFC) | ≥ 7.0:1 |
换行与水平滚动策略
- 水平滚动(
white-space: pre)(默认推荐): 保留代码布局完整性、缩进对齐和多行格式。对于缩进传达语义结构的Python、YAML和代码差异至关重要。 - 软换行(
white-space: pre-wrap)(可选模式): 推荐用于长终端输出字符串、命令行示例或窄侧边栏小部件,因为水平滚动会中断阅读流程。
约束
- 无障碍性 (WCAG 2.1 AA):
- SC 1.4.3 对比度(最低): 所有语法高亮令牌颜色和注释必须达到针对代码背景的最小对比度4.5:1。
- SC 2.1.1 键盘: 用户必须能够使用
Tab和Space/Enter键导航到并激活代码块头部按钮(标签、复制按钮)。 - SC 4.1.3 状态消息: 复制按钮反馈必须通过一个
aria-live="polite"区域向辅助技术宣布。 - SC 1.3.1 信息和关系: 行号必须对屏幕阅读器隐藏(
aria-hidden="true"或CSS计数器),以避免在阅读过程中穿插数字。
- 文本选择和复制: 在代码块中选择文本时,绝不能将行号或差异标记(
+/-)复制到剪贴板缓冲区。 - 布局偏移防止: 展开多文件标签或切换行换行必须指定固定的行高或容器边界,以防止累积布局偏移(CLS)。
常见失败模式
- 难以阅读的低对比度注释: 对注释使用微弱的灰色文本(例如,
#4A5568在#1A202C上,对比度2.8:1),认为注释不重要,违反了WCAG AA指南。 - 复制行号: 在
<pre>内部将行号渲染为原始文本,导致复制粘贴产生带有1 2 3 4前缀的无效代码片段。 - 未宣布的复制操作: 更改复制按钮的视觉图标,但未更新
aria-label或发送aria-live公告,使屏幕阅读器用户不确定操作是否成功。 - 页面级溢出扩散: 未能在
<pre>上设置max-width: 100%和overflow-x: auto,导致120个字符的代码行在移动设备屏幕上撑破页面布局。 - 水平滚动中的不可访问焦点陷阱: 在可滚动的代码块上放置
tabindex="0",但没有清晰的键盘视觉轮廓指示器,导致键盘用户卡在长代码块内部。
验证标准
- 代码块具有一个结构化的容器,带有粘性头部工具栏,显示语言、文件...
...(由于原文被截断,此处按指令保持原样,若需完整翻译请提供完整原文)