回到列表
问题修复
CSS布局修复

修复文档和博客页面侧边栏滚动问题

解决文档页左侧导航、右侧目录以及博客详情页目录在页面滚动时跟随正文移动的问题,通过精准计算 CSS sticky top 值与 display: contents 布局扁平化消除视觉偏移。

Claude Opus 4.6Claude Opus 4.6· AI Copilot

问题描述

BDI 官网的文档页面和博客详情页存在侧边栏滚动异常的问题:

  1. 文档页左侧导航在正文滚动时会向上移动约 32px 后才固定
  2. 文档页右侧目录嵌套在内容区域的 flex 容器中,sticky 定位受嵌套层级影响
  3. **博客详情页的"本页目录"**会随正文滚动,且固定位置在页面顶部导航栏后方,导致目录标题不可见

根因分析

CSS Sticky 的工作机制

position: sticky 的行为是:元素在正常文档流中渲染,当滚动使元素距离视口顶部达到 top 阈值时,元素"粘住"不再移动。

关键公式:

滚动距离 = 初始位置 − sticky top 值

如果 sticky top 值 小于 元素的初始位置,元素会先向上滚动一段距离再固定。

文档页右侧目录的嵌套问题

文档页的关键困难在于右侧目录嵌套层级过深。布局结构如下:

层级元素说明
1外层 flexlayout.tsx 的主容器
2左侧 aside与外层 flex 同级,sticky 直接生效
2content-div包裹 page.tsx 输出的容器
3内层 flexpage.tsx 的 flex 容器
4右侧 aside嵌套在 content-div 和内层 flex 之中

左侧导航栏是外层 flex 的直接子元素,sticky 行为直接有效;而右侧目录嵌套了两层包装 div,可能在嵌套布局中出现微妙的定位偏差。

博客页的具体问题

项目
原 sticky top 值top-8 = 2rem = 32px
页面顶部导航栏高度64px
结果目录固定在导航栏后方,不可见

修复方案

核心原则

移除容器顶部内边距,精确匹配 header 高度设置 sticky top,使用 display: contents 扁平化嵌套层级。

文档页修复

涉及文件:

  • app/[locale]/docs/layout.tsx
  • app/[locale]/docs/[[...mdxPath]]/page.tsx

核心改动:

  1. 容器移除顶部内边距,改为 pb-8 lg:pb-12
  2. 内容区和侧边栏内部各自添加 pt-8 lg:pt-12 实现视觉对齐
  3. sticky top 设为 top-16.25 = 65px(header h-16 + border-b 1px)
  4. 关键修复:content-div 添加 xl:contents,page.tsx 内层 flex 添加 xl:contents

xl:contents 使包装元素在 xl 断点以上(右侧目录可见时)变为 display: contents,其子元素直接成为外层 flex 的子元素,右侧目录与左侧导航处于同一嵌套层级,sticky 行为完全一致。

博客页修复

涉及文件: app/[locale]/blog/[slug]/page.tsx

将原 Grid 布局重构为 Flex 布局:

  1. TOC 从 Grid 的第二列提升为 Flex 的独立子元素
  2. sticky top 设为 top-16.25 = 65px,与 header 完全匹配
  3. 移除 self-start,采用内层 div 承载 sticky 行为

SQLite 警告抑制

涉及文件: .npmrc(新建)

构建和开发时 node:sqlite(实验性 API)会输出 ExperimentalWarning。通过在 .npmrc 中设置 node-options=--disable-warning=ExperimentalWarning,利用 Node.js 原生机制在所有进程(包括构建 worker)中统一抑制。

修改文件一览

文件修改内容
app/[locale]/docs/layout.tsx重构 padding,sidebar sticky top,content-div 添加 xl:contents
app/[locale]/docs/[[...mdxPath]]/page.tsxTOC sticky top,内层 flex 添加 xl:contents
app/[locale]/blog/[slug]/page.tsxGrid 转 Flex 布局,TOC sticky top
.npmrcnode-options=--disable-warning=ExperimentalWarning
next.config.ts移除 SQLite monkey-patch(改用 .npmrc)

验证结果

  • pnpm check 通过,72 个文件无需修复
  • pnpm build 编译成功,28 个页面生成正常,SQLite 警告消失
  • 开发服务器终端无 ExperimentalWarning 输出

总结

本次修复的两个核心技术要点:

  1. CSS position: sticky 的精确计算:sticky 元素的初始位置必须等于 top 阈值才能实现零偏移。将 top 设为 top-16.25(= 65px = h-16 + border-b),与 header 高度精确匹配。

  2. display: contents 消除嵌套影响:当 sticky 元素嵌套在多层 flex 容器中时,使用 xl:contents 在目标断点扁平化 DOM 层级,让右侧目录和左侧导航成为同一 flex 容器的直接子元素,确保 sticky 行为完全一致。


  • 版本: 2.0.0
  • 时间: 2026-02-19 14:30:00
  • 作者: Claude Opus 4.6
  • 简介: 第二版修复,重构容器 padding 和布局结构,将 sticky top 精确匹配 header 高度以消除所有视觉偏移