如何用纯CSS实现Grid布局中目录固定、右侧文章可滚动的效果
纯CSS实现固定目录布局方案
核心思路
利用CSS Grid划分页面区域,结合position: sticky实现目录在顶部主header滚动消失后固定,同时通过Grid轨道的最小宽度设置避免内容覆盖目录,全程无需JavaScript。
完整代码示例
HTML结构
<div class="page-container"> <!-- 顶部滚动消失的header --> <header class="header-main"> <h1>灰色顶部Header</h1> <p>滚动页面时我会消失</p> </header> <!-- 固定在顶部的次级header --> <header class="header-sticky"> <nav>黄色固定导航Header</nav> </header> <!-- 主内容区域:包含目录和文章 --> <div class="main-content"> <aside class="toc"> <h3>目录</h3> <ul> <li><a href="#sec1">章节1</a></li> <li><a href="#sec2">章节2</a></li> <li><a href="#sec3">章节3</a></li> <li><a href="#sec4">章节4</a></li> </ul> </aside> <main class="article-content"> <section id="sec1"> <h2>章节1</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> <p>...</p> <!-- 填充足够多内容模拟滚动 --> </section> <section id="sec2"><h2>章节2</h2><p>...</p></section> <section id="sec3"><h2>章节3</h2><p>...</p></section> <section id="sec4"><h2>章节4</h2><p>...</p></section> </main> </div> </div>
CSS样式
/* 重置默认样式 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { line-height: 1.6; } /* 页面主容器Grid布局 */ .page-container { display: grid; grid-template-rows: auto auto 1fr; min-height: 100vh; } /* 顶部滚动header:跨所有列 */ .header-main { grid-column: 1 / -1; background: #eee; padding: 2rem; } /* 固定次级header:跨所有列,sticky定位 */ .header-sticky { grid-column: 1 / -1; position: sticky; top: 0; background: #ffd700; padding: 1rem; z-index: 10; /* 确保在目录上方 */ min-height: 60px; /* 固定高度方便目录定位,自适应高度可删除此属性 */ } /* 主内容区域:内部嵌套Grid划分目录和文章 */ .main-content { display: grid; /* 目录列最小280px,最大占25%宽度;文章列占剩余空间 */ grid-template-columns: minmax(280px, 25%) 1fr; gap: 2rem; /* 目录和文章之间的间距 */ padding: 1rem; } /* 目录:sticky定位,top值等于次级header的高度 */ .toc { position: sticky; top: 60px; /* 与.header-sticky的min-height保持一致 */ align-self: start; /* 关键:避免Grid拉伸目录高度,保持内容高度 */ background: #f5f5f5; padding: 1.5rem; border-radius: 4px; height: fit-content; /* 目录高度随内容自适应 */ } /* 文章内容区 */ .article-content { max-width: 800px; /* 限制文章宽度,提升可读性 */ } /* 小屏幕适配:改为单列布局 */ @media (max-width: 768px) { .main-content { grid-template-columns: 1fr; } .toc { top: 60px; /* 依然固定在次级header下方 */ margin-bottom: 1rem; } }
关键细节说明
解决目录上方空白问题:
- 目录使用
position: sticky而非fixed,保持在Grid文档流中,跟随顶部主header滚动,直到其顶部到达次级固定header的底部(通过top: 60px精准控制,数值匹配次级header高度),此时自动固定。 - 配合
align-self: start和height: fit-content,确保目录高度随内容自适应,不会被Grid拉伸导致多余空白。
- 目录使用
解决窗口窄时内容覆盖目录问题:
- 主内容区的Grid列设置为
minmax(280px, 25%),强制目录列最小宽度为280px,避免被文章内容挤压。 - 添加媒体查询,在小屏幕(768px以下)自动切换为单列布局,目录固定在次级header下方,不会被文章覆盖。
- 主内容区的Grid列设置为
自适应高度兼容:
- 如果次级header是自适应高度(无固定min-height),可将目录的
top值改为top: 100%,同时调整结构,将次级header和主内容区放在同一个Grid行内,利用Grid的行高自动计算顶部偏移量。
- 如果次级header是自适应高度(无固定min-height),可将目录的
内容的提问来源于stack exchange,提问作者user18490
相关产品推荐
相关产品推荐

