跳到正文

阅读进度条

Reading Progress Bar

初级通用

长文章顶部一条细细的彩色线,随着往下读逐渐变长,读到底正好满格;也可以做成角落里的一个小圆环加百分比。读者一眼就知道还剩多少,更愿意读完。

你可能会说:「长文章能不能在顶部加一条进度条,读到哪里就显示到哪里?」

效果预览

正在加载演示…

怎么做

  1. 1

    一条固定在顶部的细线

    进度条固定在页面最上方,用 transform: scaleX 控制长度,从左边开始伸长。用缩放而不是改宽度,滚动时不会触发重新排版。

    查看代码html
    <div class="read-progress" role="progressbar" aria-label="阅读进度"
         aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
      <div class="read-progress__bar"></div>
    </div>
    
    <style>
      .read-progress { position: fixed; inset: 0 0 auto 0; height: 3px; z-index: 60; }
      .read-progress__bar {
        height: 100%;
        background: linear-gradient(90deg, #6366f1, #ec4899);
        transform: scaleX(0);
        transform-origin: left;
      }
    </style>
  2. 2

    进度 = 已滚动 ÷ 可滚动总距离

    可滚动的总距离是页面总高度减去窗口高度,不是页面总高度,否则读到底也到不了 100%。如果只想计算文章区域,就用文章的位置和高度来算。

    查看代码js
    const box = document.querySelector('.read-progress');
    const bar = box.querySelector('.read-progress__bar');
    
    function update() {
      const max = document.documentElement.scrollHeight - window.innerHeight;
      const progress = max > 0 ? Math.min(1, window.scrollY / max) : 0;
      bar.style.transform = `scaleX(${progress})`;
      box.setAttribute('aria-valuenow', Math.round(progress * 100));
    }
    
    window.addEventListener('scroll', update, { passive: true });
    window.addEventListener('resize', update);
    update();
  3. 3

    新浏览器可以只用 CSS

    支持滚动驱动动画的浏览器,可以完全不写脚本:把一个从 0 到 1 的缩放动画绑定到页面滚动上。不支持的浏览器会退回上面的脚本方案,所以两种可以同时保留。

    查看代码css
    @supports (animation-timeline: scroll()) {
      .read-progress__bar {
        animation: grow linear both;
        animation-timeline: scroll(root);
      }
      @keyframes grow {
        from { transform: scaleX(0); }
        to   { transform: scaleX(1); }
      }
    }

适合放在哪

适合用

  • 博客、教程、长篇报道等阅读页。
  • 文档页,配合目录让读者知道读到哪里了。
  • 长表单或分步流程,用进度提示还剩多少(这时按步骤算,而不是按滚动算)。

不适合用

  • 页面很短、一屏就能看完时,进度条没意义。
  • 无限滚动的信息流别加;内容没有尽头,进度永远到不了 100%。
  • 页面顶部已经有加载进度条时,别再叠一条,读者会分不清。

让 AI 帮你做

请给【长文阅读页,如:博客文章详情页】加上阅读进度条。先阅读文章页的组件结构,确认滚动发生在 window 还是某个容器,以及顶部导航栏的高度和层级。要求:进度条固定在页面顶部(或导航栏下方),3px 左右,用 transform: scaleX 表示进度;进度 = 已滚动距离 ÷(内容总高度 − 可视高度),读到底正好 100%;滚动监听用 passive,窗口大小变化时重新计算;支持 animation-timeline 的浏览器优先用纯 CSS;提供 role=progressbar 和 aria-valuenow。只在文章页显示,不改无关代码。最后说明怎样验证:读到底时进度条正好满格。

用到的知识