一次 Header 宽度幽灵问题的完整排查
· 更新于
记录今天如何定位并修复 Header 右侧漏底、TOC 错位与容器宽度联动回归问题。
今天花了很长时间处理一个看起来“很玄学”的 UI 问题:
- 在某个宽度附近(大约 778px)开始出现
- Header 右侧会露出一块区域,能看到正文内容“透出来”
- 改一个地方会牵出一串回归:横向滚动条、TOC 位置异常、宽屏布局不同步
这篇文章按时间线整理:问题现象 → 错误假设 → 根因确认 → 最终修复。
现象复盘
最初看到的是:Header 背景没有覆盖满可见区域,右侧有一条漏底区域。
后来又发现几个关联现象:
- TOC 在宽屏时有时跑到正文上层或位置不稳定
- 窄屏时 TOC 隐藏行为异常(看起来像媒体查询失效)
- Header 原本“宽屏更宽、滚动后收缩到正文宽度”的过渡有时失效
这些问题看起来互不相关,但实际上都与“容器宽度计算是否一致”有关。
先踩过的坑(错误方向)
1) 只盯 site-header 背景色
我们一开始把精力集中在颜色本身,比如 bg-[Canvas]、显式颜色、系统色等。
这只解决了“看起来是什么颜色”,但没有解决“为什么右侧会漏出”。
2) 直接把 Header 改成 100vw
100vw 确实能强行覆盖右侧槽位,但很容易引入副作用:
- 在某些情况下出现横向滚动条
- 与居中容器计算叠加后,定位补偿更复杂
3) 在 global.css 到处补丁
把局部问题全靠全局补丁压住,短期可见“好了”,长期会出现更多联动回归。
真正的根因
关键点是这句:
site-header-inner: w-full + px-4
如果是默认 content-box 盒模型,那么:
w-full只计算内容盒px-4会额外再加宽度- 内层可能比外层更宽,导致视觉上出现“漏底/不对齐”
同样的问题也会出现在 main、footer:只要是 w-full + padding,就需要统一盒模型策略。
最终修复策略
1) 所有关键容器统一 box-border
核心容器统一成“padding 算进宽度里”:
site-header-innermainfooter
这样 w-full 才不会因为 padding 导致实际渲染宽度溢出。
2) 容器变量与实际宽度保持同一语义
为了保持“视觉内容宽度”不变,同时使用 box-border,把容器变量改成包含两侧 padding:
:root {
--site-container-wide: calc(72ch + 2rem);
--site-container-prose: calc(65ch + 2rem);
}
这保证了:
- Header 宽屏状态与 footer 宽度仍对齐
- Header 滚动收缩目标与正文主列仍对齐
- TOC 偏移公式可继续基于统一变量计算
3) TOC 偏移公式改为变量驱动
把 TOC 的 left 改成使用 --site-container-prose:
left: calc(50% + var(--site-container-prose) / 2 + 2rem);
避免“正文宽度改了但 TOC 公式还写死旧值”的错位。
这次排查的经验
- 先确认几何问题,再谈颜色问题:先看谁更宽、谁溢出。
- 容器系统要一致:
header/main/footer不能各用一套宽度语义。 - 变量要代表真实布局语义:变量名和实际计算含义必须一致。
- 回归往往来自联动:一个宽度修复可能影响 TOC、动画、响应式行为。
小结
这次不是“某一行 CSS 写错了”这么简单,而是典型的布局体系一致性问题:
- 盒模型
- 容器宽度变量
- 定位公式
- 响应式规则
只修一个点,通常会在别处反弹;把整条链路统一之后,问题才会真正稳定。
如果你也碰到“看起来像随机出现”的前端 bug,可以按这个顺序排:
盒模型 → 宽度来源 → 溢出路径 → 定位公式 → 响应式边界。