引用块(blockquote)内文字比正文多内缩 22px,用首尾引号替代缩进使两者对齐;版本号升 4.0.0 #32

Closed
opened 2026-10-28 01:56:35 +00:00 by laoyang · 2 comments
Owner

现象

正文里的引用块(blockquote)有浅蓝底色 + 左侧 6px 色条,但色条和底色带来的
padding-left 让块内文字的
起点比正文段落更靠右
,导致引用文字与正文段落的
缩进不一致,阅读时视线需要重新定位。

用户原话:

页面如果有引用的文字,会有一个色块,然后这个色块左侧有一定的宽度,这样这个应用块
里面的文字,段落也缩进了,这样就和主要段落缩进不同了。需要解决。我的建议是,
色块保留,然后在引用的开始和结束,增加两个引号,这两个引号,代替引用文本的缩进,
这样让引用文本的缩进和段落缩进基本保持一致,你看这样行不行。

已实测现状(线上真实几何,1440 视口)

测的是线上文章 /2026/01/principles-of-communism.html(含真实引用块),
Chromium 无头浏览器量 getBoundingClientRect() + getComputedStyle():

正文段落 p:        left=67   text-indent=32px   ⇒ 文字起点 = 67 + 32 = 99
引用块 blockquote: left=67   width=850  border-left=6px  padding-left=16px
  块内 p:          left=89   text-indent=32px   ⇒ 文字起点 = 89 + 32 = 121

引用块内文字比正文文字靠右 22px(= border 6px + padding 16px)。
而块内 p 自己还在继承 text-indent: 2em(32px,来自 site.css 的
.article .content p),所以是"块本身就内缩 + 段首又缩进"双叠加。

当前 blockquote 样式(assets/css/kratos.css:966):

.k-main .details .article .content blockquote {
  margin-bottom: 16px;
  padding: 16px;
  border-left: 6px solid #dce6f0;
  background: #f2f7fb;
  color: #819198;
  font-size: 15px;
}

注意:site.css 里没有任何 blockquote 规则,全部来自 kratos.css。

用户选定的方案

  1. 色块保留(浅蓝底 + 左侧色条)
  2. 在引用的开始和结束各加一个引号 —— 即整段首尾各一个,不是每段各加
  3. 引号放大且淡色,做装饰
  4. 用引号代替引用文本的缩进,让引用文字与正文段落的缩进基本一致

验收标准

  1. 引用块内文字起点与正文段落文字起点基本一致(差 ≤ 8px,因中文字形与引号
    占位不可能像素级相等;目标是对齐到肉眼看不出来)
  2. 引用块首尾各有一个引号(整段一个,不是每段)
  3. 引号字号大于正文、颜色淡于正文,属装饰性质,不抢注意力
  4. 浅蓝底色 + 左侧色条保留
  5. 引用块内多段落时,引号仍在整段首尾,不重复出现
  6. 引用块内含 <cite>(出处署名)时不错位
  7. 暗色模式(html.yang-dark)下引号颜色适配,不发灰发黑看不清
  8. 移动端 390/768 视口下不溢出、引号不被挤压
  9. 版本号升到 4.0.0(用户明确要求跳大版本)

约束

  • 不能改文章内容(存量 968 篇文章,含引用块的 15+ 篇),必须靠 CSS 伪元素自动生效
  • kratos.min.css 是 kratos.css 的压缩产物,若改 kratos.css 必须重新压缩
  • 优先只改 site.css(不参与压缩,且加载顺序在 kratos.min.css 之后)
  • 走 /theme-update/ 发布,不覆盖服务器主题目录
## 现象 正文里的**引用块(blockquote)**有浅蓝底色 + 左侧 6px 色条,但色条和底色带来的 `padding-left` 让块内文字的**起点比正文段落更靠右**,导致引用文字与正文段落的 缩进不一致,阅读时视线需要重新定位。 用户原话: > 页面如果有引用的文字,会有一个色块,然后这个色块左侧有一定的宽度,这样这个应用块 > 里面的文字,段落也缩进了,这样就和主要段落缩进不同了。需要解决。我的建议是, > 色块保留,然后在引用的开始和结束,增加两个引号,这两个引号,代替引用文本的缩进, > 这样让引用文本的缩进和段落缩进基本保持一致,你看这样行不行。 ## 已实测现状(线上真实几何,1440 视口) 测的是线上文章 `/2026/01/principles-of-communism.html`(含真实引用块), Chromium 无头浏览器量 `getBoundingClientRect()` + `getComputedStyle()`: ``` 正文段落 p: left=67 text-indent=32px ⇒ 文字起点 = 67 + 32 = 99 引用块 blockquote: left=67 width=850 border-left=6px padding-left=16px 块内 p: left=89 text-indent=32px ⇒ 文字起点 = 89 + 32 = 121 ``` **引用块内文字比正文文字靠右 22px**(= border 6px + padding 16px)。 而块内 `p` 自己还在继承 `text-indent: 2em`(32px,来自 `site.css` 的 `.article .content p`),所以是"块本身就内缩 + 段首又缩进"双叠加。 当前 blockquote 样式(`assets/css/kratos.css:966`): ```css .k-main .details .article .content blockquote { margin-bottom: 16px; padding: 16px; border-left: 6px solid #dce6f0; background: #f2f7fb; color: #819198; font-size: 15px; } ``` 注意:`site.css` 里**没有任何 blockquote 规则**,全部来自 kratos.css。 ## 用户选定的方案 1. **色块保留**(浅蓝底 + 左侧色条) 2. **在引用的开始和结束各加一个引号** —— 即**整段首尾各一个**,不是每段各加 3. 引号**放大且淡色**,做装饰 4. 用引号**代替**引用文本的缩进,让引用文字与正文段落的缩进基本一致 ## 验收标准 1. 引用块内**文字起点**与正文段落**文字起点**基本一致(差 ≤ 8px,因中文字形与引号 占位不可能像素级相等;目标是对齐到肉眼看不出来) 2. 引用块首尾各有一个引号(整段一个,不是每段) 3. 引号字号大于正文、颜色淡于正文,属装饰性质,不抢注意力 4. 浅蓝底色 + 左侧色条**保留** 5. 引用块内**多段落**时,引号仍在整段首尾,不重复出现 6. 引用块内含 `<cite>`(出处署名)时不错位 7. 暗色模式(`html.yang-dark`)下引号颜色适配,不发灰发黑看不清 8. 移动端 390/768 视口下不溢出、引号不被挤压 9. 版本号升到 **4.0.0**(用户明确要求跳大版本) ## 约束 - 不能改文章内容(存量 968 篇文章,含引用块的 15+ 篇),必须靠 CSS 伪元素自动生效 - `kratos.min.css` 是 `kratos.css` 的压缩产物,若改 kratos.css 必须重新压缩 - 优先只改 `site.css`(不参与压缩,且加载顺序在 kratos.min.css 之后) - 走 `/theme-update/` 发布,**不覆盖**服务器主题目录
Author
Owner

4.0.0 已发布,等你点升级

提交:05b4b56(wordpress-kratos-yang main)
包:kratos_yang-4.0.0.zip,md5 bc23f478d5f5170524aec3921b10e6ff
发布位置:只发了 /www/wwwroot/yangyq.net/theme-update/(zip + readme + update.json),
没有覆盖 wp-content/themes/kratos_yang/。线上主题目录仍是 3.2.64,等你后台点升级。

改了什么

按你定的方案:色块保留,首尾各加一个引号,用引号占住那段缩进。

改前实测(1440 视口,线上真实文章):

文字起点
正文段落 p 99
引用块框内沿 89
块内 p 121

引用文字比正文靠右 22px,而且块内段落还多叠了一层 32px 首行缩进。

改后:

  • border-left 6 + padding-left 26 = 32,正好等于正文的 text-indent: 2em(16×2)
  • 块内 > p 的 text-indent 归零,消除双层叠加
  • 左引号浮在 padding 区、右引号贴末字之后,都不参与文字排版
  • 引号 60 / 56px,淡蓝 #c6d2dd;暗色降到 #3d4b58

三篇文章 × 五个视口(1440 / 1200 / 992 / 768 / 390)实测对齐差全部 0.00px。

两个花了不少功夫才查出来的坑

① 引号一开始其实压在文字上,读代码完全看不出来。

left: 6px、font-size: 30px 的时候,伪元素的盒在元素内 x=12,完全正确。
但截两张图逐像素相减才发现,引号的墨迹在 x=30.540,而首字墨迹起点是 32.5 ——
缩进空白里(6
32)非底色像素是 0,引号整个压在第一个字上。

根因是中文 UI 字体下 " 走的是 CJK 全角字形:字身宽 1em,左侧空白(side bearing)
约 0.62em,30px 字号就是 18.5px。盒左沿 12 + 18.5 = 30.5,正好压到首字。

解决:给引号指定拉丁衬线字体(Georgia, "Times New Roman", serif),side bearing 降到
约 0.03em,再配合 left: 2px / top: 15px / font-size: 60px。改后墨迹落在 10.0~29.5,
比正文字还小一点点但已经"放大"了(20×16 vs 正文汉字 15×15)。

这是「盒对了 ≠ 字形画在那儿」——getComputedStyle 和 getBoundingClientRect
只能量盒,量不到墨迹。只有同页同视口截两张图做差分能发现。

② 窄屏下正文缩进会自己变,硬编码的 32 就错 2px。

kratos.css 在 ≤768px 把 .content p 的字号降到 15px,于是 text-indent: 2em 变成
30px,而 border 6 + padding 26 = 32 是写死的 ⇒ 窄屏引用文字反而靠右 2px。

不能写 calc(2em - 6px)——em 的基数是元素自己的字号,而 blockquote 自己写着
font-size: 15px、不跟视口变,算出来宽窄屏都是 24px。只能在与源规则同一个断点上覆盖。

而且这个 @media 块必须放在所有 blockquote 基础规则之后:第一版我放在
::before 基础规则之前,两者特异性相同,后出现的 left: 2px 直接把它压掉了。
CSS 层判据全绿(它只能看到"@media 里确实写了"),又只有像素差分能抓到。

readme

新增「六、为什么版本号跳 4.0.0」一节,14 → 15 节。里面写了两件事:
怎么改回去(引号是装饰,删掉不影响排版)、以及以后要改字号必须重新量引号位置
(left/top 是实测标定的,不是按比例算的)。

验证

判据 结果
_geom32.js 几何 48 / 0
_pix400.py 像素差分 76 / 0
_mkzip400.py 打包自检 61 / 0
_mkzip400_falsify.py 反证(18 组注入) 20 / 0
_pix400_falsify.py 反证(5 组注入) 8 / 0
_readme400.py readme 36 / 0
php -l 全量 97 文件 / 0 失败

发布侧:三方 md5 一致(本地 / 服务器 / HTTP 下载),update.json 里的 md5 与实际包一致,
readme.html 200,上一版 kratos_yang-3.2.64.zip 仍可下载(旧客户端不 404)。
PUC 实测 getUpdate()->version = 4.0.0,download_url 指向 4.0.0 包,md5 也对得上。

请你确认

后台「外观 → 主题」应该能看到 4.0.0 的更新提示,点升级后我再到线上量一次真实几何确认。
看完没问题我就关单。

## 4.0.0 已发布,等你点升级 **提交**:`05b4b56`(`wordpress-kratos-yang` main) **包**:`kratos_yang-4.0.0.zip`,md5 `bc23f478d5f5170524aec3921b10e6ff` **发布位置**:只发了 `/www/wwwroot/yangyq.net/theme-update/`(zip + readme + update.json), **没有**覆盖 `wp-content/themes/kratos_yang/`。线上主题目录仍是 3.2.64,等你后台点升级。 ### 改了什么 按你定的方案:**色块保留,首尾各加一个引号,用引号占住那段缩进**。 改前实测(1440 视口,线上真实文章): | | 文字起点 | |---|---| | 正文段落 `p` | 99 | | 引用块框内沿 | 89 | | **块内 `p`** | **121** | 引用文字比正文**靠右 22px**,而且块内段落还多叠了一层 32px 首行缩进。 改后: - `border-left 6 + padding-left 26 = 32`,正好等于正文的 `text-indent: 2em`(16×2) - 块内 `> p` 的 `text-indent` 归零,消除双层叠加 - 左引号浮在 padding 区、右引号贴末字之后,都**不参与文字排版** - 引号 60 / 56px,淡蓝 `#c6d2dd`;暗色降到 `#3d4b58` 三篇文章 × 五个视口(1440 / 1200 / 992 / 768 / 390)实测**对齐差全部 0.00px**。 ### 两个花了不少功夫才查出来的坑 **① 引号一开始其实压在文字上,读代码完全看不出来。** `left: 6px`、`font-size: 30px` 的时候,伪元素的**盒**在元素内 x=12,完全正确。 但截两张图逐像素相减才发现,引号的**墨迹**在 x=30.5~40,而首字墨迹起点是 **32.5** —— 缩进空白里(6~32)非底色像素是 **0**,引号整个压在第一个字上。 根因是中文 UI 字体下 `"` 走的是 **CJK 全角字形**:字身宽 1em,左侧空白(side bearing) 约 **0.62em**,30px 字号就是 18.5px。盒左沿 12 + 18.5 = 30.5,正好压到首字。 解决:给引号指定拉丁衬线字体(`Georgia, "Times New Roman", serif`),side bearing 降到 约 0.03em,再配合 `left: 2px / top: 15px / font-size: 60px`。改后墨迹落在 10.0~29.5, 比正文字还小一点点但已经"放大"了(20×16 vs 正文汉字 15×15)。 这是「**盒对了** ≠ **字形画在那儿**」——`getComputedStyle` 和 `getBoundingClientRect` 只能量盒,量不到墨迹。只有同页同视口截两张图做差分能发现。 **② 窄屏下正文缩进会自己变,硬编码的 32 就错 2px。** `kratos.css` 在 `≤768px` 把 `.content p` 的字号降到 15px,于是 `text-indent: 2em` 变成 **30px**,而 `border 6 + padding 26 = 32` 是写死的 ⇒ 窄屏引用文字反而靠右 2px。 不能写 `calc(2em - 6px)`——`em` 的基数是**元素自己**的字号,而 `blockquote` 自己写着 `font-size: 15px`、不跟视口变,算出来宽窄屏都是 24px。只能在与源规则同一个断点上覆盖。 而且这个 `@media` 块**必须放在所有 `blockquote` 基础规则之后**:第一版我放在 `::before` 基础规则之前,两者特异性相同,后出现的 `left: 2px` 直接把它压掉了。 CSS 层判据全绿(它只能看到"@media 里确实写了"),又只有像素差分能抓到。 ### readme 新增「六、为什么版本号跳 4.0.0」一节,14 → 15 节。里面写了两件事: 怎么改回去(引号是装饰,删掉不影响排版)、以及**以后要改字号必须重新量引号位置** (`left`/`top` 是实测标定的,不是按比例算的)。 ### 验证 | 判据 | 结果 | |---|---| | `_geom32.js` 几何 | 48 / 0 | | `_pix400.py` 像素差分 | 76 / 0 | | `_mkzip400.py` 打包自检 | 61 / 0 | | `_mkzip400_falsify.py` 反证(18 组注入) | 20 / 0 | | `_pix400_falsify.py` 反证(5 组注入) | 8 / 0 | | `_readme400.py` readme | 36 / 0 | | `php -l` 全量 | 97 文件 / 0 失败 | 发布侧:三方 md5 一致(本地 / 服务器 / HTTP 下载),`update.json` 里的 md5 与实际包一致, `readme.html` 200,上一版 `kratos_yang-3.2.64.zip` 仍可下载(旧客户端不 404)。 PUC 实测 `getUpdate()->version = 4.0.0`,`download_url` 指向 4.0.0 包,md5 也对得上。 ### 请你确认 后台「外观 → 主题」应该能看到 4.0.0 的更新提示,点升级后我再到线上量一次真实几何确认。 看完没问题我就关单。
Author
Owner

线上验收通过,关单

你在 12:37 升级到 4.0.0 了。我刚在线上量完,不拦截 CSS、直接量真实渲染。

几何:三篇文章 × 五视口,全对齐

视口 引用文字起点 正文文字起点 差
390 77.0 77.0 0.00
768 80.2 80.2 0.00
992 87.8 87.8 0.00
1440 99.0 99.0 0.00
1920 303.0 303.0 0.00

_live400.js:168 通过 / 0 失败。引用块背景、左侧色条、右引号零高、暗色、无横向溢出全部确认。

像素:引号墨迹真的在缩进空白里

这一层必须单独量,因为盒和墨迹不是一回事。

视口 缩进空白 左引号墨迹 首字起点
390 6 ~ 30 8.0 ~ 27.5 30.0
768 6 ~ 30 8.0 ~ 28.0 30.0
992 6 ~ 32 10.5 ~ 30.5 32.0
1440 6 ~ 32 10.0 ~ 29.5 32.0
1920 6 ~ 32 10.0 ~ 29.5 32.0

墨迹 20×16,比正文汉字(15×15)略大,达成「放大做装饰」;不压左侧色条;不越右界。
暗色众数 rgb(61, 75, 88) = #3d4b58,零个残留亮色像素。
有/无引号两张图尺寸完全相同 ⇒ 块高没被撑大。

_livepix400.py:76 通过 / 0 失败。

两处我自己判据写错、当场纠正的地方

① 版本号靶子选错。 第一版用 /style|kratos_yang/ 匹配 <link> 的 href,
结果抓到 id='bootstrap-css' 的 ?ver=4.5.0,报「线上不是 4.0.0」——假红。
正确的靶子是 link#kratos-site-css(ver=4.0.0)。又一次「判据选错靶子」。
另外也确认了:bootstrap 4.5.0、iconfont 4.0.0、layer 3.1.1、animate 3.7.2
是各自库的版本号,和主题版本无关,别拿它们判断主题版本。

② 用盒宽去比首字,必然假红。 第一版写了
盒右沿 = 块左 + border + left + font-size(60px) ≤ 首字起点,
全线报红(113 ≤ 77、135 ≤ 99)。
原因就是这次最核心那个发现:绝对定位伪元素没写 width 时,盒宽 = 字形 advance = 1em = 60px,
而引号墨迹只有 20px 宽。
浏览器没有任何 API 能给伪元素的墨迹框。
这条我删掉了,换成像素差分,并留了一条盒子层面的弱检查(left ∈ [0,8])。

最终判据清单(本地 + 线上两层)

层 判据 结果
本地 CSS _geom32.js 48 / 0
本地像素 _pix400.py 76 / 0
打包 _mkzip400.py 61 / 0
反证 _mkzip400_falsify.py 20 / 0(18 组注入)
反证 _pix400_falsify.py 8 / 0(5 组注入)
文档 _readme400.py 36 / 0
线上几何 _live400.js 168 / 0
线上像素 _livepix400.py 76 / 0

关单。

## 线上验收通过,关单 你在 12:37 升级到 4.0.0 了。我刚在线上量完,**不拦截 CSS、直接量真实渲染**。 ### 几何:三篇文章 × 五视口,全对齐 | 视口 | 引用文字起点 | 正文文字起点 | 差 | |---|---|---|---| | 390 | 77.0 | 77.0 | **0.00** | | 768 | 80.2 | 80.2 | **0.00** | | 992 | 87.8 | 87.8 | **0.00** | | 1440 | 99.0 | 99.0 | **0.00** | | 1920 | 303.0 | 303.0 | **0.00** | `_live400.js`:**168 通过 / 0 失败**。引用块背景、左侧色条、右引号零高、暗色、无横向溢出全部确认。 ### 像素:引号墨迹真的在缩进空白里 这一层必须单独量,因为盒和墨迹不是一回事。 | 视口 | 缩进空白 | 左引号墨迹 | 首字起点 | |---|---|---|---| | 390 | 6 ~ 30 | **8.0 ~ 27.5** | 30.0 | | 768 | 6 ~ 30 | **8.0 ~ 28.0** | 30.0 | | 992 | 6 ~ 32 | **10.5 ~ 30.5** | 32.0 | | 1440 | 6 ~ 32 | **10.0 ~ 29.5** | 32.0 | | 1920 | 6 ~ 32 | **10.0 ~ 29.5** | 32.0 | 墨迹 20×16,比正文汉字(15×15)略大,达成「放大做装饰」;不压左侧色条;不越右界。 暗色众数 `rgb(61, 75, 88)` = `#3d4b58`,零个残留亮色像素。 有/无引号两张图尺寸完全相同 ⇒ 块高没被撑大。 `_livepix400.py`:**76 通过 / 0 失败**。 ### 两处我自己判据写错、当场纠正的地方 **① 版本号靶子选错。** 第一版用 `/style|kratos_yang/` 匹配 `<link>` 的 href, 结果抓到 `id='bootstrap-css'` 的 `?ver=4.5.0`,报「线上不是 4.0.0」——假红。 正确的靶子是 `link#kratos-site-css`(`ver=4.0.0`)。又一次「判据选错靶子」。 另外也确认了:`bootstrap 4.5.0`、`iconfont 4.0.0`、`layer 3.1.1`、`animate 3.7.2` 是各自库的版本号,和主题版本无关,别拿它们判断主题版本。 **② 用盒宽去比首字,必然假红。** 第一版写了 `盒右沿 = 块左 + border + left + font-size(60px) ≤ 首字起点`, 全线报红(113 ≤ 77、135 ≤ 99)。 原因就是这次最核心那个发现:**绝对定位伪元素没写 width 时,盒宽 = 字形 advance = 1em = 60px, 而引号墨迹只有 20px 宽。** 浏览器没有任何 API 能给伪元素的墨迹框。 这条我删掉了,换成像素差分,并留了一条盒子层面的弱检查(`left ∈ [0,8]`)。 ### 最终判据清单(本地 + 线上两层) | 层 | 判据 | 结果 | |---|---|---| | 本地 CSS | `_geom32.js` | 48 / 0 | | 本地像素 | `_pix400.py` | 76 / 0 | | 打包 | `_mkzip400.py` | 61 / 0 | | 反证 | `_mkzip400_falsify.py` | 20 / 0(18 组注入) | | 反证 | `_pix400_falsify.py` | 8 / 0(5 组注入) | | 文档 | `_readme400.py` | 36 / 0 | | **线上几何** | `_live400.js` | **168 / 0** | | **线上像素** | `_livepix400.py` | **76 / 0** | 关单。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: laoyang/wordpress-kratos-yang#32