26

更好的纯CSS滚动指示器技术实现

 4 years ago
source link: https://www.tuicool.com/articles/EjimEfb
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

byzhangxinxu from https://www.zhangxinxu.com/wordpress/?p=8701

本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

7zqyYrE.jpg!web

一、CSS滚动指示器

滚动指示器指的是页面的顶端会有一个进度条,指示滚动的进度。效果如下GIF所示(点击播放):

rm6ryez.png!web

CSS滚动指示器指的是不借助JavaScript,纯CSS实现滚动进度效果。

二、传统的实现方法

传统CSS实现方法由一个名叫 Mike的人首先提出,时间应该是16年,这个CodePen目前已经有十几万的访问量: CSS only scroll indicator

传统的CSS实现非常有创意,具体原理如下。

在body标签上写一个对角的线性渐变,然后用一个白色的固定定位的浮层覆盖在上面,CSS代码示意如下:

body{    
    background: linear-gradient(to right top, teal 50%, white 50%);
    background-size: 100% calc(100% - 100vh);
    background-repeat: no-repeat;
}

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

::before 伪元素模拟的就是白色的覆盖层,不过这个覆盖层并不是完全覆盖,上边缘露出了一点点的距离,这个距离可以透出body渐变背景,随着滚动进行,会出现类似进度条一样的效果。如果我们把白色覆盖层的透明度降低,大家就可以看懂实现的原理了,如下GIF录屏效果(点击播放,1M大小):

FFFbUfE.png!web

三、传统实现方法的致命缺陷

传统的css滚动指示器效果虽然方法和思路非常精妙,但是却有致命的缺陷,导致几乎无法在实际项目中应用。

致命缺陷是:

  1. 页面内容不能有背景色或背景图!
  2. body自身也不能有背景图!

由于存在上面这两点性质,实际开发场景变幻莫测,页面内容有个背景色背景图什么的太正常不过了,居然会影响CSS滚动指示器的效果,显然这个技术没有实用性,就是个开阔眼界的玩具而已。

好在技术在发展,时代在召唤,我自己花时间琢磨了一下,有没有什么方法可以化腐朽为神奇,避开上面这些不足,让CSS滚动只是器能够在实际项目中大放光彩。嘿,还真让我想到了,一番实践下来确实可行,这里给大家分享下。

四、我想到的更好的实现

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

具体操作如下:

  1. 在<body>标签内插入指示器元素:
    <div class="indicator"></div>
  2. 粘贴如下所示的CSS代码:
    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滚动指示器demo

GIF录屏效果如下(观察最上边缘):

vumq6ze.gif

原理说明

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

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

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

uyuiueI.png!web

五、其他说明和结语

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

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

    3a6v2uF.png!web

本文内容实际上应该2个月前就开始排期了(第五届CSS大会分享内容),一直到今天才排到更新,事情太多了,想做的事情堆积如山,周更的小说已经一个月没写了,要写的公众号文章也有好几个,还不知道排到什么时候。今日两更,还有5篇文章争取端午完成,不过估计写完3篇不错,因为端午还给自己安排了个支付开发需求,还有2篇只能下周了,那小说怎么办呢?还有公众号文章?天哪!下下周还要去北京做分享,好在一分付出还有半分的收获的。

加油加油!

n2qYJjY.png!web

本文为原创文章,欢迎分享,勿全文转载,如果内容你实在喜欢,可以加入收藏夹,永不过期,而且还会及时更新知识点以及修正错误,阅读体验也更好。

本文地址: https://www.zhangxinxu.com/wordpress/?p=8701

(本篇完)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK