CSS 中的 Position Sticky
position: sticky
是 CSS 中的一个定位属性,它使得元素在页面滚动到某个位置时表现得像 position: fixed
,而在其他位置表现得像 position:relative
。具体来说,元素会“粘”在设定的位置,直到其父容器的边缘到达“粘性”元素的相应边缘。
https://developer.mozilla.org/zh-CN/docs/Web/CSS/position#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”行为(详情见 Github issue on W3C CSSWG)。
但是,position: sticky 元素实际上不会变成 position:relative。相反,当它不是“粘性”时(即当它不需要粘在屏幕上时),它的行为就像 position:relative,这意味着它将根据正常文档流进行布局,但其 position 属性实际上不会改变。
以下是一些导致 position: sticky
元素表现得像 position:relative
的情况:
滚动位置不在阈值内: 当页面没有滚动到元素的
top
、bottom
、left
、right
等粘性边界指定的位置时,该元素看起来就像一个position:relative
元素。父元素的边界: 当
position: sticky
元素的底部到达其父容器的底部时,它将停止粘性行为,就像它是position:relative
一样。兼容性和限制: 如果父元素具有
overflow
属性,并且其值不是visible
,或者position: sticky
元素的任何祖先元素具有transform
、filter
、perspective
或will-change
属性,或者position: sticky
元素的任何祖先元素不是position: static
(例如position:relative
、position:absolute
或position:fixed
),则position: sticky
可能无法正常工作,并且元素的行为将类似于position:relative
。未指定阈值: 如果
position: sticky
元素没有指定top
,bottom
,left
,right
中至少一个属性值,那么它将不具有粘性行为。
请注意,即使在这些情况下,元素的 position
属性也是 sticky
,但其行为看起来类似于 relative
。这是因为它不是固定在视口中,而是继续随滚动容器的内容滚动。
Example
以 Apple 的产品详情页面为例: https://www.apple.com/shop/buy-iphone/iphone-15-pro
此页面的框架如下所示:⬇️
当我们向下滚动页面时,红色块(我设置了 position:sticky)在滚动位置达到顶部阈值时开始粘在屏幕上(情况 1)。当我们继续向下滚动时,当我们的滚动位置到达红色块父元素的底部时,它将停止粘住(情况 2)。
源代码可以在 这里 查看。