241 lines
9.1 KiB
CSS
241 lines
9.1 KiB
CSS
/* ==========================================================================
|
||
API 文档版式(docs/content/api/**)
|
||
--------------------------------------------------------------------------
|
||
三处视觉缺口,对应下面三段:
|
||
|
||
1. 端点标题 `## `POST` `/data/page`` 与 `## 基础约定` 长得一样 → 方法徽章
|
||
2. 参数表是裸 markdown 表格(必填列原来是 emoji)→ G3ApiParams 面板
|
||
3. 请求体 / 响应体是两块一模一样的灰底 JSON → G3ApiPayload 面板(按 code 着色)
|
||
|
||
两条自我约束:
|
||
- 只用 --vp-c-* 变量,不引第三方样式表。站点其余部分是逐像素对齐 Docus 的
|
||
(见 custom.css),API 页必须留在同一套设计语言里。
|
||
- 一律逻辑属性(inline-* / block-*),站内已有 RTL 支持(见 content/ui/usage/rtl)。
|
||
========================================================================== */
|
||
|
||
/* ==========================================================================
|
||
1. 端点标题
|
||
--------------------------------------------------------------------------
|
||
写法:## `POST` `/data/page`
|
||
|
||
用 :has(> code:first-child) 把端点标题与普通 H2 区分开 —— 这既是样式的需要,
|
||
也是「为什么不用组件渲染标题」的答案:标题一旦交给 Vue 组件渲染,就不再进
|
||
markdown 的 heading token 流,右侧目录(G3DocAside)会丢掉全部条目、锚点
|
||
一并消失。所以标题仍是 markdown H2,只在 CSS 上做文章。
|
||
|
||
代价:方法徽章的颜色没法按 GET/POST 区分(CSS 不能按文本匹配)。当前
|
||
/api/** 下全部是 POST,所以是准确的;将来出现混合方法时,在 config.mts 的
|
||
markdown.config 里加一个「把首词换成 <span class="g3-api-method--get">」的
|
||
小插件即可,slug 由文本 token 决定,不受影响。
|
||
|
||
作用域:三张 API 页都带 frontmatter `pageClass: g3-api`(VitePress 把该 class
|
||
落到根 <div class="Layout"> 上,见主题 Layout.vue:34),下面全部规则都由
|
||
.g3-api 兜住,不会漏到组件页去。
|
||
========================================================================== */
|
||
.g3-api .vp-doc h2:has(> code:first-child) {
|
||
/* 覆盖 VitePress 的 .vp-doc h2(上边框 + padding-top):端点标题改为
|
||
「下方一条分隔线」,与紧随其后的参数面板构成一组,读起来是一个接口一节。 */
|
||
margin-block: 56px 20px;
|
||
padding-block: 0 14px;
|
||
border-block-start: 0;
|
||
border-block-end: 1px solid var(--vp-c-divider);
|
||
font-size: 20px;
|
||
line-height: 28px;
|
||
}
|
||
|
||
/* 方法徽章:第一个 code */
|
||
.g3-api .vp-doc h2:has(> code:first-child) > code:first-child {
|
||
padding: 2px 8px;
|
||
border-radius: 6px;
|
||
background-color: var(--vp-c-brand-soft);
|
||
color: var(--vp-c-brand-1);
|
||
font-family: var(--vp-font-family-mono);
|
||
font-size: 12px;
|
||
font-weight: 700;
|
||
line-height: 18px;
|
||
letter-spacing: 0.06em;
|
||
}
|
||
|
||
/* 路径:第二个 code(nth-of-type 只数 code,不受中间的空格文本与
|
||
末尾 header-anchor 的 <a> 影响) */
|
||
.g3-api .vp-doc h2:has(> code:first-child) > code:nth-of-type(2) {
|
||
padding: 0;
|
||
background-color: transparent;
|
||
color: var(--vp-c-text-1);
|
||
font-family: var(--vp-font-family-mono);
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
letter-spacing: -0.01em;
|
||
}
|
||
|
||
/* ==========================================================================
|
||
2 & 3. 面板(G3ApiParams / G3ApiPayload)
|
||
--------------------------------------------------------------------------
|
||
结构:标题栏 + 内容两段式。三个语气走同一组自定义变量,默认中性、
|
||
ok / warn / error 分别取 success / warning / danger。
|
||
|
||
⚠ 语气语义是 **body.code**,不是 HTTP 状态码 —— 这正是通用 OpenAPI
|
||
渲染器做不到的地方(它们的颜色模型绑死 HTTP 状态码,会把这里的
|
||
失败响应渲染成绿色成功块)。
|
||
========================================================================== */
|
||
.g3-api-panel {
|
||
--g3-api-accent: var(--vp-c-text-3);
|
||
--g3-api-accent-soft: var(--vp-c-bg-alt);
|
||
|
||
margin: 16px 0;
|
||
border: 1px solid var(--vp-c-divider);
|
||
border-radius: 8px;
|
||
/* 圆角要裁掉子元素底色(标题栏、代码块),但横向滚动不能裁 ——
|
||
滚动交给 __body,见下。 */
|
||
overflow: hidden;
|
||
}
|
||
|
||
.g3-api-panel--ok {
|
||
--g3-api-accent: var(--vp-c-success-1, var(--vp-c-green-1));
|
||
--g3-api-accent-soft: var(--vp-c-success-soft, var(--vp-c-green-soft));
|
||
}
|
||
|
||
.g3-api-panel--warn {
|
||
--g3-api-accent: var(--vp-c-warning-1, var(--vp-c-yellow-1));
|
||
--g3-api-accent-soft: var(--vp-c-warning-soft, var(--vp-c-yellow-soft));
|
||
}
|
||
|
||
.g3-api-panel--error {
|
||
--g3-api-accent: var(--vp-c-danger-1, var(--vp-c-red-1));
|
||
--g3-api-accent-soft: var(--vp-c-danger-soft, var(--vp-c-red-soft));
|
||
}
|
||
|
||
.g3-api-panel__head {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 8px 14px;
|
||
background-color: var(--vp-c-bg-soft);
|
||
border-block-end: 1px solid var(--vp-c-divider);
|
||
color: var(--vp-c-text-2);
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
line-height: 20px;
|
||
}
|
||
|
||
/* 语气点:与语气同色。文字标签(成功/失败)与它并存,
|
||
不让颜色成为唯一的区分手段。 */
|
||
.g3-api-panel__dot {
|
||
flex: 0 0 auto;
|
||
width: 6px;
|
||
height: 6px;
|
||
border-radius: 50%;
|
||
background-color: var(--g3-api-accent);
|
||
}
|
||
|
||
.g3-api-panel--ok .g3-api-panel__head,
|
||
.g3-api-panel--warn .g3-api-panel__head,
|
||
.g3-api-panel--error .g3-api-panel__head {
|
||
color: var(--g3-api-accent);
|
||
}
|
||
|
||
.g3-api-panel__tone {
|
||
font-weight: 500;
|
||
opacity: 0.9;
|
||
}
|
||
|
||
/* code 徽章:仅 G3ApiPayload 传了 code 时出现 */
|
||
.g3-api-panel__code {
|
||
padding: 1px 7px;
|
||
border-radius: 9999px;
|
||
background-color: var(--g3-api-accent-soft);
|
||
color: inherit;
|
||
font-family: var(--vp-font-family-mono);
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.g3-api-panel__body {
|
||
/* 宽表横向滚动由这一层承担:VitePress 给 .vp-doc table 设了
|
||
display:block + overflow-x:auto,那会让 table 自己成为滚动容器
|
||
(custom.css 里已记录过它导致 sticky 表头失效的问题)。 */
|
||
overflow-x: auto;
|
||
}
|
||
|
||
/* --- 参数表:去掉 .vp-doc 给 markdown 表格画的四边框与上下留白 ------ */
|
||
.g3-api-panel__body table {
|
||
display: table;
|
||
width: 100%;
|
||
margin: 0;
|
||
}
|
||
|
||
.g3-api-panel__body table th,
|
||
.g3-api-panel__body table td {
|
||
border: 0;
|
||
border-block-end: 1px solid var(--vp-c-divider);
|
||
padding: 8px 14px;
|
||
background-color: transparent;
|
||
}
|
||
|
||
.g3-api-panel__body table tr:nth-child(2n) {
|
||
background-color: transparent;
|
||
}
|
||
|
||
.g3-api-panel__body table tr:last-child td {
|
||
border-block-end: 0;
|
||
}
|
||
|
||
.g3-api-panel__body table th {
|
||
color: var(--vp-c-text-3);
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
text-align: start;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* 列序约定:参数 / 类型 / 必填 / 说明。这两条按位置定样式,所以要两重限定:
|
||
1) variant="params" —— 参数表才有这个形状。bare 的表(错误码:code / 含义 /
|
||
典型原因 / 定位)若套上,散文列会被当成「类型」套等宽、被当成「必填」染成品牌色。
|
||
2) :has(td:nth-child(4)) —— 同一个 params 变体下,「字段 / 说明」两列表(如
|
||
/data/page 的 data 字段)第 2 列是散文,也不该套等宽小字。
|
||
第 1 列两种表都是标识符(参数名 / 字段名 / code),所以不加限定。 */
|
||
.g3-api-panel__body table td:first-child {
|
||
color: var(--vp-c-text-1);
|
||
font-family: var(--vp-font-family-mono);
|
||
font-size: 13px;
|
||
}
|
||
|
||
.g3-api-panel--params .g3-api-panel__body:has(td:nth-child(4)) table td:nth-child(2) {
|
||
color: var(--vp-c-text-3);
|
||
font-family: var(--vp-font-family-mono);
|
||
font-size: 12px;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.g3-api-panel--params .g3-api-panel__body:has(td:nth-child(4)) table td:nth-child(3) {
|
||
color: var(--vp-c-brand-1);
|
||
font-weight: 500;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* --- 报文里的代码块:贴边(VitePress 默认 margin:20px 0 + 圆角 8px)- */
|
||
.g3-api-panel__body div[class*='language-'] {
|
||
margin: 0;
|
||
border-radius: 0;
|
||
}
|
||
|
||
/* ==========================================================================
|
||
4. 表格列宽:短中文列不被压扁
|
||
--------------------------------------------------------------------------
|
||
现象:/api/getting-started 的「接口一览」里「板块」列被压成一列一个字
|
||
(「数据查询」折成两行)。
|
||
|
||
原因不是这列太长,而是**太短**:CJK 没有「词」的边界,可以逐字换行,于是
|
||
该列的 min-content 宽度只有 1 个字。table-layout: auto 按 min-content 分配
|
||
空间时,浏览器会把这列压到最小、把余量让给旁边的长路径与长文案 —— 越短的列
|
||
越容易被牺牲,与直觉相反。
|
||
|
||
nowrap 把该列的 min-content 抬到「整格文字的宽度」,即不可再压。
|
||
API 页各表的首列都是短键(板块 / 项 / code / 字段 / 参数名),nowrap 安全;
|
||
长文案列(说明、触发场景)不带这条规则,照常换行。
|
||
========================================================================== */
|
||
.g3-api .vp-doc table th:first-child,
|
||
.g3-api .vp-doc table td:first-child {
|
||
white-space: nowrap;
|
||
}
|