CSS position: sticky
对于"老前端"来们来说,实现这样一个效果:在网页滚动到一定高度之后,让一部分内容(比如导航,目录列表等)固定在页面中显示。我们第一直觉可能是:使用JS监听scroll事件,然后通过修改对应元素的css或者style来实现。
比如如下示例中的nav
模块:
1. 现代
CSS如何实现?
我不得不在这一节的标题中加入了现代
两个字,因为如果你去问活跃在2019或者2020年之前的前端同学下面这个问题:CSS的position有哪些属性?我想你得到的答案大概率是:static
、relative
、absolute
、fixed
、inherit
,毕竟这是经典八股文以及CSS面试“可能”必考的题目之一。实际上position
还有一个值sticky
,通过使用这个值,我们只需要两行简单的CSS就能实现上述效果:
position: sticky;
top: 0px;
2. 理解 sticky
sticky
虽然好用,但它并不像fix
或者absolute
一样好理解。如果你百度一下,可能会看到一堆使用条件,比如:父元素不能overflow:hidden或者overflow:auto属性
, 父元素的高度不能低于sticky元素的高度
等等。
实际上我们并不需要去特别记忆这些奇奇怪怪的规,只要理解 黏性元素
(sticky item
),黏贴容器
(sticky container
)两个概念即可。其中 sticky item
是指被设置成 position: sticky
的元素,sticky container
是指这个元素的父元素。比如,下图中,我们设置了.nav
为 position: sticky
之后他的父元素(灰色虚线边框的元素)就自动成为了sticky container
。
然后我们只要记住一个规则就可以了:当sticky container
滚动的时候, sticky item
距离sticky container
可见区域达到我们定义的条件之后就会被固定下来,如果sticky container
的剩余空间不足以放置 sticky item
, sticky item
也会变回正常状态。
具体来说(Demo在文章末尾):
- 在案例Demo中我们设置了
top: 50px;
,一开始sticky item
距离sticky container
顶部可见区域大于50px,所以会随着页面滚动 - 继续滚动,当
sticky item
距离sticky container
顶部可见区域小于50px的时候(并且sticky container
能容纳下sticky item
),sticky item
就会固定在页面中 - 当
sticky container
的可见区域无法容纳sticky item
的时候,sticky item
会变回正常状态随着页面滚动
Try Demo(codepen.io链接):
兼容性
随着几年的发展,除了旧的IE,所有主流的现代浏览器都支持sticky。