第九章 · 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 常用媒体特性)。