使用纯 CSS 实现滚动阴影效果

开门见山,有这样一种很是常见的状况,对于一些可滚动的元素而言。一般在滚动的时候会给垂直于滚动的一侧添加一个阴影,用于代表当前有元素被滚动给该滚出了可视区域,相似这样:css

能够看到,在滚动的过程当中,会出现一条阴影:html

对于两侧的列在滚动的过程当中,静止不动,吸附在边界的问题,一般 CSS 使用 position: sticky 便可解决。git

可是对于滚动过程当中才出现的阴影(滚动容器内的内容没有贴边,则阴影出现,贴边,则阴影消失),以前的作法一直都是须要借助 JS 完成的。github

那么,有没有纯 CSS 可以实现的方案呢?嘿嘿嘿,有。有一种很是讨巧的障眼法,下面就让咱们来一步一步揭开它的面纱。网站

 

神奇的 background-attachment

要使用纯 CSS 实现上述滚动阴影,最核心的要使用到的元素就是 background-attachmenturl

在较早的一篇文章里 -- CSS 实现视差效果,详细了介绍了 background-attachment,借助了 background-attachment: fixed 能够简单的实现网站的滚动视差或者是相似图片点击的水纹效果,相似这样:spa

固然,今天咱们的主角不是 background-attachment: fixed,而是 background-attachment: srcoll.net

 

background-attachment: srcoll

首先,介绍一下 background-attachment,若是指定了 background-image ,那么 background-attachment 决定背景是在视口中固定的仍是随着包含它的区块滚动的。3d

简单而言,就是决定了在可滚动的容器中,背景图案是如何进行运动的。经过两个简单的 Demo,弄懂 background-attachment: srcoll 和 background-attachment: localcode

background-attachment: local,这个就是和咱们平常使用中的用法是一致的,可滚动容器的背景图案随着容器进行滚动:

background-attachment: scroll,这个是今天的主角,它代表背景相对于元素自己固定, 而不是随着它的内容滚动:

若是你还没弄明白他们的区别,能够戳下面的 DEMO 本身感觉一下:

CodePen Demo -- bg-attachment Demo

 

srcoll 与 local 同时使用,实现障眼法

到这里,可能不少同窗仍是懵的,咱们到底要作什么呢?这个和本文的滚动阴影有什么关联呢?

别急,滚动阴影的难点在于,初始没有滚动的时候是没有阴影展示的,只有当开始滚动,阴影才会出现。

因此这里,咱们借助 background-attachment: srcoll 和 background-attachment: local 两个属性,在滚动初始的时候,利用两层背景叠加在一块儿隐藏阴影背景,真正滚动的时候,将叠加的部分移走,只漏出阴影部分便可。

嗯?什么意思。咱们用给滚动容器,加上两个渐变效果,分别运用上 background-attachment: srcoll 和 background-attachment: local,再叠加起来,像是这样:

<!-- 可滚动容器 -->
<ul> 
    <li>...</li>
    ...
    <li>...</li>
</ul> 
// 情形一:
.g-one {
    background: linear-gradient(#fff, #f00);
    background-size: 100% 10px;
    background-repeat: no-repeat;
    background-attachment: local;
}

// 情形二:
.g-two {
    background: radial-gradient(at 50% 0, #000, #0f0 70%);
    background-size: 100% 10px;
    background-repeat: no-repeat;
    background-attachment: scroll;
}

// 情形三:
.g-combine {
    background: 
        linear-gradient(#fff, #f00),
        radial-gradient(at 50% 0%, #000, #0f0 70%);
    background-size: 100% 10px, 100% 10px;
    background-repeat: no-repeat;
    background-attachment: local, scroll;
}

实际效果就是这样,一个背景是随容器滚动,一个背景是随容器固定。随容器滚动的背景充当初始的遮罩层:

OK,能够看大,当滚动的时候,最后一幅叠加的状况,其实就是咱们须要的滚动的时候展现不一样的颜色(阴影)的效果。咱们调整一下两个渐变的颜色,遮罩层(background-attachment: local)为白色,再把固定不动的阴影层(background-attachment: scroll),利用径向渐变模拟为咱们想要的阴影颜色。

CSS 代码大概是这样:

.g-final {
    background: 
        linear-gradient(#fff, transparent 100%),
        linear-gradient(rgba(0, 0, 0, .5), transparent 100%);
    background-size: 100% 30px, 100% 10px;
    background-repeat: no-repeat;
    background-attachment: local, scroll;
}

利用 linear-gradient(rgba(0, 0, 0, .5), transparent 100%) 线性渐变模拟了一层灰色阴影:

OK,大功告成。上述全部 DEMO,能够戳这里看看:

CodePen Demo -- Pure CSS Scroll shadow

如文章开头所示,这技巧也是能够直接运用在 table 里面:

CodePen Demo -- Pure CSS Table scroll shadow

 

一些问题

层叠顺序

固然,在上述的过程当中,其实一直有个问题,就是因为是使用背景 background 模拟的阴影,其实最终的效果,内容是在阴影(背景之上的),可是实际效果其实没有很大的差异,若是能忍受这一点,这个方案是彻底可用的。

 

兼容性

嗯,固然还有一个问题是就是 background-attachment 的兼容问题。让咱们看看 CAN I USE

Can i use 下面的注释代表,大部分兼容问题实际上是出在 background-attachment: fixed,对于本文的效果影响不大。

 

最后

本文技巧非原创,第一次看到来自这篇文章:探索CSS属性*-gradient的实用价值 ,对其可否在实际中运用再作了一些探究。

好了,本文到此结束。

更多精彩 CSS 技术文章汇总在个人 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

若是还有什么疑问或者建议,能够多多交流,原创文章,文笔有限,才疏学浅,文中如有不正之处,万望告知。

相关文章
相关标签/搜索