用 Impeccable Layout 重构结构:阅读顺序、分组、节奏与可用空间的诊断式排版方法
【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccable
当一次 UI 重构需要动的是“盒子之间的空气”,而不是颜色与字体时,Impeccable 的 Layout 参考定义了一套可执行的方法:先把产品优先级翻译成阅读顺序、分组、节奏与可用空间,再诊断结构问题,最后才动手移动任何盒子。本文以 .cursor/skills/impeccable/reference/layout.md 为骨架,结合 skill 的 SKILL.md、live.md 参数契约与仓库中的命令元数据,系统讲解 layout 参考中「访问者模式 → 双重隔离评估 → 空间论点 → 应用 → 验证」的完整工作流,以及在 Live 模式下必须声明的 density 签名参数。读完你将能独立执行一次“先诊断、后编辑、再扫描验证”的布局重构,并理解其规则在仓库源码中的落点。
一、layout 在 Impeccable 中的定位
在 skill 的命令体系里,layout [target]属于Enhance(增强)类别。命令元数据文件 .cursor/skills/impeccable/scripts/command-metadata.json 中的描述是:
Improve layout, spacing, and visual rhythm. Fixes monotonous grids, inconsistent spacing, and weak visual hierarchy.
即:改善布局、间距与视觉节奏,修复单调网格、不一致的间距和脆弱的视觉层级。当用户反馈“布局不对”“间距有问题”“视觉层级混乱”“界面拥挤”“对齐不齐”或“想要更好的构图”时,就路由到 layout 流程(对应 SKILL.md 的命令路由规则)。
layout 参考开宗明义地给出它的核心命题:
Layout turns product priority into reading order, grouping, rhythm, and usable space. Diagnose the structural problem before moving boxes.
这意味着 layout 的目标函数不是“好看”,而是忠实转译产品优先级。动手前必须先诊断结构问题,这正是后面所有小节的方法论起点。该参考文档在同一技能包内以多份拷贝存在(例如 skill/reference/layout.md、plugin/skills/impeccable/reference/layout.md),说明它是跨 harness(Cursor / Claude / 插件等)打包发布的共享参考。
二、先定访问者模式:结构是模式的一种功能
布局不是凭空设计的,它首先取决于用户在这个界面上的成功形态。layout 参考把访问者模式归并为三类并分别给出结构倾向:
| 访问者模式 | 允许的结构倾向 | 理由 |
|---|---|---|
| Persuade + Experience(说服 + 体验) | 构图可以不对称、流动、甚至刻意打破常规——前提是“选定的视觉世界值得这么做” | 此类界面(落地页、活动页、作品集)以情绪与行动为设计目标 |
| Operate + Read(操作 + 阅读) | 可预测的结构、稳定的密度、可导航的线性秩序,这些本身就是一种可用性 affordance | 此类界面(应用 UI、仪表盘、文档)以任务完成与理解为目标 |
| Native(原生) | 导航、安全区(insets)、适配与触控目标一律跟随平台规范 | 需要读取 ios.md 或 android.md 的专门指导 |
SKILL.md 中对四种模式的划分可作为更细的背景参照:Persuade是“访客决定并行动,设计即产品”;Operate是“访客完成任务”,可扫描性、一致性、原生预期压倒表达;Read是“访客理解内容”,结构服务于理解;Experience是“访客身处作品之中”,界面应退居其次。layout 参考把它们归纳为两组,因为这两组各自共享相近的结构策略。
两条边界约束必须同时满足:
- 保留既有的视觉世界。layout 命令只改变既有世界内部的结构;如果任务本质是“替换身份/整个视觉世界”,那属于 new-work.md 的职责,不应混入本次 layout 流程。
- 模式由“被请求的表面”决定,而非由产品决定。工具的落地页仍是 Persuade,时装品牌的文档仍是 Read——docs 索引是 Read 而不是 Persuade。
三、两次相互隔离的评估:先诊断,后动手
动手编辑前的第一项硬性纪律是诊断与修复分离。layout 参考要求:当 sub-agent 工具可用且被允许时,两个评估应独立并行运行;否则按顺序由你本人完成。
3.1 第一次评估:布局评估(Layout assessment)
对具有代表性的状态与视口逐一检查,且每一条都必须用渲染结果或源码证据作答,覆盖七个问题维度:
- 阅读顺序(Reading order):做“眯眼测试”(squint test)——虚化细节后,是否仍能按顺序辨认主元素、次元素与主要分组?
- 分组(Grouping):相关项是否彼此靠近、不同分组是否被明确区隔?还是说容器/卡片在替孱弱的邻近关系“打补丁”?
- 节奏(Rhythm):紧凑与宽松的间隔是否形成了刻意设计的韵律?还是同一个间距值被到处复用,直到所有东西权重相等?
- 结构(Structure):拓扑结构是否匹配内容与任务?那些重复的卡片、列、区块真的是同质的,还是仅仅因为框架默认长这样?
- 密度(Density):每个区域的信息量是否匹配使用频率、决策复杂度与访问者模式?
- 适配(Adaptation):在窄、中、宽、缩放与本地化(localized)状态下,什么会重排、折叠、换行、滚动或保持固定?DOM 顺序与焦点顺序是否仍与视觉顺序一致?
- 极端情况(Extremes):长内容、空状态、遮罩层、sticky 元素、安全区与小尺寸触控目标是否会暴露结构失效?
3.2 第二次评估:机械扫描(Mechanical scan)
布局评估保持“纯人工判断”,随后运行独立的机械扫描:
node .cursor/skills/impeccable/scripts/detect.mjs --json --scope layout [target files or dirs]这里--scope layout把检测器限定在布局相关规则上,--json便于程序化解析输出。关于该命令的加载机制有一个值得注意的实现细节:依据 SKILL.md 的说明,skill 的运行时基目录(skill base directory)会解析所有node .cursor/skills/impeccable/scripts/...形式命令的绝对路径,仓库中的.cursor/skills/impeccable/scripts/只是“运行时未报告基目录”时的回退位置;当前仓库提交的 scripts 目录 主要包含command-metadata.json与 live-browser 系列辅助脚本,完整的 detector 与 edit hook 脚本随 skill 包交付。仓库测试目录下的大量反模式 fixture 即为这类结构性扫描的目标形态,例如 cramped-padding.html、edge-flush-cards.html、first-viewport-column-overflow.html、clipped-overflow-container.html、repeated-container-text.html 与 layout.html 等,它们描述了检测器应当拦截的间距、溢出、堆叠与容器行为问题类别。
机械扫描无法裁决的“任意间距、溢出、堆叠与容器行为”仍须人工目检。两条纪律必须遵守:
- 证据隔离:不要把机械证据掺入第一次人工评估;两遍结论都完成后再综合,再进入编辑。
- 结论上限:扫描通过不等于层级或节奏正确——“a clean scan cannot prove hierarchy or rhythm”。它只能证明“没有明显机械缺陷”,证明不了设计论点成立。
四、动笔前先立“空间论点”(Set the spatial thesis)
在编辑之前,必须先能用一句话以上的精确语言回答:
- 主阅读路径 / 主任务路径是什么?
- 什么内容应该在一起、什么必须分开?
- 哪个元素引领、哪个元素支撑?
- 目标密度与间距节奏是什么?
- 结构在不同容器、视口、输入模式与内容极端下如何变化?
然后选择能表达上述关系的最简结构模型,并遵循两条实现纪律:
- 按关系选择布局原语:flex 处理一维排列、grid 处理二维网格、block/flow 处理文档流……让原语的本质与你真正控制的“关系”一致,而不是随手嵌套。
- 语义化命名:可复用的间距与容器角色使用语义化命名(间距 token 如
--space-sm/md/lg,容器角色如cluster、stack、switcher),为后续维护与跨组件复用留下依据。
五、应用原则:从邻近关系到间距刻度的十二条准则
layout 参考的 Apply 段给出了可直接落地的编辑准则,可归纳为三个层次。
分组与层级:
- 按意义分组,先邻近后容器。优先用 proximity(邻近关系)表达归属,而不是急着加容器或装饰边框。
- 让层级跟随产品优先级,而不是框架默认值。框架的默认标题/卡片结构只是起点。
- 让不同的内容保持视觉可区分,但不必把每个分组都变成孤立的组件。组件化过度同样会破坏整体节奏。
- 当同一组件出现在不同上下文时,优先做成容器感知(container-aware)的组件,依据所在容器调整自身表现。
间距与节奏:
- 用“紧—松”的刻意对比制造节奏,而不是复制同一数值直到权重平均化。
- 使用成文的间距刻度,拒绝一次性魔数。参考特别强调:以 4 为基数的刻度通常能提供 8 刻度缺失的中间档(例如 4/8/12/16 vs 8/16),小的增量往往是细腻节奏的关键。
- 当
gap比子元素 margin 更能直接表达“兄弟元素间距”时,优先用gap。这是现代 CSS 布局(flex/grid 均支持 gap)在源码层面最直接的“关系表达”手段。
极端与细节:
- 保持触控目标可用,即便可见标记很小。
- 仅在能厘清状态或层级时才使用深度(depth),阴影与层叠不是装饰性的默认值。
- 光学修正(optical correction)必须发生在目检渲染结果之后,不要靠预判下结论。
最后一条总纲性提醒写得很克制但关键:
Variation is not a goal by itself. Repetition should support recognition; break it only when content or priority changes.
即:变化本身不是目标。重复服务于“被识别”;只有在内容或优先级确实改变时才打破重复。这与「响应式行为要结构化」的要求同源——重排、折叠、回流或按需揭示,都应以“此时什么仍然重要”为准,而不是等价地把每列等宽缩放。
六、验证清单:逐条给出证据,并重跑扫描
编辑完成后,layout 参考要求逐条核验以下八项,每一项都必须有渲染或源码证据,绝不允许用一句光秃秃的“是/没问题”敷衍:
- 眯眼测试仍能按顺序揭示主、次元素与主要分组;
- 阅读与任务路径在每个支持的尺寸下依然清晰;
- 相关内容自然聚拢,无关内容不会糊成一团;
- 紧—松间距形成有意的节奏,而非单调重复;
- 密度匹配使用频率与内容复杂度;
- 长文本、空状态、本地化、缩放与动态内容不会破坏结构;
- 键盘、触摸与辅助技术的顺序与视觉顺序一致;
- 最后一次机械扫描没有无法解释的发现。
若结构与论点皆成立,则把成果交接给/impeccable polish(即进入 polish.md 描述的最终质量收尾阶段)。这里的交接顺序是有意的:layout 负责“结构性是否站得住”,polish 负责“对齐与微细节是否无瑕”,二者不在同一轮互相污染。
七、Live 模式签名参数:density 与唯一的结构分支参数
layout 参考还规定了该动作在Live 视觉变体模式(参见 live.md)下如何暴露可调参数。核心约定是:
Every variant declares a coarse
densityparameter and authors spacing againstvar(--p-density, 1).
每一个变体都必须声明一个粗粒度的density(密度)参数,并且间距书写要基于 CSS 变量var(--p-density, 1)(默认 1 即“作者既定的密度”,大于 1 更疏松、小于 1 更紧凑)。layout 参考给出的规范参数声明为:
{"id":"density","kind":"range","min":0.6,"max":1.4,"step":0.05,"default":1,"label":"Density"}对照 live.md 的参数契约可以精确解释该 JSON 各字段的语义与底层机制:
- kind 为
range:UI 层渲染为滑块(slider),驱动--p-<id>这个 CSS 自定义属性,作者只需在自己的 CSS 中写var(--p-density, 1)即可整体放大/收紧间距。live.md 中还给出同模式的另两种 kind——steps(分段单选,驱动data-p-<id>属性,写作:scope[data-p-density="airy"] .grid { … })与toggle(同时驱动--p-<id>: 0|1与属性存在性)。 - min/max/step/default:密度范围 0.6–1.4(约为作者基准的 60%–140%),以 0.05 为步进、默认 1.0,label 为 “Density”。粗粒度的目的正是让用户能自然说出“再紧一点 / 再松一点”这种连续语气,而不是追求精确微调。
- 该参数属于coarse knob(粗调旋钮)哲学:浏览器侧的旋钮以零再生成成本驱动 CSS 变量;微边距与一次性微调不应成为参数。
第二条规定同样明确:
Add one structural parameter only when the topology genuinely branches.
只有当拓扑结构真正发生分支(例如窄屏单列 ↔ 宽屏多栏这类结构性分岔)时,才允许额外增加一个结构参数;并且该参数必须遵守 live.md 的参数契约。这条规则与 live.md 对“硬上限:每个变体四个参数”“参数是设计的一部分,规划期就应决定可调旋钮”的总体预算约束一致;当以layout为命名的 Live 子动作运行时,会先加载本参考文档再进入规划,其 MUST 参数(即这里的density)叠加在 live.md 的通用预算之上。
从实现角度看,这一机制的落地分布在 live-browser 辅助脚本与浏览器注入层。例如 live-browser-dom.js 负责将变体与参数旋钮渲染进页面,而.cursor/skills/impeccable/scripts中的 live-browser 系列脚本共同支撑“浏览器中选择元素 → 生成变体 → 拖动 density → 接受后碳化(carbonize)写入真实样式”的完整链路。接受的变体会把选中的 range 值作为字面量替换进 CSS,或更新该 CSS 变量的默认值,实现“变体预览中的密度选择最终固化到代码”。
八、与相邻参考的协作边界
理解 layout 参考后,还需要知道它在技能参考体系中的邻接关系,以免职责越界:
- 身份与世界的建立/替换→ new-work.md。layout 只动“既定世界内部的结构”。
- 字号、行高、字体层级→ typeset.md。间距与字距紧密相关但分工不同:layout 管结构空气,typeset 管文字本身。
- 平台导航、安全区与触控规范→ ios.md 与 android.md。
- 最终质量收尾→ polish.md。结构成立后才进入 polish。
- Live 变体模式的总体参数契约与变体交付纪律→ live.md。
一句话收束全篇:layout 不是“把东西排整齐”,而是先在七个维度上用证据诊断、先写出空间论点、再按语义分组与成文刻度应用、最后逐条验证并重跑机械扫描的过程;在 Live 模式下,则通过粗粒度density(0.6–1.4、步进 0.05、默认 1,书写为var(--p-density, 1))这一个签名参数让密度成为可实时体验、可接受落地的设计决策。把握住「诊断先于移动、证据先于断言、节奏先于网格」这三条主线,你就能把一次“看起来不对劲”的界面,改造成结构上有论据、验证上有依据的设计。
【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccable
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考