by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=9291
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。
本文内容接自之前一篇关于sticky粘性定位文章:“杀了个回马枪,还是说说position:sticky吧”。
因此,如果上面一篇文章还没阅读过,先读一读上面文章。
一、从一个现象说起
![]()
设置了position:sticky粘性定位的元素的父元素如果高度计算值和粘性定位元素一样高,则垂直滚动的时候,粘性定位效果是不会出现的。
很多人不理解为什么会这样?
要讲清楚这个问题,就必须深入理解粘性定位的计算规则。
二、深入理解粘性定位的计算规则
粘性定位中有一个“流盒”(flow box)的概念,指的是粘性定位元素最近的可滚动元素(overflow属性值不是visible的元素)的尺寸盒子,如果没有可滚动元素,则表示浏览器视窗盒子。
粘性定位中还有一个名叫“粘性约束矩形”的概念,表示的是粘性定位元素的包含块在文档流中呈现的矩形区域和流盒的四个边缘在应用粘性定位元素的left、top、right、bottom属性的偏移计算值后的新矩形的交集。
由于滚动的时候,流盒不变,而粘性定位元素的包含块跟着滚动,因此粘性约束矩形随着滚动的进行是实时变化的。
假设我们的粘性定位元素只设置了top属性值,则粘贴定位元素碰到粘性约束矩形的顶部的时候开始向下移动,直到它完全包含在粘贴约束矩形中。
下面我们根据一个简单的例子来进一步理解上面的规则,例如,有一个页面是窗体滚动,包含<div>元素和<nav>元素,这两个元素是父子关系,HTML代码如下:
<div> <nav>导航</nav> </div>
其中:
div {
height: 100px;
margin-top: 50px;
border: solid deepskyblue;
}
nav {
position: sticky;
top: 20px;
background: lightskyblue;
}
则随着滚动的进行,<nav>元素的粘性约束矩形范围和实际的渲染表现如图1所示:

图1 top方位的粘性定位原理示意图
详细的计算规则如下:
由于<nav>这个粘性定位元素的top偏移是20px,因此,流盒矩形就是滚动窗口矩形再往下偏移20px,就是图中的红色色块区域。而<nav>这个粘性定位元素的包含块就是其父元素<div>元素(设置了边框),粘性约束矩形指的是流盒矩形和包含块的重叠区域,因此,图所示的粘性约束矩形就是红色色块区域和方框区域重叠的矩形区域。
然后:
-
在默认状态下(图1左一),由于
<div>元素设置了margin-top:50px,因此,<nav>这个粘性定位元素的顶部距离粘性约束矩形的顶部还有33px的大小,不会有粘性效果。 -
随着浏览器滚动,
<nav>元素和粘性约束矩形的顶部距离越来越小,直到为0。此时<nav>元素开始下移,使自己约束在粘性约束矩形范围内,如图1左二所示。 -
浏览器继续滚动,
<nav>元素的底部也快要超出粘性约束矩形范围的限制了,如图1右二所示。 -
最终,
<nav>元素的底部和粘性约束矩形范围的底部重合,由于粘性定位元素不能超出粘性约束矩形的范围限制,因此此时粘性效果失效,<nav>元素被跟着一起滚走了,如图1右一所示。
如果还不是很理解,您可以狠狠地点击这里:帮助理解粘性定位的学习页面
right、left以及bottom方向的定位与top方向类似。
明白了粘性定位的计算规则,也就明白为什么粘性定位元素父元素和自身高度计算值一样的时候没有粘性效果了。因为此时包含块高度和粘性定位元素一样,导致粘性约束矩形的高度最大也就是和粘性定位元素一样高,粘性定位元素的已经完全没有了实现粘性效果的空间。
三、粘性定位其他特征
本文一开始那篇sticky文章还提到了粘性定位其他两个特征:
- 如果我们的粘性定位元素的某个祖先元素的
overflow属性值不是visible,那么页面滚动的时候就不会有粘性定位效果。 - 同一容器中多个粘贴定位元素独立偏移,因此可能重叠;位置上下靠在一起的不同容器中的粘贴定位元素则会鸠占鹊巢,挤开原来的元素,形成依次占位的效果。
第一个特性源自粘性定位的定义,这么设计主要是为了避免当多个滚动互相嵌套的时候,粘性定位混乱。
第二个特性原因就是本文提到的粘性定位的计算规则,具体解释:
当我们的粘性定位元素都在一个容器的时候,大家都公用一个巨大的粘性约束矩形,因此,滚动的时候会一个一个往上重叠。
当我们的粘性定位元素属于不同容器的时候,就会有多个不同的粘性约束矩形,这些粘性约束矩形正好一个一个排列得很整齐,于是视觉上达成一个巧合一般的约定,即上一个粘性定位元素被滚走,下一个粘性定位元素正好开始有粘性效果。
以上~
感谢阅读,感谢分享!
本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=9291
(本篇完)
相关文章
- 纯CSS实现标题栏、表格头水平滚动垂直不滚动 (0.720)
- CSS实现滚动高度自动变小的粘滞效果 (0.656)
- CSS fixed固定定位transofrm失效及居中小技巧 (0.656)
- JS正则表达式y标识符之粘性匹配 (0.481)
- CSS <position>值简介理解background百分比定位 (0.456)
- 杀了个回马枪,还是说说position:sticky吧 (0.430)
- 大侠,请留步,要不过来了解下CSS Scroll Snap? (0.344)
- 我熟知的三种三栏网页宽度自适应布局方法 (0.290)
- 文章文档标题自动生成导航jQuery小插件titleNav.js (0.280)
- 这个有点屌CSS @container scroll-state容器滚动查询 (0.200)
- 小tip: CSS后代选择器可能的错误认识 (RANDOM - 0.009)























