CSS-position sticky粘性定位的计算规则

367 阅读2分钟
现象

设置了 position:sticky 粘性定位的元素的父元素如果高度计算值和粘性定位元素一样高,则垂直滚动的时候,粘性定位效果是不会出现的;

流盒(flow box)

指粘性定位元素最近的可滚动元素overflow属性值不是visible的元素,如果没有该元素,则选择浏览器视窗;

粘性约束矩形

粘性定位元素的文档流矩形区域和流盒的四个边缘在粘性定位元素使用left、top、right、bottom属性的偏移计算值后的新矩形的交集;
由于滚动的时候,流盒不变,而粘性定位元素的包含块跟着滚动,因此粘性约束矩形随着滚动的进行是实时变化的;
假设我们的粘性定位元素只设置了top属性值,则粘贴定位元素碰到粘性约束矩形的顶部的时候开始向下移动,直到它完全包含在粘贴约束矩形中;

例子

浏览器窗体滚动,一个div元素,包含nav元素;

<div>
	<nav>粘性定位元素</nav>
</div>
body {
	height: 5000px;
	background: red;
}
div {
	height: 100px;
	margin-top: 50px;
	border: 1px solid #000000;
}
nav {
	position: sticky;
	top: 20px;
	background: yellow;
}

5E9B3E53-5CB5-4AB1-BC4A-0E6B1312C5FD.png

红色区域是流盒(浏览器视窗),位置固定,和div元素(边框区域)重合的部分就是粘性约束矩形;

详细的计算规则

由于nav这个粘性定位元素的top偏移是20px,因此,流盒矩形就是滚动窗口矩形再往下偏移20px,就是图中的红色色块区域。而nav这个粘性定位元素的包含块就是其父元素div元素(设置了边框),粘性约束矩形指的是流盒矩形和包含块的重叠区域,因此,图所示的粘性约束矩形就是红色色块区域和方框区域重叠的矩形区域;
然后:
在默认状态下(图左一),由于div元素设置了margin-top:50px,因此,nav这个粘性定位元素的顶部距离粘性约束矩形的顶部还有33px的大小,不会有粘性效果;
随着浏览器滚动,nav元素和粘性约束矩形的顶部距离越来越小,直到为0。此时nav元素开始下移,使自己约束在粘性约束矩形范围内,如图左二所示;
浏览器继续滚动,nav元素的底部也快要超出粘性约束矩形范围的限制了,如图右二所示;
最终,nav元素的底部和粘性约束矩形范围的底部重合,由于粘性定位元素不能超出粘性约束矩形的范围限制,因此此时粘性效果失效,nav元素被跟着一起滚走了,如图右一所示;