首页
/ impeccable layout 实战指南:从空间论点到两段评估,修复间距、节奏与视觉层级

impeccable layout 实战指南:从空间论点到两段评估,修复间距、节奏与视觉层级

2026-09-04 14:27:26作者:毕习沙Eudora

layout 是 impeccable 技能(AI 设计语言包)中 Enhance 类别的一条命令,负责"Fix spacing, rhythm, and visual hierarchy"——把产品优先级转译成阅读顺序、分组、节奏与可用空间。读完本篇,你将掌握 layout 工作流的完整执行路径:先按访客模式确定布局目标,再做相互隔离的两段评估(视觉布局评估 + 机械扫描),随后写下"空间论点"(spatial thesis)再动手编辑,最后用可验证的清单收尾并交接给 polish;同时会深入源码,看清 --scope layout 机械扫描背后 13 条 layout 域规则、检测引擎的分工以及退出码语义。

一、layout 命令在技能体系中的定位

impeccable 以"技能"(skill)形式分发给 AI 编程助手,SKILL.md 中的命令表把 layout [target] 归入 Enhance 类别,其参考文档即 layout.md。该文档的开篇一句话定义了命令的职责:

Layout turns product priority into reading order, grouping, rhythm, and usable space. Diagnose the structural problem before moving boxes.

(布局把产品优先级转化为阅读顺序、分组、节奏与可用空间。移动盒子之前,先诊断结构问题。)

这句话确立了整条工作流的第一原则:先诊断,后动手。原文档还划定了两条边界:

  • 保留既有视觉世界(Preserve the established visual world)。一条 layout 命令只在其内部改变结构;替换身份(identity replacement)属于 new-work.md 的职责,不应混入布局修复。
  • 收尾交接:当结构立住(the structure holds)时,交接给 /impeccable polish 做最终质量打磨,对应 polish.md

二、访客模式:布局目标因"访客成功定义"而异

impeccable 用"访客在这个界面上如何才算成功"划分四种模式(Persuade / Operate / Read / Experience,见 SKILL.md 的 Modes 一节)。layout.md 据此给出三类布局取向:

模式组合 布局取向
Persuade + Experience 构图可以不对称、流动,甚至刻意"破坏"——前提是所选世界(visual world)值得这样做
Operate + Read 可预测的结构、稳定的密度、可导航的线性,本身就是可用性(affordances)
Native 遵循 ios.mdandroid.md 中关于导航、安全边距(insets)、自适应与触控目标的规定

判断布局"对不对"之前,必须先确定这是哪种模式:一个营销落地页的 hero 区允许破格,而一个管理后台的表格区则要求稳定的栅格与密度——用同一把尺子量两者都会出错。

三、两段相互隔离的评估

这是 layout 工作流最核心的机制。文档要求:当子代理工具(sub-agent tool)可用且被允许时,下面两段评估要独立运行;否则由你自己按顺序完成。隔离的目的是防止"先入为主"——机械证据不能污染第一眼判断。

3.1 第一段:布局评估(Layout assessment)

检查代表性状态(representative states)与视口(viewports),并用渲染结果或源码证据回答以下全部问题(原文档逐条继承如下):

  • 阅读顺序(Reading order):做"眯眼测试"(squint test)。把细节模糊掉之后,你还能按顺序认出主元素、次元素和各主要分组吗?
  • 分组(Grouping):相关元素是否彼此靠近、不同分组之间是否有清晰分隔?还是容器在替弱 proximity(邻近性)打补丁?
  • 节奏(Rhythm):紧凑区间与宽裕区间是否构成有意的节拍?还是同一个间距值被重复到所有元素权重相等?
  • 结构(Structure):拓扑是否与内容和任务匹配?重复的卡片、列、区块是真正等价的,还是仅仅因为框架默认长这样?
  • 密度(Density):每个区域的信息量是否匹配使用频率、决策复杂度与访客模式?
  • 自适应(Adaptation):在窄屏、中屏、宽屏、缩放、本地化(长文案)各状态下,什么被重排、折叠、换行、滚动或保持固定?DOM 顺序与焦点顺序是否仍与视觉顺序一致?
  • 极端情况(Extremes):超长内容、空状态、浮层、粘性元素、安全区、小触控目标,是否暴露出结构性失败?

3.2 第二段:机械扫描(Mechanical scan)

跑 impeccable 自带的反模式检测器,只看 layout 域:

node .agent/skills/impeccable/scripts/detect.mjs --json --scope layout [target files or dirs]

命令语义与底层实现要点(均可在仓库源码中核对):

  • 入口转发detect.mjs 只是一个约 20 行的转发器,它依次探测 detector/detect-antipatterns.mjscli/engine/detect-antipatterns.mjs 两个候选,导入并调用 detectCli(),真正逻辑在 CLI 主程序中。
  • 参数解析cli/main.mjs--scope 支持逗号分隔的多值(如 --scope layout,type),取值必须来自规则注册表声明的 scope,否则报错退出;--json 把全部发现(每条 advisory 带 advisory: true 标记)以 JSON 数组打到 stdout;无目标参数时会回退扫描当前目录,非 TTY 且无目标时走 stdin(用于 hook 场景)。
  • 退出码:非 advisory 的发现数 > 0 时退出码为 2,否则为 0;advisory(建议级)发现单独打印、永不计入失败,因此不会被 --scope layout 的 CI 阻断。
  • 可选视口--viewport WxH(默认 1280x800,如 --viewport 390x844 做移动端宽度过渡检查),URL 目标(http(s) 或 file://)会走 Puppeteer 真实渲染路径,拿到真实级联与计算样式。
  • 项目上下文:扫描默认读取 .impeccable/config.json 的忽略配置与项目 DESIGN.md 设计系统,--no-config / --no-design-system 可关闭。

文档特别强调两个认知纪律:

  1. 机械证据不得进入第一段评估,两段结果要在编辑前才做综合(synthesize both passes before editing);
  2. 干净扫描不能证明层级或节奏(A clean scan cannot prove hierarchy or rhythm)——扫描器查的是可判定的失败,眯眼测试里"读不出主次"这种问题它看不见。此外,还要人工检查检测器无法解析的任意间距、溢出、层叠与容器行为。

3.3 --scope layout 到底会扫出什么:13 条 layout 域规则

scope 过滤的实现是 registry/antipatterns.mjs 中的 filterByScopes()RULE_SCOPES 由全部规则的 scopes 字段派生,CLI 只保留声明了对应 scope 的发现。带 layout scope 的规则分两类:

"AI 味"反模式(category: slop)

规则 id 名称 判定要点
nested-cards 卡片套卡片 卡片内再嵌卡片制造视觉噪音与过度深度;应改用间距、排版与分隔线压平层级
monotonous-spacing 单调间距 同一间距值到处使用、没有节奏;应对相关项用紧分组、对区块用宽分隔
icon-tile-stack 图标瓦片压在标题上方 "圆角方图标容器 + 下方标题"的通用 AI 特性卡模板;可改为图标与标题并排,或让图标不套容器

质量与可访问性(category: quality)

规则 id 名称 判定要点
content-hidden-at-rest 内容静止时不可见 页面大量文本在 reveal 处理器跑完后仍是 opacity 0 / visibility hidden(失败 reveal 特征);内容应默认可见
edge-flush-cards 卡片贴住滚动器边缘 横向滚动器/标签面板中的卡片一边留 gutter、一边贴边,边缘与圆角被裁切
text-occlusion 文本被重叠元素遮挡 文字被不透明层或第二行文本压住不可读
first-viewport-column-overflow 单列拉长首屏 多列首屏中一列远超首屏而另一列留白,折线(fold)落入单个区块内部
cramped-padding 内边距局促 文本离容器边缘太近;两种形态:元素自带文本但 padding 低于字号需求;包裹带文本子元素且自身近乎零 padding 的容器贴着可见边界。建议至少 8px,理想 12–16px
body-text-viewport-edge 正文贴视口边缘 段落无容器水平 padding 直接贴住视口左/右边;建议容器至少 16px(理想 24–32px)或 max-width + 自动外边距
text-overflow 内容溢出容器 内容渲染得比容器更宽,外溢或逼出横向滚动条
clipped-overflow-container 定位子元素被裁剪 overflow: hidden/clip 容器包绝对定位子元素,把需要逃逸的 tooltip、菜单、弹层剪掉
line-length(type+layout 双域) 行长过长 超过约 80 字符;应给文本容器 65ch–75ch 的 max-width
heading-rhythm(layout+type 双域) 标题挤在前一块之上 标题应与它所引入的内容绑定:其上方留白应大于下方留白,否则每个区块都像在给上一块做字幕

这些规则的具体检测逻辑集中在 rules/checks.mjs(5000+ 行),例如 monotonous-spacing 的匹配分支与 checkHeadingRhythmDOM()(该文件 #L3904 附近)分别对应节奏与标题留白两条规则;规则注册表还声明了引擎支持矩阵(RULE_ENGINE_SUPPORT):browser 引擎支持 element / page / layout 三类检查,static-html 引擎支持 element / page,正则引擎支持 source / page-analyzer——即部分 layout 规则只有真实浏览器渲染路径才完整生效,这也是 CLI 在检测到框架 dev server 时提示"改用 URL 扫描更准"的原因。

四、编辑前:写下空间论点(Spatial thesis)

两段评估合成结论后、动任何代码之前,原文档要求先"点名"(name)以下五件事:

  1. 主阅读路径或任务路径是什么;
  2. 什么属于一组、什么必须分开;
  3. 哪个元素领衔、哪些是支撑;
  4. 预期的密度与间距节奏;
  5. 结构在容器、视口、输入模式与内容极端之间如何变化。

然后:选择能表达这些关系的最简结构模型,按"布局原语所控制的关系"选用它们,并给可复用的间距与容器角色起语义化名字(而不是 margin: 17px 式的匿名值)。这一步的作用是把"感觉不对"翻译成可执行、可复查的结构决策。

五、Apply:动手编辑时的十一条原则

原文档 Apply 一节给出的是判断标准而非 CSS 速查,逐条继承如下:

  • 按语义分组:先用 proximity(邻近性),再考虑加容器或装饰;
  • 用"紧—松"刻意的对比制造节奏,而不是均质间距;
  • 使用有文档的间距刻度(documented spacing scale),拒绝一次性魔数。原文档给出经验值:4 为基数的刻度能提供 8-only 刻度漏掉的有用中间档位
  • 层级跟随产品优先级,不跟随框架默认;
  • 让不同的内容保持视觉差异,但别把每个分组都变成孤立组件;
  • 响应式行为是结构性的:基于"什么仍然重要"来重排、折叠、回流或揭示(reveal),而不是只缩放字号;
  • 同一组件出现在不同上下文时,优先容器感知(container-aware)组件
  • gap 比子元素 margin 更直接地表达关系时,gap 做兄弟节奏
  • 可见标记(marks)很小的时候,触控目标依然要够大可用
  • 深度(阴影、层叠)只在它澄清状态或层级时使用
  • 光学修正(optical corrections)只放在检查过渲染结果之后做,不要凭感觉预设。

收尾还有一句总纲:变化本身不是目的(Variation is not a goal by itself)。重复应该服务于识别;只有当内容或优先级变化时才打破它。

六、Verify:用证据验收,不接受"裸 yes"

结构改完后,用以下 8 条清单逐项验收,每项都必须给出渲染或源码证据,然后重跑机械扫描:

  1. 眯眼测试仍能按顺序看出主元素、次元素与主要分组;
  2. 阅读与任务路径在每个支持的尺寸下保持清晰;
  3. 相关内容自然成组,不相关内容没有糊在一起;
  4. 紧与松的间距构成有意节奏,而非单调重复;
  5. 密度匹配使用频率与内容复杂度;
  6. 长文本、空状态、本地化、缩放、动态内容都不破坏结构;
  7. 键盘、触控与辅助技术的操作顺序与视觉顺序一致;
  8. 最终机械扫描没有无法解释的发现(rerun detect.mjs --scope layout)。

文档原话要求:不要用一句光板 "yes" 冒充验收(Do not substitute a bare "yes" for verification)。当结构立住时,交接给 /impeccable polish

七、Live 模式的签名参数:density

当通过 live.md 描述的 live 变体模式做可视化迭代时,layout 领域有固定的"签名参数"约定:每个变体声明一个粗粒度的 density 参数,并且所有间距都对着 var(--p-density, 1) 书写:

{"id":"density","kind":"range","min":0.6,"max":1.4,"step":0.05,"default":1,"label":"Density"}

参数契约(见 live.md 的参数一节)要点:

  • range 参数驱动 CSS 变量 --p-<id>,组件 <style> 里写成 var(--p-<id>, 默认值)steps 参数驱动 data-p-<id> 属性选择器;toggle 两者都驱动。layout.md 的 density 声明里 min/max/step/default/label 字段完整,是 range 类型的标准形态;
  • 只有当拓扑真正分叉时(topology genuinely branches)才额外增加一个结构性参数——参数不是越多越好,密度旋钮应能覆盖大多数布局变体。

这样做的收益是:同一个布局变体的"松紧"被收敛成一个 0.6–1.4 的连续旋钮(默认 1),间距规则不用为每个变体重写,验收时也能直接拖动对比节奏变化。

八、验证与测试依据

这套 layout 工作流在仓库中有对应的测试与 fixture 支撑,可用于自查理解:

  • tests/detect-antipatterns-fixtures.test.mjs:对 tests/fixtures/layout.htmltests/fixtures/cramped-padding.html 等 fixture 做静态 HTML/CSS 引擎断言,例如 nested-cards 的 flag 列应产出 ≥4 条发现,且 monotonous-spacing 作为页面级规则在该 fixture 上不触发(页面级规则需要完整布局矩形,测试注释明确说明了这一分层)。
  • tests/detect-antipatterns.test.js:正则引擎路径的单测,如 detects monotonous spacing via regex(约 #L793)验证同一规则在源码扫描路径下同样可用。
  • tests/fixtures/ 目录还包含 text-overflow.htmledge-flush-cards.htmlfirst-viewport-column-overflow.htmltext-occlusion.html 等与本文规则一一对应的样例页,可直接用 detect.mjs 复现扫描结果。

九、小结:layout 工作流的执行顺序

步骤 动作 原文档章节
1 判定访客模式,确定布局取向;保留既有视觉世界 Visitor mode
2 独立跑布局评估(7 问,全部要证据) Two isolated assessments
3 独立跑机械扫描 detect.mjs --json --scope layout,再综合两段 Two isolated assessments
4 写下空间论点(5 项点名 + 最简结构模型) Set the spatial thesis
5 按 11 条原则编辑(4 基数间距刻度、gap、容器感知组件等) Apply
6 8 条清单逐项取证验收,重跑扫描,无未解释发现 Verify
7 结构立住后交接 /impeccable polish;live 变体统一声明 density 参数 Verify / Live-mode signature params

核心可以浓缩成文档第一句:先诊断结构问题,再移动盒子——诊断有双通道(眯眼测试式评估 + 13 条 layout 域规则扫描),动手有空间论点约束,收尾有证据清单兜底。这套流程不产出"更花哨的布局",而是产出"产品优先级在空间里被如实表达、且在每个视口与极端内容下都立得住"的布局。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
981
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384