← 目录 02 / 11

构成主义设计系统规格 v0.1

这是一份可直接翻译成 CSS 变量的规格书。所有色值都经过 WCAG 对比度实测,所有字体都经过西里尔覆盖核实——不是凭感觉挑的。 实测方法与版本见文末"数据来源与验证状态"。


1. 色彩系统

1.1 设计前提

构成主义海报是双色油墨印在廉价纸上:纸本身是米黄偏灰的(不是纯白),墨只有黑和红。所以色板要以"纸"为基准,而不是以"白"为基准。

面积配比是硬约束(这是最容易做错的地方):

颜色 面积占比 角色
纸(米黄) 60–75% 基底,呼吸,可读性保障
墨黑 20–30% 结构、正文、分隔、压重
朱红 5–15% 引爆点。只出现在最关键的一两处
蓝 / 黄(至上主义点缀) 0–3% 可选。用于单调处破局,不可参与主结构

1.2 色板令牌(含实测对比度)

:root {
  /* ---- 纸 ---- */
  --kv-paper:      #EFE9DC;  /* 主纸色:廉价胶版纸 */
  --kv-paper-dim:  #E3DBC9;  /* 纸的暗面:分层、凹陷、次级区块 */
  --kv-paper-lift: #F7F3EA;  /* 纸的亮面:极少量用于提升 */

  /* ---- 墨 ---- */
  --kv-ink:        #12100E;  /* 油墨黑(不用纯黑 #000,纯黑太屏幕感) */
  --kv-ink-soft:   #3A352E;  /* 次级文字 */
  --kv-rule:       #12100E;  /* 分隔线用纯墨,1–6px 粗线 */

  /* ---- 朱红(两个变体,用途不同!见下表) ---- */
  --kv-red:        #D6281F;  /* 印刷朱红 —— 图形/大面积/大字号 */
  --kv-red-ink:    #B31B12;  /* 深红 —— 小字号文字专用(通过 AA) */
  --kv-red-deep:   #8E1B14;  /* 圧印/阴影/套印底层 */

  /* ---- 至上主义点缀(慎用) ---- */
  --kv-blue:       #16407A;
  --kv-yellow:     #E8B31A;

  /* ---- 半调/网点灰 ---- */
  --kv-gray:       #8A8377;
}

1.3 实测对比度与使用授权(这是本节最重要的表)

用 WCAG 2.x 相对亮度公式精算(脚本见 04-技术实现手册.md):

前景 背景 对比度 结论
--kv-ink 墨黑 --kv-paper 纸 15.69 : 1 ✅ AA 正文可用
--kv-paper 纸 --kv-ink 墨底 15.69 : 1 ✅ AA 正文可用
--kv-yellow 黄 --kv-ink 墨底 9.85 : 1 ✅ AA 正文可用
--kv-blue 蓝 --kv-paper 纸 8.47 : 1 ✅ AA 正文可用
--kv-red-ink 深红 --kv-paper 纸 5.63 : 1 ✅ AA 正文可用
--kv-paper 纸 --kv-red-ink 深红底 5.63 : 1 ✅ AA 正文可用
--kv-red 朱红 --kv-paper 纸 4.15 : 1 ⚠️ 仅 ≥24px 或 ≥18.66px 粗体
--kv-paper 纸 --kv-red 朱红底 4.15 : 1 ⚠️ 仅 ≥24px 或 ≥18.66px 粗体
--kv-red 朱红 --kv-ink 墨底 3.78 : 1 ⚠️ 仅大字
--kv-gray 灰 --kv-paper 纸 3.10 : 1 ⚠️ 仅大字 / 装饰性
--kv-red-deep 暗红 --kv-ink 墨底 2.79 : 1 ❌ 任何字号都不合格,禁止使用

由此得出的硬规则:

  1. 需要正文字号的红字 → 必须用 --kv-red-ink(#B31B12),不能用 --kv-red。
  2. 朱红 --kv-red 只用于:大面积色块、几何图形、≥24px 的标题。
  3. 灰 --kv-gray 只能做装饰性网点/网纹,不能承载文字。
  4. --kv-red-deep 禁止出现在墨底上(这条是精算才发现的坑)。
  5. 不要用 opacity 制造"浅色文字"——那会绕过上面的全部结论。需要浅色就加色板令牌。
  6. 🔴 绝对不要用纯红 #FF0000 做白底正文:它在白底只有 4.00 : 1,连 AA 正常字号都不过。这是最常见的"看起来够红"的错误用色。

替代方案:如果你希望"红色只有一枚、且正文字号也能用",可以用印刷油墨红 #C8102E(在白底上 5.88 : 1,过 AA 正文)。它的饱和度比朱红略低,但一次解决所有字号问题:

/* 单红方案(牺牲一点"朱红感",换来全字号合规) */
--kv-red:     #C8102E;   /* 5.88:1 on #fff,图形与大字 */
--kv-red-ink: #C8102E;   /* 同一枚,正文也能用 */

另一种更沉的印刷红:#AD2A07(白底 6.75 : 1,是白底上最优的红)。代价是偏砖红,离"苏联海报朱红"远了一点。

1.4 深色模式(可选)

构成主义没有"深色模式"这个概念。如果必须做,应该理解成"反相印刷":墨色当纸、纸色当墨,红色保持不变(但红底白字同样受 4.15:1 限制)。


2. 字体系统

2.1 选字原则

构成主义的字体气质:窄、重、几何、全大写、工业怪诞体(grotesque)。当年用的是木活字和手工铅字,特征是字面窄、笔画均匀、无衬线、字距可压到极紧。

2.2 西里尔(Cyrillic)覆盖核实结果 ⚠️

这是本次调研最有价值的发现之一。 很多设计稿惯用的"海报字体"其实不支持西里尔字母,如果页面要出现俄文(构成主义主题下很常见)会直接掉字体。

数据来源:Google Fonts 官方元数据 fonts.google.com/metadata/fonts(共 1950 个字族)。

✅ 支持西里尔(可放心用):

字体 类别 字重轴 气质 建议角色
Oswald Sans 200–700 窄体工业怪诞体,最贴近构成主义铅字 主力标题(全大写)
Unbounded Sans 200–900 可变 几何、方正、当代感、有先锋气 Hero 超大标题(次选主力)
Russo One Sans 400 极粗、方正、机械 单字重标题、Logo
Rubik Mono One Sans 400 等宽超粗,块状 数据/编号/印章式文字
Jost Sans 100–900 + 斜体 几何无衬线,Futura 的免费近亲(Futura 正是构成主义时期的产物) 副标题、几何感正文
Play Sans 400/700 方正、略窄 次级标题
PT Sans / PT Serif / PT Mono Sans/Serif/Mono 各 400/700 俄罗斯本土设计(ParaType),与主题同源 正文、注释
Roboto Condensed Sans 100–900 + 斜体 窄体、中性偏工业 大段窄栏正文
Alumni Sans Sans 100–900 + 斜体 极窄、高瘦 超大单行标题、竖排
Manrope / Onest / Golos Text / Commissioner Sans 200–900 可变 当代几何,可选正文 正文(需要现代感时)
Noto Sans / Noto Serif / Source Serif 4 Sans/Serif 可变 覆盖面最广,兜底 兜底与长文
Yeseva One / Prata / Podkova / Oranienbaum Display/Serif — 俄式装饰衬线 反差点缀(非主用)
Ruslan Display / Prosto One / Kelly Slab / Iceberg / Marmelad Display — 俄式装饰/粗黑 极少量点缀

❌ 不支持西里尔(页面出现俄文会掉字体):

Anton、Bebas Neue、Archivo、Archivo Black、Barlow、Barlow Condensed、Bricolage Grotesque、Chivo、Space Grotesk、Syne、Teko、Saira Condensed、Fjalla One(无基础西里尔)

其中 Anton / Bebas Neue / Archivo Black / Barlow Condensed 是最容易被设计师顺手拿去做"海报标题"的四个——如果确定不需要俄文可以用,但只要有一处俄文就会露馅。

2.3 中文选字(已核实许可证)

字体 仓库 Star 许可证 用途
得意黑 Smiley Sans atelier-anchor/smiley-sans 14,905 OFL-1.1 ⭐ 中文标题首选——窄体+斜体骨架,气质与构成主义高度契合,是中文里少见的"海报字"
霞鹜文楷 LXGW WenKai lxgw/LxgwWenKai 26,243 OFL-1.1 正文/引文(楷体,气质偏温,做对比用)
思源黑体 Source Han Sans adobe-fonts/source-han-sans 17,331 OFL-1.1(仓库标注 NOASSERTION,实为 OFL) 中文正文兜底,多字重
Noto CJK notofonts/noto-cjk 4,093 OFL-1.1 兜底

2.4 推荐字体栈(三套,按场景选)

/* A 套:默认(中英混排,最稳) */
--kv-font-display: "Oswald", "得意黑 Smiley Sans", "Noto Sans SC", sans-serif;
--kv-font-body:    "PT Sans", "Noto Sans SC", "Source Han Sans SC", sans-serif;
--kv-font-mono:    "JetBrains Mono", "PT Mono", ui-monospace, monospace;

/* B 套:更当代、更"先锋派"(几何感更强) */
--kv-font-display: "Unbounded", "得意黑 Smiley Sans", sans-serif;
--kv-font-body:    "Jost", "Noto Sans SC", sans-serif;
--kv-font-mono:    "IBM Plex Mono", "PT Mono", monospace;

/* C 套:更贴近"俄罗斯印刷所"(同源感强) */
--kv-font-display: "Russo One", "Oswald", "得意黑 Smiley Sans", sans-serif;
--kv-font-body:    "PT Serif", "Noto Serif SC", serif;
--kv-font-mono:    "PT Mono", monospace;

中文必须放在西文之后,且中文标题要用 font-weight 与西文的视觉重量对齐(Oswald 700 ≈ 思源黑体 Heavy ≈ 得意黑只有一个字重但字面重)。

2.5 字号与排版参数

核心是极端对比。 标题:正文 ≥ 6:1(瑞士风格约 2.5–3:1)。

:root {
  /* 阶梯(fluid,基于 clamp) */
  --kv-size-mega:  clamp(4rem, 15vw, 16rem);   /* Hero 单字/单词,占满屏宽 */
  --kv-size-h1:    clamp(2.75rem, 8vw, 7rem);  /* 章节主标题 */
  --kv-size-h2:    clamp(1.75rem, 3.6vw, 3rem);
  --kv-size-h3:    clamp(1.25rem, 2vw, 1.75rem);
  --kv-size-body:  clamp(1rem, 1.05vw, 1.125rem);   /* 16–18px 起 */
  --kv-size-label: 0.75rem;    /* 标签/编号,全大写+宽字距 */
  --kv-size-quote: clamp(1.5rem, 3vw, 2.5rem);

  /* 字距:大标题收紧,小标签放开 —— 这是构成主义的"呼吸" */
  --kv-track-mega:  -0.04em;
  --kv-track-h:     -0.02em;
  --kv-track-body:   0;
  --kv-track-label:  0.18em;   /* 小字必须放开,否则挤成一团 */

  /* 行高:标题极紧,正文正常 */
  --kv-leading-mega: 0.82;
  --kv-leading-h:    0.95;
  --kv-leading-body: 1.55;

  /* 字重 */
  --kv-weight-display: 700;
  --kv-weight-body:    400;
  --kv-weight-label:   600;
}

排版硬规则: 1. 标题一律全大写(text-transform: uppercase)——西文。中文不做强制大写,改用字重+字距。 2. 标题永远 text-wrap: balance,正文 text-wrap: pretty。 3. 斜排只允许短标签/短标题(≤ 3 个词),正文永远水平。原因见无障碍一节。 4. 数字用 font-variant-numeric: tabular-nums,编号列要对齐。


3. 网格与间距

3.1 网格

12 栏 + 可见轴线,但允许被冲破。

:root {
  --kv-cols: 12;
  --kv-gutter: 1.5rem;     /* 栏间距 */
  --kv-margin: clamp(1rem, 4vw, 4rem);  /* 页边距 */
  --kv-hairline: 1px;      /* 细线/网格线 */
  --kv-rule: 6px;          /* 粗分隔线(构成主义特征) */
  --kv-axis-angle: -15deg; /* 主斜轴角度,全站统一 */
}

用法规则: - 内容区默认占 1–7 栏(不对称),不要居中。居中=瑞士风格。 - 每页/每屏至少有一处跨满 12 栏的元素(贯穿式色块或斜轴)。 - 网格线可以显示出来(用 repeating-linear-gradient 做底纹,透明度 6–10%)。 - 全局 --kv-axis-angle 是"主梁"角度,全站统一一个角度,不要每块换角度——否则会散。

3.2 间距阶梯

8pt 基准,但构成主义偏爱突兀的大间距 + 紧密的小间距并存(对比原则在空间上同样成立)。

:root {
  --kv-space-1: 0.25rem;   /* 4  */
  --kv-space-2: 0.5rem;    /* 8  */
  --kv-space-3: 1rem;      /* 16 */
  --kv-space-4: 1.5rem;    /* 24 */
  --kv-space-5: 2.5rem;    /* 40 */
  --kv-space-6: 4rem;      /* 64 */
  --kv-space-7: 7rem;      /* 112 */
  --kv-space-8: 12rem;     /* 192 — 用于制造"空"的冲击 */
}

4. 形状、边线与阴影

:root {
  --kv-radius: 0;          /* 全局零圆角,不可协商 */
  --kv-border: 2px solid var(--kv-ink);
  --kv-border-thick: 6px solid var(--kv-ink);

  /* 只有两种"阴影",都不是柔和投影 */
  --kv-shadow-hard: 8px 8px 0 var(--kv-ink);      /* 硬边偏移(拟印刷/拟立体) */
  --kv-shadow-red:  8px 8px 0 var(--kv-red);      /* 红色硬边,克制使用 */
}

禁止清单:border-radius、box-shadow 模糊值(blur > 0)、linear-gradient 装饰性渐变、backdrop-filter 毛玻璃。

允许的例外:drop-shadow() 用于 SVG 几何形(保持硬边),mix-blend-mode 用于叠印。


5. 质感系统("印刷感"三件套)

必须极轻。目标是"这是印出来的",不是"这是做旧滤镜"。

效果 手段 强度上限
纸张纤维颗粒 SVG feTurbulence 内联 data-URI 背景 opacity: 0.04–0.08
半调网点 SVG pattern / radial-gradient 重复 / mask 网点尺寸 3–6px,只在图片上
套印错位 伪元素复制文字,偏移 1–3px,mix-blend-mode: multiply 偏移 ≤ 3px

阈值判断:把页面缩到 50% 看——如果颗粒/网点依然明显,就是太重了;正确的强度是缩小时几乎看不见、原尺寸下能感觉到"不干净"。


6. 动效系统

:root {
  --kv-ease-mech: cubic-bezier(0.85, 0, 0.15, 1);  /* 机械、果断 */
  --kv-dur-fast: 120ms;
  --kv-dur-base: 200ms;
  --kv-dur-slow: 320ms;
}

动效语汇(只允许这几种):

动作 说明
硬切入场 元素从侧向/斜向平移进入,无淡入,或淡入极快
裁切框扫过 clip-path 从 0 到 100% 揭示图片
逐行跳出 标题按行 stagger 出现,每行延迟 40–60ms
色块翻转 背景色在 hover 时硬切(无过渡或极短过渡)
编号跳变 数字直接替换,不做滚动计数

禁止:弹性/回弹缓动、视差滚动叠加多层、超过 400ms 的动画、任何 ease-in-out 默认缓动。

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

7. 无障碍红线(这套风格的固有风险)

风险 具体问题 对策
斜排文字 旋转后的文字对屏幕阅读器无影响(DOM 顺序不变),但视觉阅读效率大幅下降,且长文本旋转后行宽变化导致难读 斜排只用于 ≤3 词短标签;正文永远水平
红字对比度 朱红在纸上仅 4.15:1,小字不合格 小字红用 --kv-red-ink
极端字号 clamp(..., 15vw, ...) 在窄屏可能溢出 必须配 overflow-wrap: anywhere + 容器 overflow: clip
全大写 屏幕阅读器对全大写词的朗读可能逐字母拼读 用 text-transform: uppercase(视觉大写,DOM 保持正常大小写),不要在 HTML 里直接写全大写
质感叠加 颗粒/网点降低文字清晰度 质感层加 pointer-events: none 且不得覆盖正文区域
动效 硬切+闪动可能触发前庭不适 遵守 prefers-reduced-motion
零圆角按钮 触控目标易过小 触控目标 ≥ 44×44px

8. 现行规则来源:StyleKit「构成主义 Constructivism」

状态:由用户提供并声明已实际抓取确认(本环境搜索接口当时限流,未由我二次核验原文,故记为「用户实测来源」而非「我实测来源」)。

本位规则优先于本文档前面章节中的自拟取值。下表是 StyleKit 规则与它的落地结果:

StyleKit 规则 取值 落地位置 精算结论
苏维埃红 #cc0000 --red on 纸 4.84:1 —— 过 AA 正文线,比自拟的 #D6281F(4.15,仅大字)更合规
纯黑 #1a1a1a --ink on 纸 14.32:1
泛黄纸 #f2e8d5 --paper 基准底色
金星 #d4a843 --gold ⚠️ on 纸仅 1.82:1 → 只能做图形;on 黑 7.86:1 可做文字
棕 #8b4513 --brown on 纸 5.84:1 ✅;⚠️ on 黑 2.45:1 禁用
rounded-none 硬直角 全局 border-radius: 0 —
shadow-[4px_4px_0] 版画硬阴影 --shadow-hard: 4px 4px 0 0 var(--ink) 模糊值恒为 0
对角倾斜 -rotate-6 / skew-x-3 -6deg / 3deg --tilt / --skew 全站统一一个角度
font-black uppercase 900 + 全大写 巨型标题改用 Unbounded 900 Oswald 最重只有 700,没有真 900
Mechanical Easing 只准 linear + 75ms/100ms,禁 ease-in-out --ease-mech: linear,--dur-fast: 75ms,其余 100ms 微交互全部合规;页面转场为有意例外(见下)
Block Invasion 黑块从左横扫 曾实装为 .wipe 的 translateX 100ms linear ⚠️ 已按要求回退,见下

StyleKit 动效语汇的落地状态:

语汇 本项目实现 状态
Diagonal Aggression 报纸板块与文章侧栏卡片:translate(-4px,-4px) skewX(-3deg) + 硬阴影同步拉开 ✅ 采用
Soviet Reversal 板块 :active 变墨底纸字;文章条 :active 翻成纸底黑字 ✅ 采用
Mechanical Easing 微交互 linear + 75/100ms ✅ 采用
Block Invasion 曾实装为黑块从左横扫(translateX,100ms linear) ⚠️ 已回退——用户认为此前的「红色幕布下坠」更有力量,故改回

有意偏离记录(用户决定):页面转场用 红色幕布下坠 —— 满屏 --red 的 clip-path 自上而下压满 → 换视图 → 再向下收拢退场, 280ms + cubic-bezier(.85, 0, .15, 1)。 这偏离了 StyleKit「只准 linear + 75/100ms」的规则,影响范围仅 .wipe 一处, 其余所有过渡仍严格走 Mechanical Easing。 缓动值不是 ease-in-out(规则明令禁止的那个),而是一条前快后慢的机械曲线。 2026-10-13 实测:真实动画路径端到端 6/6 通过,幕布退场后正确归位为 polygon(0px 0%, 100% 0%, 100% 0%, 0px 0%)(零面积,不会卡在屏幕上)。

从这套色板精算出来的三条硬约束(写进 CSS 注释,防止后来者踩): 1. 苏维埃红 on 纯黑 = 2.96:1 → 禁止在黑底上用红字 2. 金星 on 纸 = 1.82:1 → 金星只能做图形或黑底文字 3. 棕 on 纯黑 = 2.45:1 → 禁止

已知未采用的规则:StyleKit 可导出 Figma tokens / Tailwind preset / SKILL.md;本项目是手写 CSS(无 Tailwind),未使用其导出产物。另有一个「动力学构成主义」变体,本页未使用。


9. 数据来源与验证状态

数据 来源 验证方式
字体西里尔覆盖 Google Fonts 官方元数据 https://fonts.google.com/metadata/fonts(1950 个字族) 程序化查询 subsets 字段,逐字族判定
字体字重轴 同上 程序化读取 fonts 对象的字重键
色值对比度 WCAG 2.x 相对亮度公式 PowerShell 脚本精算(脚本见 04-技术实现手册.md 附录),非目测
中文/开源字体许可证 GitHub REST API api.github.com/repos/{owner}/{repo} 读取 license.spdx_id 与 stargazers_count 实际返回
构成主义史料 Tate、TheArtStory、MoMA、V&A 直接抓取页面原文

⚠️ 未验证项:本环境 web_fetch 无法访问 Wikimedia Commons / MoMA / V&A 的图片下载页(403 或不可达),因此公有领域图像素材的具体下载链接未经我直接验证,见 03-资源清单.md 中的明确标注。