间距与层级
间距用一个 0.25rem 基准的九档刻度,容器只有一条 72rem 的线,层级用 1px 描边而不是投影, z-index 只有四档。所有值都写成 rem,因为它们要跟着根字号一起缩放。
间距刻度
刻度以 0.25rem 为基准(Tailwind 默认 --spacing,未覆盖)。下面的条带就是每档的实际宽度。
| 档位 | 值 | 用途 |
|---|---|---|
1 | 0.25rem | 图标与文字之间、极紧凑堆叠 |
2 | 0.5rem | 行内元素间距、按钮内 gap |
3 | 0.75rem | 表单标签到控件、示例行间距、表格行内距 |
4 | 1rem | 卡片内距、区块内段落间距、舞台内距 |
6 | 1.5rem | 两栏间隙、示例舞台大内距 |
8 | 2rem | 卡片网格间距、段落群之间 |
12 | 3rem | 区块分隔前的留白、主栅格列间距 |
16 | 4rem | 页面级分块 |
24 | 6rem | 首屏 section 的桌面垂直节奏 |
组件内距
| 组件 | 内距 | 备注 |
|---|---|---|
| 卡片 | 1rem | 四面相同;紧凑卡片可降到 0.75rem |
| 按钮 | 10 / 12 / 16 / 20px | 对应 xs / sm / md / lg 的横向内距,高度 32 / 36 / 40 / 44px |
| 图标按钮 | 0 | 正方形,内距归零 |
| 表单控件 | 0.625rem 0.75rem | 纵向 10px、横向 12px |
| 表格单元格 | 0.5rem 0.75rem 0.5rem 0 | 左侧不留白,靠列对齐 |
容器
| 对象 | 值 | 说明 |
|---|---|---|
| 页面内容最大宽 | 72rem | 顶栏、内容列、页脚共用同一条线 |
| 横向内距 | 1rem | 40rem 起升到 1.5rem |
| 正文最大宽 | var(--zz-measure) · 48rem | 长文与 lede 用,比容器窄 |
| 顶栏高度 | var(--zz-nav-h) | calc(3.5rem + env(safe-area-inset-top, 0px)),锚点偏移也引用它 |
| 文档侧栏 | 15rem | 64rem 起出现,与内容列间距 3rem |
横向内距只写两档,不要为某个断点临时插 1.25rem;72rem 之外也不加第二层容器宽度。 内容超过 var(--zz-measure) 时靠增列解决,不靠加宽正文。
垂直节奏
区块之间的留白只有这四档,上下不对称是刻意的:底部留得多,滚动到底时不会觉得被截断。
| 场合 | 垂直内距 | 备注 |
|---|---|---|
| 内页内容列 | 2.5rem | 桌面 3rem;底部收尾 4rem / 桌面 5rem |
| 首页 section | 3rem | 桌面放大到 6rem–7rem |
| 页脚 | 3.5rem | 垂直内距,左右与内容列对齐 |
| 区块分隔 | 3rem + 1px | 上外边距 3rem、1px 上边框、再 1.5rem 内距 |
区块分隔统一是「margin-top: 3rem + border-top: 1px solid var(--zz-border-subtle) +padding-top: 1.5rem」,本页每个 section 就是这个组合。不要用背景色划分区块——颜色变化留给悬停面。
边框与层级
"浮起"靠的是零模糊的外描边,不是投影:深色主题下 --zz-elevation 是0 0 0 1px oklch(1 0 0 / 0.07),hover 时同一几何只把透明度升到 0.13,所以不会跳动。 亮色主题下描边不足以表达层级,才额外叠一层极轻的真实投影。这两个值都装在 token 里, 组件只写 box-shadow: var(--zz-elevation),不判断主题。
静态面板
可交互面板
外描边画在盒子外侧,父级 overflow: hidden 会把它裁掉;这类卡片要么不裁,要么把描边换成border-strong 的实边框。深色主题下面板底仍用 --zz-surface,不要为了"浮起"再加边框。
描边宽度规范
| 用途 | 宽度 | 颜色 |
|---|---|---|
| 发丝分隔 | 1px solid | --zz-border-subtle |
| 控件描边 | 1px solid | --zz-border-strong |
| 强调容器 | 2px solid | --zz-border-strong |
| 引用 / 提示块左线 | 2px solid | --zz-brand 或状态色 |
1px 发丝线:分隔内容
2px 左线:引用与提示
z-index 阶梯
只有四档,全部通过 var(--zz-z-*) 消费。任何裸数值都会被一致性检查 (scripts/check-tokens.mjs)拦下。
| 层 | token | 值 | 使用者 |
|---|---|---|---|
| nav | --zz-z-nav | 100 | 顶栏、吸顶导航 |
| dropdown | --zz-z-dropdown | 200 | 下拉、提示卡、选择器 |
| modal | --zz-z-modal | 300 | 模态、搜索面板、遮罩层 |
| tooltip | --zz-z-tooltip | 400 | tooltip 及所有浮在最上的提示 |
.zz-topbar { z-index: var(--zz-z-nav); }
.zz-dropdown{ z-index: var(--zz-z-dropdown); }
.zz-modal { z-index: var(--zz-z-modal); }
.zz-tooltip { z-index: var(--zz-z-tooltip); }层内比较(例如按钮组里被 hover 的那一个)允许 1 / -1, 因为那只在同一个层内决定谁盖住谁;一旦要跨层,就必须往上取一档。
圆角
全部直角。8 个 Tailwind 圆角档位 --radius-xs 到 --radius-4xl 都被写成0px,所以 rounded-* 工具类不会产生任何弧度,也不需要逐个元素去写border-radius: 0。
所有容器、按钮、输入框:直角(无 border-radius)
唯一例外:圆形头像 border-radius: 50%
直角意味着层级必须由描边与底色承担,不能靠圆角和投影堆叠"卡片感";一个页面里同时出现的描边种类不超过两种。 头像用 .zz-avatar,是这条规则唯一的例外(徽章上的状态点用 50% 表达"圆", 因为方点传达不了状态)。