position: sticky
是开发中相对高频的一个用法,不过在最近的项目中竟然被我玩翻车了,设置了sticky
尽然不生效了,于是便想一探究竟。
元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor)和 containing block (最近块级祖先 nearest block-level ancestor),包括table-related元素,基于top,right, bottom, 和 left的值进行偏移。偏移值不会影响任何其他元素的位置。
该值总是创建一个新的层叠上下文(stacking context)。注意,一个sticky元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的overflow 是 hidden, scroll, auto, 或 overlay时),即便这个祖先不是最近的真实可滚动祖先。这有效地抑制了任何“sticky”行为
它是做什么的?
- 它先以正常的文档流的定时进行定位,当页面滚动到指定位置的时候会脱离文档流。
它有什么问题?
- 它是相对于最近的滚动元素进行定位的
- 它可以被父级元素的
overflow
属性所影响
sticky的正常效果
<div class="content-wrap">
<div class="content">
<div class="top">顶部区域</div>
<div class="sticky">粘性布局</div>
<div class="bottom">底部区域</div>
</div>
</div>
<style>
.top {
height: 100px;
text-align: center;
background-color: gray;
}
.bottom {
height: 2000px;
background-color: paleturquoise;
}
.sticky {
height: 30px;
background-color: red;
position: sticky;
top: 0px;
}
</style>
失效的原因
1、sticky 设置了非滚动父元素。
<div class="prent">
<div class="sticky">粘性布局</div>
</div>
当我们将为sticky
元素设置了父组件时,也就是sticky
的父元素不为body
根元素时,此时的sticky
定位时相对于prent
元素的
当然现在我们还没有办法去理解这样的一个行为,我们来给prent
加一点高度再来看一看
.prent {
border: 2px solid yellow;
height: 200px;
background-color: #aaaaaa;
}
有趣的是,当元素滑动到prent
时,sticky
元素开始生效了;
当我们继续向下滑动到bottom
时,sticky
元素随着prent
元素离开了页面。
那么我们就可以得出结论,sticky
元素的定位时相对于父级元素的,并且父级元素需要为可滚动的元素
2、父元素设置overflow
前面说道,当sticky
脱离了文档流,使用overflow
属性的以下hidden
, scroll
, auto
, 或 overlay
时会阻止元素的定位。
.prent {
border: 2px solid yellow;
height: 200px;
background-color: #aaaaaa;
overflow: hidden;
}
总结
1、使用sticky
是父级元素需要拥有滚动机制
2、使用sticky
不使用overflow
的属性