Astryx 空间层级设计规范:用间距梯度与对齐构建可感知的视觉分组
【免费下载链接】astryxAn open source design system that's fully customizable and agent ready项目地址: https://gitcode.com/GitHub_Trending/as/astryx
导读
空间层级(Spatial Hierarchy)是 Astryx 设计体系中定义「感知分组」的设计规范:在没有容器边框的情况下,仅靠邻近关系(proximity)、间距梯度(spacing tiers)与对齐(alignment)来传达"哪些内容属于一起"。本文以 docs/design/spatial-hierarchy.md 为骨架,结合 layout-primitives 与 layout-regions 两个组件族契约、container-padding 架构 与 theme-tokens 架构 的源码实现,完整呈现该规范的设计原则、分组层级、状态与响应式要求、可访问性意图,以及它在 Astryx 组件库中的落地路径。读完本文,你将掌握一套可执行的空间分组检查方法,并能在自己的 Astryx 页面中按规范组织表单、仪表盘等密集界面。
一、规范定位与边界
design:spatial-hierarchy是 Astryx 文档栈中的一份design 类型记录(详见 docs/design/README.md 中对各类记录的划分),目前处于draft权威等级,负责人为ernestt与cixzhang,评审触发词为visual / layout / responsive。
它的核心主张只有一句话:
用户应当在阅读个别标签之前,先理解什么内容属于一起。密集的表面保持有序,靠的是邻近关系表达联系,而不是靠每一组内容都被另一个容器包裹。
规范开篇即以「User intent」点明这一立场:空间层级的目标是让"归属感"先于"阅读"被感知。这与项目中family:layout-primitives(任意子内容的一维/二维排布)和family:layout-regions(页面结构区域)形成互补——布局族提供机制,本规范提供感知判据。
内容边界(Content boundary)
该文件只定义感知分组,明确不定义以下内容(边界说明见 docs/design/spatial-hierarchy.md 结尾):
- 间距 token 的具体数值(由 theme-tokens 架构拥有);
- padding 算法(由 container-padding 架构拥有);
- 组件 props 与 DOM 结构(由组件/族契约拥有);
- 审计评分阈值(由审计契约拥有)。
也就是说,这是一份"判据规范",具体的数值与机制在别处。下文将分别从 token 层、组件层、容器层说明它是如何被支撑的。
二、设计原则:四条驱动规则
规范定义了四条设计原则(DR1–DR4),构成一切空间决策的判据:
| 原则 | 内容 | 强度 |
|---|---|---|
| DR1 — 邻近关系传达联系 | 紧密相关的元素必须比无关内容靠得更近 | MUST |
| DR2 — 间距随分组层级增长 | 从局部内容到组、从组到区块,间距必须逐级增大 | MUST |
| DR3 — 空间先于容器 | 作者应先用间距和对齐建立分组,再考虑加卡片或边界 | SHOULD |
| DR4 — 变化是有意的 | 构图必须使用足够的空间对比来揭示层级,而不是到处使用同一个间距 | MUST |
其中 DR3 直接呼应了规范的用户意图:容器是"最后手段",而不是第一反应。DR4 则要求空间具有"对比度"——如果整页只有一个 gap,层级就会消失。这两条在实践中对应着 docs/families/layout-primitives.md 中"共享小词汇表"的设定:Stack、Grid、Center 等原语共用同一套SpacingStep间距词汇,但允许每个组件在其排列模型上表达不同的 gap 值——这正是空间对比得以实现的机制基础。
三、解剖与层级:四种角色
规范用一张表定义了空间层级的四种解剖角色:
| 角色 | 用途 | 必需关系 |
|---|---|---|
| 局部间距(local gap) | 将标签、值、图标或控件与紧邻内容连接 | 必须小于其所在组的组间距 |
| 组间距(group gap) | 分隔对等控件或内容组 | 大于局部间距、小于区块分隔 |
| 区块间距(section gap) | 分隔不同关注点 | 强到能通过"眯眼测试" |
| 对齐边(alignment edge) | 跨行或跨区域连接相关内容 | 在同一分组层级内一致重复 |
注意这里用到了"眯眼测试"(squint test)——眯起眼睛模糊化细节后,仅靠留白轮廓仍能看出内容分块。区块间距的判定标准就是"足以幸存于眯眼测试"。
规范给出的两个代表性例子:
- 表单:标签与字段之间使用最紧密的关系(局部间距);字段与字段之间使用更大的间距(组间距);区块与区块之间使用最大的间距(区块间距)。
- 仪表盘:先通过间距与对齐分隔区域,之后才考虑嵌套卡片——这与 DR3「空间先于容器」完全一致。
四、状态表现:稀疏、充实、空与错误态
规范要求:空间关系必须在充实(populated)、稀疏(sparse)、空(empty)和错误(error)状态下都可感知。条件性内容不得使分组顺序塌缩或反转。
这提示了一个容易踩坑的场景:错误提示、辅助文本、可选操作的出现不能把"原本属于同一组"的内容挤得四分五裂,也不能把不同组的内容推挤到一起。在 Astryx 中,这类动态内容通常挂在 Field、InputGroup 等控件下方,需要依赖 docs/families/layout-regions.md 中"FR1 — 区域拥有结构而非产品语义"的边界来保持分组稳定:区域只负责空间边界,内容的出现与消失由调用方组合,从而避免结构性变化破坏空间节奏。
五、响应式与输入行为:DR5 与 DR6
| 原则 | 内容 |
|---|---|
| DR5 — 重排保留分组 | 在受限宽度下,内容可以堆叠或移动,但局部、组、区块关系必须仍然可区分 |
| DR6 — 动态内容保留节奏 | 校验信息、辅助文本、可选操作必须始终与它们所服务的内容保持关联 |
DR5 意味着"堆叠"不是"乱序"的借口——即便从横向变为纵向,层级梯度仍然要成立。在实现层面,这对应 docs/families/layout-primitives.md 的 FR7「响应式行为是显式的」:Grid 通过 intrinsic 轨道数学重排,Stack 仅在配置了wrap时换行,Center 不产生断点;该族不承诺共享断点或自动区域交换。因此"窄屏下保留分组"的责任落在调用方组合上,而不是由某个组件自动完成。
DR6 则与 layout-regions 族契约一致——区域只提供边界,校验/辅助内容的关联性由内容自身的组合保证。
六、可访问性意图
规范强调:视觉分组应与语义阅读顺序和程序化关系一致。当一组内容需要标签、标题或其他语义边界时,不能只依赖留白作为唯一信号。
换句话说:空间是增强,不是替代。分组若承担"这是什么"的信息职责,就必须有对应的语义(heading、fieldset/legend、role 等)。这一点与 layout-regions 的 FR8「地标语义保持显式」相互呼应——LayoutHeader/Content/Footer/Panel不会因为视觉摆放自动获得banner/main/contentinfo等角色,调用方必须显式提供 role 与 label(相关实现可查 LayoutSlots.test.tsx 中的地标断言)。
七、源码级支撑:从 token 到组件的落地
以下三层实现共同支撑空间层级规范,全部位于packages/core。
7.1 间距 token 层:统一的数值词汇
规范不定义 token 数值,但空间层级需要一套可对比的间距刻度。在 tokens.stylex.ts 中,spacingDefaults定义了 0–11 的完整刻度,其中被 layout-primitives 族契约接纳为SpacingStep公开取值的是:
| Step | 0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | | ---- | -- | --- | - | --- | - | - | - | - | - | - | -- | | 值 | 0px | 2px | 4px | 6px | 8px | 12px | 16px | 20px | 24px | 32px | 40px |
这些是默认值——按照 theme-tokens 架构 的 INV3「token 名描述语义角色」,组件消费的是--spacing-*语义名而非具体像素,主题可以整体改写刻度而不改变组件的语义。这也意味着空间层级的"梯度"是可主题化的:一套紧凑主题与一套宽松主题可以共享同一份布局代码。
7.2 布局原语层:用 gap 表达组间距
l-ayout primitives 族契约 规定:gap 分隔排列的项目,padding 内缩成员自身的内容盒(FR4),两者语义严格区分——这正好对应规范中"局部间距 vs 容器内缩"的分工。
在 stack.stylex.ts 中可以看到 gap 的完整映射:每个SpacingStep同时写入columnGap与rowGap,引用spacingVars['--spacing-N']token。这意味着同一个gap值在横竖两个方向语义一致,为 DR2 的"梯度递增"提供了稳定标尺。
实际组合示例(横向 Stack,组间距取 step 3):
<div {...stylex.props(...stack({ direction: 'horizontal', gap: 3 }))}> {/* 组内使用更小的局部间距,见下 */} <Field /> <Field /> </div>局部间距(标签↔字段)则应在每个字段内部实现,整体形成「局部 4px < 组间 12px < 区块 24px+」的梯度。这正是 DR2 在代码中的直接翻译。
7.3 容器与对齐层:间距优先、边界兜底
规范要求间距与对齐优先于容器(DR3),而 Astryx 的 container-padding 架构 正是"让 padding 可被补偿、让对齐有据可依"的底层协议:
container()将 Card、Section、Dialog 的 padding 降级为内部逻辑边变量--container-padding-*;- Layout 通过
--layout-padding-outer-* / --layout-padding-inner-*区分外壳边与相邻区域边; - bleed 消费者(Section、ScrollableArea、Layout、Divider、Table)在各自契约覆盖的边上减去继承的内缩量,实现"贴边";
- 对齐消费者(Toolbar 等)读取当前内联内缩来对齐可见内容,而非对齐堆叠的触摸目标 padding。
在 padding.stylex.ts 中可以看到边补偿变量与 padding 声明成对发布:containerPaddingInlineVarStyles将每个 step 同时写入--container-padding-inline-start/end。这就是规范中"alignment edge 在同一分组层级内一致重复"的实现——对齐边不是一个视觉约定,而是有 CSS 变量背书的可测几何。
值得注意的边界:按照 container-padding 架构 的 INV8「参与是显式的」,Stack 与 Center 目前只应用局部 padding、不发布该协议,因此其内部的后代不能假定 full-bleed 补偿。这恰好与 DR3 互补:先用间距与对齐建立分组,容器与出血是显式选择的进阶能力,而非默认行为。
八、决策日志与开放问题
决策状态
规范明确:尚无仓库级设计决策批准本记录。它从公开的 Design Conventions wiki 提炼了间距意图,但没有拷贝 token 值或审计阈值。这意味着它目前是"判据级草稿",需要与下文开放问题的证据集一起,才能提升为current权威等级。
开放问题
| 编号 | 问题 |
|---|---|
| OQ1 — 证据集 | 哪些页面、表单和集合示例最能验证每个分组层级? |
| OQ2 — 容器例外 | 哪些组件族除了空间分组外,还要求可见的容器包裹? |
OQ2 正是 DR3 的反面问题——规范不禁止容器,只要求容器是"有意选择"而非默认动作。从 docs/design/README.md 可知,任何规范性截图/示意图都应放到docs/design/assets/spatial-hierarchy/下并附带 alt 文本、状态、主题/模式与视口信息;该目录在本次审阅时尚未包含规范性资产。
组件契约关联
规范声明未断言任何组件链接,layout-primitives 与 layout-regions 是"待采纳评审的候选关系"。这与它的草稿状态一致——族契约已批准(authority: current),而空间层级规范尚未跟上,二者之间的正式绑定仍需采纳评审。
九、落地检查清单
将本规范转化为可执行的检视步骤:
- 先眯眼测试:模糊页面细节后,仅凭留白是否能分出不混淆的区块?这是 DR4/区块间距的及格线。
- 验证梯度单调:局部间距 < 组间距 < 区块间距是否处处成立(DR2)?在 Astryx 中对应从字段内部 →
Stack gap→Section分区的数值递增。 - 优先间距而非容器:新增分组时先调 gap 与对齐,再决定是否需要 Card 或 Divider(DR3)。
- 检查状态与窄屏:在充实/稀疏/空/错误四种状态与窄宽度下重跑第 1、2 步(DR5/DR6)。
- 补充语义边界:视觉分组是否与阅读顺序一致?需要标签/标题/地标的组是否补上了语义(可访问性意图,参考 LayoutSlots.test.tsx 的地标写法)。
十、从草案走向规范的路线
综合 docs/design/README.md 的晋升规则:design:spatial-hierarchy当前为draft,promote 到current需要满足——解决 OQ1 的证据集、决策 OQ2 的容器例外、补充docs/design/assets/spatial-hierarchy/下的规范性视觉资产、并通过cixzhang/imdreamrunner对 PR head 的精确审批。在此之前,它是一份"意图正确、机制已由布局族与容器架构支撑"的判据文档,可以在任何 Astryx 页面中直接用于设计评审。
【免费下载链接】astryxAn open source design system that's fully customizable and agent ready项目地址: https://gitcode.com/GitHub_Trending/as/astryx
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考