
本文介绍如何仅用纯 CSS 实现双列粘性滚动的“异步停止”行为:红列(内容较短)滚动至底部后固定,蓝列(内容较长)继续滚动直至自身内容结束。核心在于将 sticky 定位从 top: 0 改为 bottom: 0 并配合 margin-top: auto 触发反向对齐。
本文介绍如何仅用纯 css 实现双列粘性滚动的“异步停止”行为:红列(内容较短)滚动至底部后固定,蓝列(内容较长)继续滚动直至自身内容结束。核心在于将 sticky 定位从 `top: 0` 改为 `bottom: 0` 并配合 `margin-top: auto` 触发反向对齐。
要实现题述的“同步起始、差异终止”滚动行为——即两列同时开始滚动,但红列(短列)先触底冻结,蓝列(长列)继续滚动直至自身内容结束——关键在于反转粘性锚点方向,而非依赖 top: 0 的常规顶部吸附。
✅ 正确解法:bottom: 0 + margin-top: auto
CSS 中 position: sticky 的行为取决于其“粘性边界”:
-
top: 0表示元素在视口顶部到达时开始粘住; -
bottom: 0则表示元素在视口底部即将离开时才开始粘住——这恰好让内容“从下往上”被拉入视野,并在触达容器底部时锁定。
配合 margin-top: auto(在 Flex 容器中触发自动外边距分配),可将 .col 内容整体“推至容器底部”,使其初始渲染位置处于底部对齐状态。此时滚动时,元素会像被“向上拖拽”一样逐步显现,一旦其底部与容器底部对齐,bottom: 0 即生效,实现“触底即停”。
以下是精简有效的 CSS 方案:
.container {
display: flex;
justify-content: space-around;
align-items: flex-start; /* 注意:此处保持 flex-start 不影响 bottom-sticky */
border: 2px dashed rgba(114, 186, 94, 0.35);
background: rgba(114, 186, 94, 0.05);
height: 100vh; /* 推荐设高度,确保滚动上下文明确 */
overflow-y: auto; /* 确保容器可滚动(若需全局滚动,可省略) */
}
.col {
margin-top: auto; /* 关键:将列内容压至容器底部 */
position: sticky;
bottom: 0; /* 关键:粘性锚点改为底部 */
}
.col div {
height: 250px;
width: 250px;
border: 2px dashed rgba(255, 186, 94, 0.35);
margin-bottom: 20px;
}
.col div:nth-child(2n) {
opacity: 0.5;
}
.col1 div { background-color: red; }
.col2 div { background-color: blue; }? 使用注意事项
-
容器高度必须明确:
.container建议设置height(如100vh)或确保其父容器提供足够滚动上下文,否则sticky可能失效; -
不要混用
top和bottom:同一元素不可同时声明top与bottom,否则bottom优先级更高,但语义冲突易引发不可预期行为; -
内容长度决定停止时机:红列(
.col1)因子元素较少,会更早达到“底部对齐”状态而停止;蓝列(.col2)因内容更多,在红列冻结后仍持续上滑,直到其最后一个子元素底部与容器底部对齐; -
兼容性提示:
position: sticky在现代浏览器中支持良好(Chrome 56+、Firefox 59+、Safari 15.4+),但不支持 IE。
✅ 效果验证逻辑
- 初始状态下,两列内容均位于容器底部(视觉上可能被截断);
- 向下滚动 → 内容“向上浮现”,两列同步移动;
- 当红列最后一个
<div> 底部抵达容器底部时,<code>bottom: 0生效 → 红列冻结; - 继续滚动 → 仅蓝列继续上移,直至其自身内容全部展示完毕。
该方案完全基于原生 CSS,无需 JavaScript,语义清晰、性能优异,是实现“差异化粘性滚动”的优雅解法。

















