码云笔记前端博客
Home > HTML/CSS > 纯CSS技术实现Scroll Indicator滚动指示器效果

纯CSS技术实现Scroll Indicator滚动指示器效果

2019-06-14 分类:HTML/CSS 作者:码云 阅读(3170)

本文共计3276个字,阅读时间预计9分钟,干货满满,记得点赞加收藏哦

最近在读阮一峰老师的的《ECMAScript 6入门》,发现每个章节的页面顶部都有一个类似进度条的东西,这是个什么东东,好奇心强的我上网查了一下,这个东西叫Scroll Indicator。

Scroll Indicator:滚动指示器。是Web中常见的一种效果。用户滚动垂直滚动内容时,页面顶部有一个类似进度条的效果,当内容滚动到页面最低端,进度条效果填满整个进度条。通俗来说,就是当前可视区域距离页面顶部的占比,感觉描述得有点绕,还是录制一个动效图,用图来说明这种效果,毕竟一图胜过千言万语:

纯CSS技术实现Scroll Indicator滚动指示器效果

JavaScript实现

在还没有捞源码之前,自己先大致想了一下实现思路:

  • 页面加载完成之后,获取到页面文档高度(DH)、当前可视区域高度(VH)、可视区域距离页面顶部的高度scrollTop(TH);
  • (DH-VH)就是需要滚动的值;
  • 监听页面scroll事件,(TH/(DH-VH))*100%,便是当前的占比;
  • 当然,需要考虑节流、防抖。推荐阅读《第6题:什么是防抖和节流 有什么区别 如何实现

HTML代码:

1
2
3
<body>
  <div class="scroll-indicator j-scroll-indicator"></div>
</body>

css代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
body {
  margin: 0;
  paddingL 0;
  height: 5000px;
}

.scroll-indicator {
  position: fixed;
  height: 8px;
  top: 0;
  left: 0;
  background: #369;
}

核心代码:

1
2
3
4
5
6
7
8
9
(function() {
      var dh = $(document).height();
      var vh = $(window).height();
      var sHeight = dh - vh;
      $(window).scroll(function () {  
        var perc = $(window).scrollTop() / (dh - vh);
        $('.j-scroll-indicator').css({width: perc * 100 + '%'});
  });  
}());

效果如下:

纯CSS技术实现Scroll Indicator滚动指示器效果

然后去捞了一下阮老师es6官网的源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(function() {
      var $w = $(window);
      var $prog2 = $('.progress-indicator-2');
      var wh = $w.height();
      var h = $('body').height();
      var sHeight = h - wh;
      $w.on('scroll', function() {
        window.requestAnimationFrame(function(){
          var perc = Math.max(0, Math.min(1, $w.scrollTop() / sHeight));
          updateProgress(perc);
        });
      });

      function updateProgress(perc) {
        $prog2.css({width: perc * 100 + '%'});
        ditto.save_progress &amp;&amp; store.set('page-progress', perc);
      }

    }());

不出所料,做法是一样的。

然后,就开始瞎琢磨,之前用 css 搞过瀑布流,那可以用 css 搞滚动指示器吗?

答案当然是可以的。

css 搞滚动指示器

我想到的更好的实现

我想到的这个技术实现区别就在于对角线性渐变不是写在body标签上的,而是一个普通的div元素上。

具体操作如下:

1、在标签内插入指示器元素:

1
<div class="indicator"></div>

2、粘贴如下所示的CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
body {
    position: relative;
}
.indicator {
    position: absolute;
    top: 0; right: 0; left: 0; bottom: 0;
    background: linear-gradient(to right top, teal 50%, transparent 50%) no-repeat;
    background-size: 100% calc(100% - 100vh);
    z-index: 1;
    pointer-events: none;
    mix-blend-mode: darken;
}
.indicator::after {
    content: '';
    position: fixed;
    top: 5px; bottom: 0; right: 0; left: 0;
    background: #fff;
    z-index: 1;
}

一个更好的CSS滚动指示器效果就实现了

原理说明

传统CSS滚动指示器为了防止对角渐变(也就是滚动进度条)的覆盖页面上的元素内容,因此写在了最底层的body元素上,这就导致如果body元素内的普通元素内容有背景色,或者背景图之类的,就会覆盖进度条,产生致命缺陷。

我的优化方法是把对角渐变(也就是滚动进度条)连同里面的白色覆盖层写在了普通元素的上面,这样避开被覆盖的致命缺陷。但是这样实现带来另外一个问题,页面的内容都被白色图层覆盖了,那页面内容岂不是都看不见了?不要担心,有CSS声明可以让白色的图层变成透明,那就是mix-blend-mode:darken,也就是darken混合模式。darken混合模式的混合方式很好理解,两个颜色进行混合,哪个颜色深就使用哪个颜色?

要知道所有的颜色里面最浅的就是白色,于是我们只要把我们的白色覆盖层的混合模式设置为darken,那必然最终呈现出来的颜色一定是覆盖层下面元素内容的颜色,换句话说我们的白色透明覆盖层变透明了。

CSS滚动指示器
CSS滚动指示器要想效果良好,需要注意两点:

  1. 进度条的颜色尽量取深色,因为本身包含darken混合模式,如果颜色过浅,很容易被底部的内容颜色给混合。
  2. CSS滚动指示器需要在页面滚动高度超过一屏的时候才出现。原因有两方面:一是如果滚动高度过小,没有必要使用滚动指示器;二是滚动指示器本质上是一个渐变,如果滚动高度不足,则进度条的边缘会过于倾斜而导致显示效果不完美。

CSS滚动指示器

网友的方法也不错

使用 CSS来实现滚动指示器,难点在于:如何实时去获取当前可视区域在文档流中的位置。

上述问题,如何去考虑呢?我们从分解滚动指示器的动作中来找答案:

  • 黑色表色进度条
  • 红色表示文档高度
  • 绿、蓝、橙表示视窗滚动

CSS来实现滚动指示器

也就是说:(TH/(DH-VH))公式中的TH可以不用知道,只需要DH-VH的高度,即直角三角形的高度便OK。

现在问题转化为:如何求出VH,这时候该vh这个长度单位登场了,vh是基于视窗单位的排版计量。vh可以获取当前视窗的高度。嗯,现在看来,应该是可以一写了。

HTML代码:

1
2
3
4
5
<body>
    <div class="main">
        <h1>滚动鼠标</h1>
    </div>
</body>

CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.main {
   margin: 0;
   padding: 0;
   display: block;
   height: 30000px;
   text-align: center;
   line-height: 100px;
}

body {
   margin: 0;
   padding: 0;
   background: linear-gradient(to right top, #369 50%, #fff 50%);
   background-size: 100% calc(100% - 99vh);
}

body:before {
   content: '';
   position: fixed;
   top: 4px;
   bottom: 0;
   width: 100%;
   z-index: -1;
   background: #fff;
}

大致实现是没有问题的,但是有下面几个缺点:

  • 文档内容太少(高度太小)的话,进度条呈箭头形,不美观(可考虑加毛玻璃效果来弱化)
  • background-size:100%calc(100%-99vh);中的99vh是相对值,若是视窗高度比较小,进度条会填不满进度条槽(可考虑加min-height来弱化)

纯CSS实现Scroll Indicator(滚动指示器)

结束语

其实这只是非常牛逼的渐变非常小的一个技巧,更多精彩CSS技术文章敬请关注码云笔记,持续更细。

好了,本文到此结束,希望对你有帮助,如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

「除特别注明外,本站所有文章均为码云笔记原创,转载请保留出处!」

赞(1) 打赏

觉得文章有用就打赏一下文章作者

支付宝
微信
1

觉得文章有用就打赏一下文章作者

支付宝
微信

上一篇:

下一篇:

你可能感兴趣

共有 0 条评论 - 纯CSS技术实现Scroll Indicator滚动指示器效果

博客简介

码云笔记 mybj123.com,一个专注Web前端开发技术的博客,主要记录和总结博主在前端开发工作中常用的实战技能及前端资源分享,分享各种科普知识和实用优秀的代码,以及分享些热门的互联网资讯和福利!码云笔记有你更精彩!
更多博客详情请看关于博客

精彩评论

站点统计

  • 文章总数: 471 篇
  • 分类数目: 13 个
  • 独立页面: 8 个
  • 评论总数: 228 条
  • 链接总数: 15 个
  • 标签总数: 1033 个
  • 建站时间: 522 天
  • 访问总量: 8680894 次
  • 最近更新: 2019年11月15日