# docs 站窄屏抽屉导航 — 设计与落地记录

> 2026-08-11。owner 当日提出「顶栏有问题，宽度不够时可以做成移动端的导航样式」，
> brainstorm 三问定范围/断点/取舍后**当日实现并验收**，故本文件是设计 + 落地合一的记录，
> 不是待执行的 spec。实测数字与故障排查见 [STATUS-CHANGELOG](../../internal/STATUS-CHANGELOG.md) 同日条目。

## 1. 问题（实测，不是观感）

owner 的原话只指向顶栏，但量完发现顶栏只是小头：

| 视口 | 顶栏 | 侧栏 | 正文标题距顶 |
|---|---|---|---|
| 390（iPhone 13）| 311px（且 `position: sticky`）| 1781px / 33 链接 | **2177px ≈ 2.6 屏** |
| 680 | 265px | 1781px | 2131px ≈ 2.5 屏 |
| 1000 | 105px | 1781px | 1979px ≈ 2.3 屏 |

顶栏占那 2131px 的 **12%**，侧栏占 **84%**。成因是两个既有断点各塌一半：`720` 让顶栏三块
各占满宽堆叠，`1100` 让 `.canonical-shell` 变单列、`.docs-sidebar` 变 `static` + `max-height: none`
（整份组件列表平铺到正文上方）。⇒ 只改顶栏解决不了问题，范围必须含侧栏。

## 2. owner 拍板的三件

| 决策 | 选择 | 关键理由 |
|---|---|---|
| 范围 | **顶栏 + 侧栏都收进抽屉** | 只修顶栏仅覆盖 12% |
| 断点 | **≤1100（`--bp-lg`）** | 与既有塌陷点一致，不新增断点值；960–1100 现状已是「单列 + 侧栏平铺」，改成抽屉是纯改善；>1100 桌面零改动 |
| 顶栏取舍 | ☰ + 站名 + **Vue│React** + 搜索 | framework 切换在看 demo 时高频，值得占一格 |

## 3. 形态

左侧滑入，宽 `min(320px, 86%)`，遮罩 `--mask-overlay`。**不用全屏覆盖** —— 全屏会让人丢失
「我在哪一页」的上下文，而文档站的常见动作是「看一眼目录再回来」。

关闭路径四条：✕ / 点遮罩 / `Esc` / **选中任一导航项后自动关**（SPA 换页不刷新，不关正好挡住刚跳到的内容）。
自动关挂在 `watch(currentPage)` 上而不是逐个链接，这样新增导航入口不会漏。

打开时锁 `body` 滚动、焦点移入抽屉，关闭后焦点还给 ☰。`role="dialog"` + `aria-modal` +
☰ 上的 `aria-expanded`/`aria-controls`。视口回到 >1100 时强制收状态，否则「窄屏开着抽屉→转横屏」
会留下锁死的 body。

## 4. 关键实现决定：页面树不复制 DOM

同一个 `<aside class="docs-sidebar">` 在窄屏被 CSS 变成抽屉本体 —— **桌面/窄屏共用一份 DOM**，
不存在「两套导航各自漂移」。抽屉里额外的主导航/偏好/元信息也全部读同一批数据源
（`topNavigation` / `localeOptions` / `docsVersion` …），只是靠 `display:none` 在桌面隐藏。

## 5. 踩到的两个坑（都值得记）

**① `align-self: start` 会废掉 `top:0; bottom:0`。** 桌面态 `.docs-sidebar` 带 `align-self: start`；
对**定位**的 grid item，align-self 会压过上下拉伸、退化成 shrink-to-fit。症状极具迷惑性：
抽屉 `clientHeight` 变成内容高 **2351px**（视口才 844），于是 `scrollHeight === clientHeight`、
测出来「不需要滚动」，而底部的偏好/元信息区**永远够不着**。修法 = 在断点块里显式 `align-self: stretch`。

**② 图标短名不一定是有效 alias。** `action/hamburger` 的 tags 逐字是 `["menu","hamburger","navigation drawer"]`，
但它的 alias 只有 `action-hamburger` —— **`hamburger` 与 `menu` 都不解析**，写错会静默渲染成空方框。
有效名的唯一真源是 `src/icons/generated/*.ts` 里每条的 `name` + `aliases[]`
（⚠️ 不是 `dist/icons/manifest.json`，那是给外部消费者的另一份出口；本轮一度查错文件，
连现役的 `search`/`clock` 都「查不到」才发现）。

## 6. 验收（全部实测）

- **窄屏三档**：顶栏 311/265/105 → **57/57/57**；正文标题距顶 2177 → **110px（0.13 屏）**；控制台 0 报错
- **横向溢出**：390 = 46px，**改动前后逐字相同**（`git archive HEAD` 取改动前产物起第二个服务做的 A/B）——
  来自 `.api-table` 既有的 `min-width: 720px` intentional-scroll，非本次引入；680/1000 均为 0
- **桌面 1280 零改动**：☰/遮罩/抽屉头/主导航/工具区全 `display:none`，`.docs-sidebar` 仍 `sticky`、
  `transform: none`，右侧 TOC 与顶栏主导航照常
- **交互**：开→`aria-expanded=true`、焦点入抽屉、`body.overflow=hidden`；Esc / 遮罩 / 选链接三条路径均关闭且焦点回 ☰；
  选链接后路由确实到 `/component/badge`；抽屉内 33 链接 + 三个附加区俱在、可滚（`clientH 844 / scrollH 2351`）
- **双主题**：取色全部落在 token 上 —— dark `#1f1f1f`/`#434343`/`#cccccc`，light `#f8f8f8`/`#cccccc`/`#434343`，遮罩 `rgba(0,0,0,.6)`
- `audit:layout-tokens` / `no-hardcoded-design-tokens` / `docs-site` / `demo-css-page-scope` 全绿；`pnpm test` 1415 passed / 11 skipped

## 7. 刻意没做

- **720 那条豁免没有消失。** 本轮删掉了 720 块里整套顶栏堆叠规则（被抽屉取代），但块内还剩
  4 条与顶栏无关的规则（`.canonical-shell` 内边距 + `.docs-pager` 竖排）。要消掉这个断点得把它们
  归并到 `--bp-sm(640)`，那会改 640–720 区间的内边距与翻页器排布 = **另一次视觉裁定**，不顺手做。
- 不引动画库、不做手势滑动关闭、不做底部 tab 栏、不重组页面树分类、不碰搜索按钮的「死按钮」问题（DOCS-7 独立项）。
