问题现象
博客在手机端打开 Day 5 这类文章时,中文文字出现了逐字分行的问题:
创 建 N A T 网 关明明一行能显示的文字,被拆成了一个个单字,视觉上完全无法阅读。
第一反应:CSS 问题
以为是 word-break 或 white-space 的锅。用 MobaXterm 连上服务器,先把 CSS 文件拉下来看:
scp root@***.uuworld.cn:/var/www/blog/static/css/tech.css .
找到好几处 word-break: break-word,这个属性在手机端会让浏览器在任意字符之间断行——而中文没有空格,浏览器就把每个字都当成了合法断点,自然就逐字分行显示。
修改方案:把涉及中文内容的 word-break: break-word 全部改成 word-break: normal,让中文按自然语意换行。
同步回服务器,重建 Hugo:
scp tech.css root@***.uuworld.cn:/var/www/blog/static/css/tech.css
ssh root@***.uuworld.cn "cd /var/www/blog && hugo"
验证 CSS 是否更新:
curl https://***.uuworld.cn/css/tech.css | grep 'word-break'
结果:CSS 已生效。但刷新手机端,问题依旧。
深入:HTML 里藏了什么
CSS 修改了但没效果,怀疑 HTML 本身就有问题。用 curl 抓页面看:
curl http://***.uuworld.cn/acp/acp-day-05-acp-day-5-vpc-nat/ | grep -A5 '典型实验流程'
输出里发现了这个:
<div class="goat svg-container ">
<svg xmlns="http://www.w3.org/2000/svg" font-family="Menlo,Lucida Console,monospace" viewBox="0 0 192 201">
<g transform='translate(8,16)'>
<text text-anchor='middle' x='0' y='4' fill='currentColor' style='font-size:1em'>系</text>
<text text-anchor='middle' x='0' y='20' fill='currentColor' style='font-size:1em'>├</text>
<text text-anchor='middle' x='0' y='36' fill='currentColor' style='font-size:1em'>├</text>
问题找到了!Hugo 生成的 HTML 里,代码块被转成了 SVG 图形,每个字符都是独立的 <text> 元素。手机端 SVG 无法正确缩放,浏览器就把每个字符当成独立行来渲染。
根因定位:Hugo 内置 goat 库
Hugo 二进制文件里内置了 goat 库:
strings /usr/local/bin/hugo | grep -i 'goat'
Hugo v0.146.0 extended 版本的代码块渲染逻辑里,藏着一个内置模板 embedded/templates/_markup/render-codeblock-goat.html。这个模板会自动检测代码块里的树形图字符(├── └─ │),然后把它们转成 SVG 图形。
Day 5 文章里有这段代码块:
系统路由表 ├── 创建VPC后自动生成 ├── 不可删除、不可手动创建 └── 可添加自定义路由条目Hugo 检测到 ├── 和 └── 字符,触发 goat 转换,生成了 SVG 而不是普通代码块。
解决方案:覆盖 Hugo 内置模板
Hugo 的 render hook 机制支持自定义覆盖。只需在项目 layouts 目录下创建同名模板:
mkdir -p /var/www/blog/layouts/_default/_markup
cat > /var/www/blog/layouts/_default/_markup/render-codeblock-goat.html << 'EOF'
{{- .Inner -}}
EOF
这个空模板只输出原始文本内容,覆盖了 Hugo 内置的 SVG 生成逻辑。
同时,把 markdown 里的树形图字符也替换成普通列表格式,彻底消除触发条件:
系统路由表 - 创建VPC后自动生成 - 不可删除、不可手动创建 - 可添加自定义路由条目重建验证:
cd /var/www/blog && hugo
curl http://***.uuworld.cn/acp/acp-day-05-acp-day-5-vpc-nat/ | grep -c 'svg-container'
# 输出: 0
经验总结
| 阶段 | 动作 | 结果 |
|---|---|---|
| 第一反应 | 修改 CSS word-break | CSS 生效但问题依旧 |
| 深入排查 | curl 查看 HTML | 发现 SVG 标签 |
| 根因定位 | strings 检查 Hugo binary | 发现内置 goat 库 |
| 解决方案 | 创建 render-codeblock-goat.html 覆盖 | 0 个 SVG,问题解决 |
Hugo extended 版本内置了很多额外功能(SCSS/SASS 渲染、goat SVG 等),这些功能在配置文件里完全看不到,但会影响页面输出。遇到类似"改了 CSS 没效果"的问题,记得直接查 HTML 源码,很可能是生成阶段就已经出错了。
相关文件
/var/www/blog/layouts/_default/_markup/render-codeblock-goat.html— 空模板,覆盖内置 goat 转换/var/www/blog/static/css/tech.css— 手机端 CSS 优化(word-break: normal)