聊聊css position属性及其sticky属性值的特性(吸顶特效)

7,079 阅读4分钟

新的知识仓库 前端从入门到入土 求关注、star及提建议,不定时更新~

本文收纳于: 从零开始的大前端筑基之旅(深入浅出,持续更新~)

CSS position属性用于指定一个元素在文档中的定位方式。toprightbottomleft 属性则决定了该元素的最终位置。

例如:

.element {
  position: relative;
  top: 50px;
  left: 50px;
}

取值

static

该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 top, right, bottom, leftz-index 属性无效。

relative

该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。

position:relative 对 table-*-group, table-row, table-column, table-cell, table-caption 元素无效。

如上图所示,虽然第一个方块因为relative移动了位置,但并未影响页面原本布局。

absolute

元素会被移出正常文档流,并不为元素预留空间,通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置。绝对定位的元素可以设置外边距(margins),且不会与其他边距合并。

此时,蓝色框的父元素设置为 position: relative,用来限定子元素绝对定位的位置,child element 设置为 top: 80px, left: 50px

fixed

元素会被移出正常文档流,并不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。打印时,元素会出现在的每页的固定位置。fixed 属性会创建新的层叠上下文。

当元素祖先的 transform, perspectivefilter 属性非 none 时,容器由视口改为该祖先。

sticky

元素根据正常文档流进行定位,然后相对它的_最近滚动祖先(nearest scrolling ancestor)_和 containing block (最近块级祖先 nearest block-level ancestor),包括table-related元素,基于top, right, bottom, 和 left的值进行偏移。偏移值不会影响任何其他元素的位置。该值总是创建一个新的层叠上下文(stacking context。

注意,一个sticky元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的overflowhidden, scroll, auto, 或 overlay时),即便这个祖先不是真的滚动祖先。

sticky详解

粘性定位可以被认为是相对定位和固定定位的混合。当元素在屏幕或滚动元素显示区域时,表现为relative,就要滚出显示器屏幕的时候,表现为fixed。

可以滚动下面这个框感受下交互表现

A
Andrew W.K.
Apparat
Arcade Fire
At The Drive-In
Aziz Ansari
C
Chromeo
Common
Converge
Crystal Castles
Cursive
E
Explosions In The Sky
T
Ted Leo & The Pharmacists
T-Pain
Thrice
TV On The Radio
Two Gallants

其中,标示A被设置为:

  {
    position: sticky;
    top: 10px;
  }

随着页面的滚动,当标示A距离上边缘10px距离的时候,黏在了上边缘,表现如同position:fixed

stickyfixed定位有着根本性的不同,fixed元素直抵页面根元素,其他父元素对其left/top定位无法限制。而sticky元素效果完全受制于父级元素

层次滚动吸顶

还是上面的栗子,我在每个标题组上加了红色或蓝色的边框,这些边框就是标示A、C、E、T的父元素边框,可以很明显的看到,粘性定位的元素在移动到父元素的底部时,就不会再保持吸顶,而是随着父元素移出显示区域。

因此可以推出一些特性:

  1. 父级元素设置和粘性定位元素等高的固定的height高度值,或者高度计算值和粘性定位元素高度一样,不会粘滞效果。
  2. 同一个父容器中的sticky元素,如果定位值相等,则会重叠;
  3. 如果属于不同父元素,且这些父元素正好紧密相连,则会鸠占鹊巢,挤开原来的元素,形成依次占位的效果。

由于每一个标示组,属于不同的父元素,因此,滚动的时候,后面的标题才能把前面已经sticky定位的标题推开,形成层次滚动吸顶效果。这是sticky定位天然的特性,无需任何JavaScript的帮助。

如果所有的标题头都在同一个父元素下,就会导致所有sticky定位的新闻标题都会重叠在一起。

还是不理解粘性定位规则的花建议看一下参考文档1。

附上浏览器支持:

如果你收获了新知识,或者收获了左侧精美图片,请点个吧~

参考文档:

  1. 深入理解position sticky粘性定位的计算规则
  2. position | MDN
  3. 杀了个回马枪,还是说说position:sticky吧