
通过为每组网格项包裹独立容器(如 section),可使 sticky 元素仅在父容器视口内生效,从而避免多列 sticky 冲突,实现“当前行侧边栏吸附、下一行到达时自动释放”的效果。
通过为每组网格项包裹独立容器(如 section),可使 sticky 元素仅在父容器视口内生效,从而避免多列 sticky 冲突,实现“当前行侧边栏吸附、下一行到达时自动释放”的效果。
在 CSS Grid 布局中实现“按行吸附”的侧边栏(sticky sidebar),关键在于理解 position: sticky 的作用机制:它并非全局固定于视口,而是相对于其最近的、具有滚动约束的祖先容器(即“sticky containment block”)生效。当多个 .sidebar 直接平铺在同一个 .grid 容器中时,它们共享同一滚动上下文(即整个 grid 容器),导致所有 sticky 元素都试图锚定在视口顶部,最终相互重叠。
✅ 正确解法是:为每一组“侧边栏 + 内容”配对创建独立的滚动上下文容器(如
以下是推荐的结构与样式实现:
<section class="grid-row"><div class="sidebar">
<h1>I want this div to be attached to the top of the screen while the row next to it is being scrolled through</h1>
</div>
<div class="content">
<p>There is a lot of content here</p>
<p>Stretching the entire height of the screen</p>
<!-- 更多内容... -->
</div>
</section><section class="grid-row"><div class="sidebar">
<h1>But when this row reaches the top, this overlaps with the first sidebar</h1>
</div>
<div class="content">
<p>There is a lot of content here</p>
<p>Stretching the entire height of the screen</p>
<!-- 更多内容... -->
</div>
</section>
.grid-row {
display: grid;
grid-template-columns: 25vw 75vw;
gap: 0; /* 避免 section 间额外间距干扰 sticky 行为 */
margin-bottom: 2rem;
}
.sidebar {
border-right: 1px solid lightgray;
border-left: 10px solid lightgray;
position: sticky;
top: 0;
background: #fff; /* 防止文字穿透重叠 */
padding: 1.5rem;
/* 可选:提升层级避免被后续内容遮挡 */
z-index: 10;
}
.content {
padding: 1.5rem;
min-height: 60vh; /* 确保内容足够高以触发 sticky 效果 */
}
⚠️ 注意事项:
- 不要给 .grid-row 设置 overflow: hidden 或 clip-path 等裁剪属性,否则会截断 sticky 元素的渲染;
- min-height 建议设为 60vh 或更高,确保内容区高度足以让 sticky 效果有“滚动空间”;
- 若需响应式适配,可用 clamp() 替代固定 vw 单位,例如 grid-template-columns: clamp(280px, 25%, 320px) 1fr;;
- 所有 .sidebar 必须位于各自 .grid-row 的第一个子元素位置(CSS 规范要求 sticky 元素需在文档流中处于可计算位置)。
? 总结:纯 CSS 即可实现该交互——无需 JavaScript。核心原理是利用 position: sticky 的“局部粘性”特性,通过语义化分组(










