跳转至

60 · codex.css 复用策略

📌 本文目标:定义视觉法典 xistudio-codex.css(1212 行)在 Vue 3 项目中的严格复用规则——什么能做、什么不能做、类名如何匹配、主题如何切换。


1. 核心原则(不可妥协)

原则 1 · 字节级 1:1 复用

  • ✅ 把 docs/02-products/P1-xistudio/layout-demo/xistudio-codex.css 逐字节复制src/styles/xistudio-codex.css
  • ❌ 不修改、不格式化、不优化、不拆分
  • ✅ Vue 项目与 demo 之间用 diff 命令验证字节兼容(diff src/styles/xistudio-codex.css ../layout-demo/xistudio-codex.css 必须为空)

原则 2 · 全局 import(不拆 SCSS module)

// src/main.ts
import './styles/xistudio-codex.css'
  • ❌ 不要拆为 _variables.scss / _drawer.scss / _topbar.scss
  • ❌ 不要包装为 CSS-in-JS(styled-components / emotion
  • ❌ 不要用 PostCSS 插件转换变量

原则 3 · 类名严格匹配

codex.css 使用了大量特定类名,组件必须严格匹配,否则样式失效:

codex.css 类 含义 用法
.ide IDE 根容器 XiStudioShell 根 div
.ide.locked 锁定模式开关 :class="{ locked: layout.locked }"
.topbar 顶栏(3 行) <div class="topbar">
.menubar ① 28px 第一行 MenuBar 根 div
.stagebar ② 44px 第二行 StageBar 根 div
.subtabs ③ 32px 第三行 SubTabs 根 div
.actL / .actR ④/⑥ 左右 Activity Bar ActivityBarLeft/Right 根 div
.body 中央 Stage 区 XiStudioShell 中央 div
.bottom ⑦ Bottom 220px BottomPanel 根 div
.status ⑧ StatusBar 24px StatusBar 根 div
.drawer Drawer 浮层 DrawerLeft/Right 根 div
.drawer.show Drawer 可见 :class="{ show: layout.drawerLeft.visible }"
.dock-icon Activity Bar 图标 38×38 DockIcon 根 div(不能用 .activity-icon
.dock-icon.active 激活态 :class="{ active: ... }"
.view-pane Drawer Tab Pane 默认 display:none
.view-pane.active 激活的 Pane 必须用 .active 类切换(不能 display:block
.bottom-pane Bottom Tab Pane 默认 display:none
.bottom-pane.active 激活的 Bottom Pane 同上
.tuning-dialog 跨 Stage 浮窗 TuningDialog 根 div
.stage-frame Stage iframe 样式 StageFrame 内 <iframe>

原则 4 · 主题切换通过 data-theme

<div class="ide" data-theme="default">

codex.css 用 [data-theme="xxx"] 选择器切换 CSS 变量。Vue 端只需 :data-theme="theme.current"


2. CSS 变量速查(颜色法典)

/* codex.css §2 颜色变量(默认主题)*/
:root,
[data-theme="default"] {
  --accent: #b87333;            /* 玫瑰金 */
  --xi-light: #f5e6d3;          /* 曦光 */
  --ok: #4caf50;
  --warn: #ff9800;
  --err: #f44336;
  --L1: #fafafa;
  --L2: #f0f0f0;
  --L3: #d8d8d8;
  --L4: #909090;
  --L5: #303030;
  --line-soft: rgba(0, 0, 0, 0.08);
  /* ... */
}

[data-theme="night-deep"] { ... }
[data-theme="paper-warm"] { ... }
/* ... 其他 4 主题 */

Vue 组件中使用变量

<style scoped>
.my-custom-element {
  color: var(--accent);          /* ✅ 使用法典变量 */
  border: 1px solid var(--line-soft);
}
</style>

⚠️ 不要在 Vue 组件中重新定义 --accent 等变量。所有变量都在 codex.css 集中管理。


3. grid-template-areas 还原

3.1 demo 实现(codex.css §4)

.ide {
  display: grid;
  grid-template-columns: 240px 1fr 320px;
  grid-template-rows: auto 1fr auto auto;
  grid-template-areas:
    "topbar topbar topbar"
    "actL   body   actR"
    "bottom bottom bottom"
    "status status status";
  height: 100vh;
}
.ide.locked .body {
  /* 锁定模式下挤压 body */
}

3.2 Vue 组件中应用

<template>
  <div class="ide" :class="{ locked: layout.locked }">
    <div class="topbar"><!-- grid-area: topbar --></div>
    <div class="actL"><!-- grid-area: actL --></div>
    <div class="body"><!-- grid-area: body --></div>
    <div class="actR"><!-- grid-area: actR --></div>
    <div class="bottom"><!-- grid-area: bottom --></div>
    <div class="status"><!-- grid-area: status --></div>
  </div>
</template>

3.3 动态 ratio(覆写 grid-template-columns)

<template>
  <div
    class="ide"
    :class="{ locked: layout.locked }"
    :style="{
      gridTemplateColumns: layout.gridColumns,
      gridTemplateRows: layout.gridRows,
    }"
  >
    ...
  </div>
</template>

layout.gridColumns 由 useLayoutStore getter 计算(参见 50-state-management.md §2.1)。


4. 反模式清单(智能体务必避开)

❌ 反模式 1 · 改 codex.css

/* ❌ 不要做 */
.dock-icon {
  width: 40px;  /* 改了! */
}

正确做法:codex.css 一字不改。如需调整尺寸,要么提 ADR 改法典,要么放弃。

❌ 反模式 2 · 用 SCSS module 替代

<!-- ❌ 不要做 -->
<style module lang="scss">
  @import './styles/dock-icon.module.scss';
  .dock-icon { ... }
</style>

正确做法:全局 import codex.css,组件 <style scoped> 仅做局部布局微调。

❌ 反模式 3 · 类名拼写错误

<!-- ❌ 这些都失效 -->
<div class="activity-icon">     <!-- 应为 .dock-icon -->
<div class="drawerLeft">         <!-- 应为 .drawer + id -->
<div class="status-bar">         <!-- 应为 .status -->

❌ 反模式 4 · 直接 display 切换

<!-- ❌ 不要做 -->
<div class="view-pane" :style="{ display: visible ? 'block' : 'none' }">

正确做法(codex.css §7 设计):

<div class="view-pane" :class="{ active: visible }">

❌ 反模式 5 · z-index 乱写

codex.css 内部已规划了 z-index 层级:

z-index 内容
基础 1 .ide
Drawer 浮层 100 .drawer
Toast 1000 .toast
TuningDialog 2000 .tuning-dialog
Modal 3000 (预留)
<!-- ❌ 不要做 -->
<style scoped>
  .my-popup { z-index: 99999; }
</style>

正确做法:用 codex.css 已定义的 z-index 等级,或新增层时与法典对齐 + ADR。

❌ 反模式 6 · Tailwind 与 codex.css 混用

如果项目引入了 Tailwind:

<!-- ❌ 不要做 -->
<div class="dock-icon p-4 bg-blue-500">  <!-- Tailwind 与法典冲突 -->

正确做法:要么不用 Tailwind,要么 Tailwind 只用于法典未覆盖的微小补丁(如 mt-2 flex-grow),不与 .dock-icon 等法典类冲突。


5. 自定义样式的边界

5.1 何时可用 <style scoped>

✅ 法典未覆盖的局部布局微调(如组件内特定 padding、grid 子布局) ✅ 临时调试样式 ✅ 业务卡片的具体长宽(不是颜色/字体)

5.2 何时必须扩展 codex.css(提 ADR)

⚠️ 新增颜色变量 ⚠️ 新增 z-index 层 ⚠️ 新增主题 ⚠️ 修改 grid-template-areas ⚠️ 新增全局类(如 .tuning-dialog 之类的复杂浮窗外壳)

5.3 ADR 流程

参见 40-postmessage-protocol.md §6,扩展 codex.css 的 ADR 路径在 docs/02-products/P1-xistudio/adr/


6. 字节兼容验证脚本

# scripts/verify-codex-css.sh
SRC=docs/02-products/P1-xistudio/layout-demo/xistudio-codex.css
DST=src-vue/src/styles/xistudio-codex.css

if diff -q "$SRC" "$DST" > /dev/null; then
  echo "✅ codex.css byte-compatible with demo"
  exit 0
else
  echo "❌ codex.css DIFFERS from demo - byte compatibility broken"
  diff "$SRC" "$DST"
  exit 1
fi

建议在 CI(GitHub Actions / GitLab CI)中加这一步,作为强制门禁


7. 主题切换实现(端到端)

7.1 Vue 端(XiStudioShell 顶层)

<template>
  <div class="ide" :data-theme="theme.current" :class="{ locked: layout.locked }">
    ...
  </div>
</template>

<script setup lang="ts">
import { useThemeStore } from '@/stores/theme'
const theme = useThemeStore()
</script>

7.2 Stage iframe 端(postMessage 同步)

// 在 StageFrame.vue 中
const theme = useThemeStore()
const bridge = useStageBridge(frameRef)

watch(() => theme.current, (newTheme) => {
  bridge.send('theme', { theme: newTheme })  // ⚠️ 需要 ADR 协议扩展
})

iframe 内部接收并切换 data-theme

// public/stages/stage-xilink.html
window.addEventListener('message', (e) => {
  if (e.data.type === 'theme') {
    document.body.dataset.theme = e.data.theme
  }
})

📝 theme 是 Shell→Stage 的协议扩展,需要按 40-postmessage-protocol.md §6 的 ADR 流程登记。

7.3 持久化

useThemeStorexistudio-theme-v1 localStorage key,与 layout-v1 解耦。


8. 与 Tailwind / UnoCSS 的取舍

方案 评价 推荐度
A · 仅 codex.css 法典统一;零冲突;视觉零回归 ⭐⭐⭐⭐⭐
B · codex.css + Tailwind 仅 utility Tailwind 用于 m/p/flex 等微补丁 ⭐⭐⭐
C · 完全 Tailwind 替代 codex.css 需要重写 1212 行;视觉法典丢失

推荐采用 A。如果团队强烈要求 Tailwind,按 B:限制 Tailwind 仅用 spacing / flex / grid utility,不覆盖颜色/边框/阴影等法典内容。


9. 性能与首屏

  • codex.css 1212 行 ≈ 35KB(gzip 后 ~7KB)
  • 全局 import 不影响首屏(与 Vue runtime 一起 bundle)
  • 首屏关键路径:xistudio-codex.cssXiStudioShell.vue → 后续懒加载组件

如果未来发现 codex.css 过大,可拆分为: - codex-base.css(grid + 颜色变量)首屏 import - codex-extras.css(动画/复杂浮窗)懒加载

当前不做——35KB 完全在可接受范围。


10. 验收

  • diff src/styles/xistudio-codex.css ../layout-demo/xistudio-codex.css 输出为空
  • 6 个主题切换正常(玫瑰金/纸面暖/深夜蓝/丝绸灰/森林雾/樱花粉)
  • 浏览器 DevTools 中无 codex.css 类的 CSS warning(如未匹配选择器)
  • 截图 diff 与 demo < 1%(同分辨率 1920×1080)
  • 所有组件类名严格匹配 §1 原则 3 的清单(grep 验证)

v1.0 · 2026-05-17 · D4 前端改造手册 · codex.css 复用策略 · 配套 v1.2.2-impl §12.8