主题
界面
主题
本页说明知识库界面的三件事:左侧导航怎么收起、新版与经典版怎么切换、以及有哪些快捷键。所有状态都只存在本机浏览器(localStorage),不上传、不需要账号。
本页与知识覆盖矩阵同属查阅页,不参与课程推进链条,因此页脚不显示「上一节 / 下一节」;课程推进顺序见学习路线总览。
| 方式 | 位置 | 说明 |
|---|---|---|
| 点击按钮 | 顶部导航栏左侧、站名右侧的方形图标按钮 | 主要入口,展开与收起共用同一个按钮,图标方向随状态翻转 |
| 键盘快捷键 | 任意页面按 [ | 焦点在搜索框、输入框内时不触发,避免误触 |
按钮带 aria-expanded 与 aria-controls,读屏软件可以播报当前是展开还是收起;鼠标悬停会显示当前动作与快捷键提示。
这里刻意选择了「完全隐藏」而不是「仅保留图标」:本知识库的侧栏条目全部是中文课程标题,没有对应的图标语义,硬做成图标栏只会得到一排看不出含义的方块。收起后正文占满整宽并自动居中,阅读区更宽;导航的入口则由始终可见的顶部按钮承担。
顶部按钮在展开与收起两种状态下位置不变——它始终贴在侧栏右边缘,因此也是「侧栏边界在哪」的视觉锚点。
transform: translateX(-100%) + 透明度变化,时长 320ms,缓动 cubic-bezier(0.22, 0.61, 0.36, 1)(先快后慢,收尾平稳)。padding-left / padding-right 同步过渡,时长与侧栏一致,因此正文扩张与侧栏滑出是同一个动作,不会出现先空一块再补上的跳变。visibility 的切换延迟到动画结束(visibility 0s linear 320ms),既不会在动画中被读到,也不会挡住正文点击。状态写在 <html> 元素的两个数据属性上:
| 属性 | 取值 | 作用 |
|---|---|---|
data-kb-sidebar | expanded / collapsed | 侧栏状态,决定上面那套样式是否命中 |
data-kb-ui | modern / classic | 界面版本,见下一节 |
具体机制:
<html>,属性天然保留,无需额外处理。docs/.vitepress/config.mts 的 head 里有一段内联脚本,在首帧渲染之前就把属性写回,所以不会出现「先展开、再收起」的闪动。localStorage(键名 java-kb:sidebar),下次访问、换页面、关掉浏览器再打开都保持上次的选择。窄屏(< 960px)沿用 VitePress 自带的汉堡菜单 + 抽屉式侧栏,本机制不介入,避免两套交互打架。
| 入口 | 位置 |
|---|---|
| 导航栏切换器 | 顶部导航栏最右侧,新版 与 经典 两个胶囊按钮(窄屏只留这两个按钮,隐藏「界面」二字) |
| 移动端菜单 | 点开汉堡菜单后,菜单底部同样有这组切换器 |
| URL 参数 | 在任意地址后加 ?ui=classic 或 ?ui=modern,用于临时对照或分享指定版本 |
默认是「新版」。未做过任何选择、或清空了浏览器数据时,页面按新版渲染;只有显式点击「经典」或带上 ?ui=classic 才会切到经典版。选择同样记在 localStorage(键名 java-kb:ui),跨页面、跨会话保持。
custom.css(靛蓝系强调色、Inter 字体、默认间距)。| 维度 | 新版做法 | 解决的问题 |
|---|---|---|
| 字体 | 改为系统字体栈(system-ui → 苹方 / 微软雅黑),不再请求 Google Fonts | 原主题通过 Google Fonts 加载 Inter,国内网络下慢且可能失败;中文正文本来也由系统字体承担 |
| 配色 | 用 oklch() 重排品牌绿与中性色,明暗两套主题分别定值;背景由纯白改为暖白 | 纯白 + 纯黑对比过强;手写十六进制色在暗色下容易失效 |
| 正文排版 | 正文 16.5px / 行高 1.85,行宽收敛到 44rem(约 42 个汉字一行),标题改用 clamp() 流式字号并去掉中文标题上的负字距 | 原行高 28px 对中文偏紧;负字距是为拉丁字母设计的,中文会显得挤 |
| 导航与侧栏 | 导航项加下划线指示条;侧栏条目加大字号层级差、增加整行悬停底色与 3px 选中指示条 | 长列表里「当前在哪一节」不够明显,可点区域也偏小 |
| 代码 | 代码块加描边与圆角、语言标签大写化、复制按钮放大到 34px | 代码块与正文区分度弱 |
| 表格 / 提示块 | 表格整体加圆角描边、表头加重、斑马纹减淡;提示块由无边框改为同色系细描边 | 大表格容易糊成一片 |
| 可访问性 | 统一的 :focus-visible 焦点环、::selection 配色、细滚动条、<kbd> 按键样式 | 键盘导航时看不清焦点位置 |
右侧「本页目录」不在此列:它的列宽、左右内边距、行盒高度与字号全部沿用 VitePress 原版,与经典版一致,新版没有对它做任何覆盖。
| 按键 | 作用 |
|---|---|
| [ | 收起 / 展开左侧导航(输入框内不生效) |
| Ctrl + K | 打开站内搜索(VitePress 自带) |
| Esc | 关闭搜索或移动端菜单 |
改样式或改行为时,按下面的对应关系找文件:
| 文件 | 职责 |
|---|---|
docs/.vitepress/theme/composables/useKbUi.ts | 状态读写与规范化,键名、默认值的唯一来源 |
docs/.vitepress/theme/components/SidebarToggle.vue | 收起按钮与快捷键 |
docs/.vitepress/theme/components/UiVersionSwitch.vue | 新旧版本切换器 |
docs/.vitepress/theme/styles/shell.css | 收起/展开的布局机制与过渡(两个版本通用) |
docs/.vitepress/theme/styles/modern.css | 新版皮肤(全部挂在 html[data-kb-ui='modern'] 之下) |
docs/.vitepress/config.mts | head 内联引导脚本,负责首帧前写回状态 |
scripts/check-theme.mjs | 主题自检:不经过站点构建,验证 CSS / TS / Vue 与引导脚本(npm run theme:check) |
状态键名与默认值在
useKbUi.ts和config.mts的内联脚本里各出现一次。这是「首帧前生效」与「Vue 里可响应」两个需求带来的必要重复,改动时必须同步,否则会出现刷新后状态回弹。
改完主题代码后,先跑 npm run theme:check:它会解析全部 CSS、转译 TS、编译每个 .vue,并把上面那段引导脚本在桩环境里跑 5 个用例核对取值优先级。这一步不需要站点构建,因此在构建跑不起来时(见 .codebuddy/rules/build-and-verify.md 约束 13)仍能确认主题代码没写坏。