为什么在使用 position:sticky 时,bottom:0 不起作用?

15

我正在尝试理解CSS中"sticky"的作用。我可以让它粘在父元素的顶部,但无法让其粘在底部。

我的测试代码如下:

.block {
  background: pink;
  width: 50%;
  height: 200px;
}

.move {
  position: sticky;
  bottom: 0;
}
1111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>
<div class="block">
  AAAA
  <div class="move">
    BBBB
  </div>
</div>
222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>

当我将“move”设置为'top:0'时,它会固定在粉色块的顶部,但当设置为'bottom:0'时,它似乎不再固定/粘性。
2个回答

27

它的功能没问题,但你看不到任何东西。让我们来看看定义:

黏性定位元素是指其计算定位属性为"sticky"的元素。它被视为相对定位元素,直到其包含块跨过特定阈值(例如将top设置为非auto值)时,在其流根(或者它所在的滚动容器)内,此时它被视为“粘住”,直到达到其包含块的相反边缘。ref

给这个块级元素一个大的外边距以将其从屏幕中隐藏,然后开始慢慢滚动。

.block {
  background: pink;
  width: 50%;
  height: 200px;
  margin-top:120vh;
}

.move {
  position: sticky;
  bottom: 0;
}
<div class="block">
  AAAA
  <div class="move">
    BBBB
  </div>
</div>

当您的元素显示时,您会注意到BBB会重叠AAA,直到它达到初始位置。这是使用bottom:0时的粘性行为。因此,我们的元素保持position:relative,当容器从屏幕顶部开始向外移动时,它会粘在底部,直到达到相反的边缘(容器的顶部)。

当使用top:0时,完全相同的情况发生,但方向相反:

.block {
  background: pink;
  width: 50%;
  height: 200px;
  margin-bottom:120vh;
}

.move {
  position: sticky;
  top: 0;
}
<div class="block">
  AAAA
  <div class="move">
    BBBB
  </div>
</div>

使用 sticky 属性可以让元素始终停留在屏幕上,而不仅仅是停留在页面的顶部或底部。这个属性决定了元素停留时的位置,以便在容器开始移出屏幕时保持可见。

要实现你想要的效果,需要使用其他属性将元素放置在底部,并让它保持底部的 sticky 状态。

下面是一个例子,在这个例子中,我使用 flexbox 将元素放置在底部,并指定它在底部保持 sticky 状态。

.block {
  background: pink;
  width: 50%;
  height: 200px;
  margin-top:120vh;
  display:flex;
  flex-direction:column;
}

.move {
  margin-top:auto;
  position: sticky;
  bottom: 0;
}
<div class="block">
  AAAA
  <div class="move">
    BBBB
  </div>
</div>

position:sticky 不会像 absolutefixed 一样定义元素的位置,而是定义元素在滚动时如何粘着。


以下是更多示例以便更好地理解:

.block {
  background: pink;
  display:inline-flex;
  vertical-align:top;
  height: 200px;
  max-width:100px;
  flex-direction:column;
  margin:100vh 0;
}

.e1 {
  position: sticky;
  top: 0;
}
.e2 {
  margin-top:auto;
  position: sticky;
  top: 0;
}
.e3 {
  position: sticky;
  top: 20px;
}
.e4 {
  position: sticky;
  bottom: 0;
  margin:auto;
}
.e5 {
  position: sticky;
  bottom: 0;
  top:0;
  margin:auto;
}
.e5 {
  position: sticky;
  bottom: 0;
}
<div class="block">
  <div class="e1">Top sticky</div>
</div>
<div class="block">
  <div class="e2">Top sticky at bottom (nothing will happen :( )</div>
</div>
<div class="block">
  <div class="e3">Top sticky at 10px</div>
</div>
<div class="block">
  <div class="e4">bottom sticky in the middle</div>
</div>
<div class="block">
  <div class="e5">top/bottom sticky in the middle</div>
</div>
<div class="block">
  <div class="e6">bottom sticky at the top (nothing will happen :( )</div>
</div>

使用 sticky 定位时,另一个常见的错误是忘记将元素的高度/宽度相对于其父元素考虑。如果元素的高度等于父元素(包含块)的高度,则逻辑上不会出现黏性行为,因为我们已经到了 相反的边缘

.block {
  background: pink;
  display:inline-flex;
  vertical-align:top;
  height: 200px;
  max-width:100px;
  flex-direction:column;
  margin:100vh 0;
}

.block > div {
  border:2px solid;
} 
.e1 {
  position: sticky;
  top: 0;
}
<div class="block">
  <div class="e1">Top sticky</div>
</div>
<div class="block">
  <div class="e1" style="height:100%">I will not stick</div>
</div>
<div class="block">
  <div class="e1" style="height:80%">I will stick a little ..</div>
</div>
<div class="block" style="height:auto">
  <div class="e1">I will not stick too</div>
</div>

请注意最后一种情况,其中父元素的高度设置为auto(默认值),因此其高度将由其内容定义,这会导致粘性元素具有与包含块相同的高度,并且不会发生任何变化,因为没有空间来实现黏性行为。


5
请尝试以下代码:

.block {
  background: pink;
  width: 50%;
}

.movetop {
  position: sticky;
  top: 0;
  background: #ccc;
  padding: 10px;
  color: #ae81fe;
  z-index: 1;
  border: 1px solid #777;
}

.movebot {
  background: #ccc;
  padding: 10px;
  color: #ae81fe;
  position: -webkit-sticky;
  position: sticky;
  border: 1px solid #777;
}

.movebot {
  bottom: 0
}
11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>
<div class="block">
  <div class="movetop">
    header
  </div>
  content<br>content<br>content<br>content<br>content<br>content<br>content<br>content<br>content<br>content<br>content<br>content<br>
  <div class="movebot">
    footer
  </div>
</div>
222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>

您可以在gedd.ski/post/position-sticky了解有关position:sticky的更多信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接