CSS Handbook · 现代布局特性

第九章 / 9.2 scroll-snap 与滚动行为

第九章 · 9.2 节

scroll-snap 与滚动行为


"滑动到某张卡片会自动对齐"这类交互,过去只能靠 JavaScript 监听滚动事件手动计算实现。CSS 滚动捕捉(Scroll Snap)把这类效果变成了纯 CSS 方案,性能更好,也天然支持触摸滑动手势。

scroll-snap 基础三件套

属性作用对象说明
scroll-snap-type滚动容器开启捕捉,指定轴向与强制程度
scroll-snap-align子项该子项对齐容器的哪个边缘
scroll-snap-stop子项是否强制每次只能停留一个子项,禁止快速滑动跳过
.container {
  overflow-x: auto;
  scroll-snap-type: x mandatory; /* x 轴,mandatory 强制吸附 */
}
.item {
  scroll-snap-align: center;
}

scroll-snap-type 的第二个参数决定"强制程度":mandatory 滚动停止后必定吸附到最近的捕捉点;proximity 仅在离捕捉点足够近时才吸附,否则停在原地,体验更"自由"。

scroll-snap-type: x mandatory(可横向滑动)
1
2
3
4

这与 6.3 Flexbox 详解 中的横向布局结合,是移动端"卡片轮播"最轻量的实现方式,无需引入任何 JS 轮播库。

整屏滚动示例

html {
  scroll-snap-type: y mandatory;
}
section {
  height: 100vh;
  scroll-snap-align: start;
}

这是纯 CSS 实现"整屏切换"落地页效果的核心代码,每个 section 占满一屏,滚动时自动吸附对齐到顶部。

scroll-behavior 平滑滚动

点击锚点链接或调用 scrollIntoView() 时,默认是瞬间跳转。scroll-behavior: smooth 让这个过程变成平滑动画,同样无需 JavaScript。

html {
  scroll-behavior: smooth;
}

scroll-margin 与锚点偏移

页面存在固定定位的顶部导航栏时,直接跳转锚点会导致目标区域被导航栏遮住一部分。scroll-margin-top 可以为锚点滚动预留出这段偏移,而不影响元素本身的布局。

h2[id] {
  scroll-margin-top: 72px; /* 等于固定导航栏的高度 */
}

常见误区

  • 设置了 scroll-snap-type 却忘记容器需要有 overflow: auto/scroll 才能真正产生可滚动区域。
  • 整屏滚动场景中,子项高度不是 100vh 或存在外边距,导致捕捉位置出现细微偏差。
  • 只关注 scroll-behavior: smooth 而忽视了它对"辅助功能用户"可能造成的眩晕感,建议配合 prefers-reduced-motion 媒体特性关闭平滑滚动(详见 5.2 常用媒体特性)。