Pixel HUD UI
一个 UI 框架,而不仅仅是颜色主题。它包含三个层次,良好的效果需要三者结合:
- 基础(Foundations):4px 网格、针对 12px 像素字体调整的字号阶梯、颜色角色(每种颜色代表一种含义)、1px 规则代替阴影、步进式动画。
- 控件(Controls):面板和标题栏、带意图的按键、图标键、标签页、分段控件、列表行、表单字段、输入框、选择器、方形复选框和单选按钮、灯开关、滑块、进度条、指示灯、标签、徽章、键帽、菜单、工具提示、对话框、提示条、表格、代码块、文章、加载器、空状态。每个控件都有固定尺寸和一个统一的状态模型(悬停、按下、聚焦、选中、禁用、加载中、错误)。
- 调色板(Palettes):
--hud-*标记,使框架可以适配任何颜色,包括应用自身的品牌色。
文件
| 文件 | 说明 |
|---|---|
references/design-system.md | 设计规范。 原则、基础以及每个控件的结构、尺寸、状态、使用时机和无障碍说明。设计前请先阅读。 |
assets/pixel-hud.css | 实现:标记、[data-skin="pixel"] 下的浅色全局样式,以及 hud-* 控件类 |
assets/palettes.css | starward(深空,暗色)、terminal(灰绿,暗色)、paper(暖沙色,浅色) |
assets/fonts.css | Fusion Pixel 12px(OFL 许可证),固定在 jsDelivr 上;或通过 @fontsource 自托管 |
assets/pixel-caret.js | 可选的文本字段 3px 方块光标(data-pixel-caret) |
assets/demo.html | 每个控件及所有状态,带调色板切换器:视觉参考 |
references/integration.md | 各技术栈的配方:映射应用颜色、Tailwind、shadcn/ui、React/Next、Vue、作用域、无闪烁切换、自托管字体 |
scripts/check-contrast.mjs | 任意调色板的 WCAG 检查:node scripts/check-contrast.mjs my.css |
工作流程
1. 阅读规范并查看演示
阅读 references/design-system.md(至少包括原则、基础以及任务所需的控件),并查看 assets/demo.html。规范说明了每个控件为何如此设计;遵循它才能使界面被识别为这个框架,而非“带像素字体的暗色主题”。
2. 了解项目
在复制任何内容之前,需了解:
- 技术栈以及全局 CSS 的加载位置(布局文件、
main.ts、index.html、Tailwind 入口); - 当前颜色的定义方式(CSS 自定义属性、Tailwind 主题、shadcn 的 HSL 变量、组件中的十六进制);
- 这是一个新 UI 还是重新样式化、是应用的唯一外观还是可切换主题、作用于整个页面还是某个区域。
这些决定了颜色映射(步骤 4),并能避免与应用的样式产生冲突。
3. 添加工具包
将 pixel-hud.css、fonts.css、palettes.css(如果使用内置调色板)和 pixel-caret.js(如果应用有文本输入框)复制到项目中。加载顺序:字体 → 调色板 → pixel-hud.css,放在应用自身基础样式之后。
4. 选择颜色
- 使用内置调色板:
data-hud-palette="starward" | "terminal" | "paper"。 - 使用应用自己的颜色:用一个代码块将应用的变量映射到
--hud-*(references/integration.md> 映射应用颜色)。保留品牌,加入框架。 - 创建新调色板:按照规范中的“新建一套配色”操作。
然后对任何你编写或映射的调色板运行 node scripts/check-contrast.mjs <文件>,并修复所有 FAIL:控件依赖于在每种表面上都可读的条、文本和绿色。
5. 开启框架
<html data-skin="pixel" data-hud-palette="starward">
如果是可切换主题,则在首次渲染前设置这些属性(references/integration.md > 无闪烁切换)。如果只对某个区域应用样式,则将两个属性放在其容器上。
6. 使用控件构建
全局样式已经处理了字体、方形直角、原生输入框、选择框、范围滑块、复选框、滚动条、聚焦环、选中效果和扫描线。通过类名为每个元素指定角色,并遵循规范中的尺寸和状态:
| 需要 | 控件(类名) |
|---|---|
| 分组相关信息 | .hud-panel + .hud-titlebar(+ .hud-titlebar__actions),主体 .hud-panel__body,分区 .hud-subhead |
| 主要操作 | .hud-btn.is-solid(意图:accent、go、warn、info、danger) |
| 次要操作 | .hud-btn |
| 仅图标操作 | .hud-icon-btn + aria-label |
| 切换视图 | .hud-tabs > .hud-tab[aria-selected] |
| 从 2-5 个值中选一个 | .hud-segmented > button[aria-pressed] |
| 可导航列表 | .hud-row[aria-current] |
| 带标签的输入框 | .hud-field > .hud-label + input/select + .hud-help / .hud-error |
| 下拉选择 | .hud-select > select |
| 是/否,从多个中选一个 | .hud-check、.hud-radio(方形标记) |
| 即时开/关 | button.hud-switch[role=switch][aria-checked] > .hud-switch__knob |
| 级别/进度 | .hud-gauge + --value(data-state 为 warn/alert) |
| 状态 | .hud-lamp[data-state] |
| 值、ID、参数 | .hud-tag;数量 .hud-badge;按键 kbd |
| 菜单、提示、模态框、反馈 | .hud-menu、.hud-tooltip、.hud-backdrop > .hud-dialog、.hud-toasts > .hud-toast |
| 数据、代码、文章 | table.hud-table、.hud-code、.hud-prose |
| 命令/聊天输入 | .hud-input + data-pixel-caret |
| 等待中、无内容显示 | .hud-loader、按键上的 aria-busy、.hud-empty |
将类放在组件源码(JSX、模板)中,通过组件库的 className/class 属性传递,而不是编写针对框架内部的选择器:这样代码能经受重构并保持清晰可读。
当重新样式化现有应用时,首先将每个现有组件映射到上表(在你的回复中提供一个简短的列表有助于用户理解),然后应用它。
7. 检查结果
- 截图页面(或打开页面)并与
assets/demo.html比较。 - 确认像素字体已加载(
document.fonts、Network 标签页);CSP 可能阻止 jsDelivr,此时需自托管。 - 使用 Tab 键遍历:每个控件都可到达,1px 绿色聚焦环可见。
- 在主要控件上遍历状态模型:悬停、按下、禁用、加载中、错误。
- 对比度脚本对正在使用的调色板通过。
最重要的规则
规范中有完整说明;以下是最常被违反的规则:
- 方形且扁平。 无圆角、无模糊阴影、除扫描线外无渐变。只有叠加层可使用硬偏移阴影。
- 颜色各司其职。 条 = 结构和选中;绿色 = 开启、强调、聚焦;黄色 = 数值;橙色 = 注释和警告;红色 = 危险。绿色被用作装饰将失去“开启”的含义。
- 选中 = 反色。 条底色填充,深色文字;行添加 3px 绿色边缘。在条色背景上,悬停时反过来反色。
- 每个区域只有一个实心主要操作;并排操作各自有独立的意图颜色,且禁用时保持该颜色(淡化而非描边)。
- 标题栏仅用于面板头部。 表格和代码头部使用柔和色调
--hud-bar-soft。 - 尺寸来自阶梯:控件 24/28/32px,间距基于 4px 网格,文字 12/14/16/24/36px。
常见陷阱
- 框架会强制其作用域内的
border-radius: 0 !important。如需保留某个圆角元素(如头像),可将皮肤作用域限定在排除该元素的容器上。 color-mix()需要 Chrome/Edge 111、Safari 16.2、Firefox 113;对于旧浏览器,请将--hud-bar-soft/--hud-bar-line设置为纯色。- 设置
display的类可能会显示hidden元素;框架会在其作用域内重新隐藏[hidden],因此切换显示时优先使用hidden属性。 - 通过代码设置字段值的框架不会触发
input事件;如果需要光标立即移动,请在此类更改后调用field.__pixelCaret.update()。 - 扫描线位于非常高的 z-index 并带有
pointer-events: none;在会遮挡内容的位置(如截图、canvas 应用)可通过data-hud-scanlines="off"关闭。