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)
- ❌ 不要拆为
_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
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
正确做法: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 切换
正确做法(codex.css §7 设计):
❌ 反模式 5 · z-index 乱写
codex.css 内部已规划了 z-index 层级:
| 层 | z-index | 内容 |
|---|---|---|
| 基础 | 1 | .ide |
| Drawer 浮层 | 100 | .drawer |
| Toast | 1000 | .toast |
| TuningDialog | 2000 | .tuning-dialog |
| Modal | 3000 | (预留) |
正确做法:用 codex.css 已定义的 z-index 等级,或新增层时与法典对齐 + ADR。
❌ 反模式 6 · Tailwind 与 codex.css 混用
如果项目引入了 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 持久化
useThemeStore 用 xistudio-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.css→XiStudioShell.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