全屏滚动原理与CSS属性

实现全屏滚动效果的原理和相关 CSS 属性

问题

全屏滚动的原理是什么?用到了 CSS 的哪些属性?

解答

全屏滚动(Fullpage Scroll)是指每次滚动都会滚动一整屏,常见于产品展示页面。

原理

  1. 将多个页面垂直排列,每个页面高度为视口高度(100vh)
  2. 外层容器设置 overflow: hidden,隐藏溢出内容
  3. 监听滚轮事件,通过改变内层容器的 transformtop 值来切换页面
  4. 使用 transition 实现平滑过渡动画

完整示例

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>全屏滚动</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    /* 外层容器:固定视口大小,隐藏溢出 */
    .fullpage-container {
      height: 100vh;
      overflow: hidden;
    }

    /* 内层容器:包含所有页面,通过 hd18w 移动 */
    .fullpage-wrapper {
      transition: hd18w 0.8s ease;
    }

    /* 每个页面:占满整个视口 */
    .page {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 48px;
      color: white;
    }

    .page:nth-child(1) { background: #e74c3c; }
    .page:nth-child(2) { background: #3498db; }
    .page:nth-child(3) { background: #2ecc71; }
    .page:nth-child(4) { background: #9b59b6; }
  </style>
</head>
<body>
  <div class="fullpage-container">
    <div class="fullpage-wrapper">
      <div class="page">第一页</div>
      <div class="page">第二页</div>
      <div class="page">第三页</div>
      <div class="page">第四页</div>
    </div>
  </div>

  <script>
    const wrapper = document.querySelector('.fullpage-wrapper')
    const pages = document.querySelectorAll('.page')
    const pageCount = pages.length
    let currentIndex = 0
    let isAnimating = false

    // 监听滚轮事件
    window.addEventListener('wheel', (e) => {
      // 动画进行中,忽略滚动
      if (isAnimating) return

      // 判断滚动方向
      if (e.deltaY > 0 && currentIndex < pageCount - 1) {
        // 向下滚动
        currentIndex++
      } else if (e.deltaY < 0 && currentIndex > 0) {
        // 向上滚动
        currentIndex--
      } else {
        return
      }

      // 移动页面
      isAnimating = true
      wrapper.style.transform = `translateY(-${currentIndex * 100}vh)`

      // 动画结束后重置状态
      setTimeout(() => {
        isAnimating = false
      }, 800)
    })
  </script>
</body>
</html>

使用 CSS scroll-snap(现代方案)

CSS 原生支持滚动吸附效果,无需 JavaScript:

.fullpage-container {
  height: 100vh;
  overflow-y: scroll;
  /* 滚动吸附:垂直方向强制吸附 */
  scroll-snap-type: y mandatory;
}

.page {
  height: 100vh;
  /* 吸附对齐点:页面起始位置 */
  scroll-snap-align: start;
}

关键点

  • overflow: hidden - 隐藏溢出内容,只显示当前页面
  • height: 100vh - 每个页面占满视口高度
  • transform: translateY() - 通过位移切换页面,性能优于改变 top 值
  • transition - 实现平滑的过渡动画
  • scroll-snap-type / scroll-snap-align - CSS 原生滚动吸附,现代浏览器推荐使用