position:sticky在不离开父元素的情况下固定位置。

32
如何使一个元素粘性,让它一直保持在视口的顶部?我希望即使该元素离开其容器,它也能保持不变。
我尝试了以下代码:
HTML
<div class="page">
  <div class="parent">
    <div class="child-sticky">
      <p>i want to be sticky, even when I'm outside my parent.</p>
    </div>
  </div>
</div>
CSS
.child-sticky {
  position:sticky;
  top:20px;
}

.page {
  height: 3000px;
}
这里有一支笔用来说明问题。向下滚动查看我的意思。 https://codepen.io/pwkip/pen/OxeMao

1
{btsdaf} - Joseph Marikle
7个回答

23

“Sticky”(粘性定位)的特性是相对于其父元素而言,它将保持在相对位置不动。如果你想要实现永久性固定,你需要使用 “fixed”(固定定位)。

查看这个 codepen 示例

1
{btsdaf} - Jules Colle
1
真是让人失望。 - Pieter De Bie

19

已经7个月了,但我找到了一个仅使用CSS的解决方案如果您想要固定的元素是其父元素的最后一个元素,那么它非常简单:只需给父元素position: sticky;并且还要给它top: -xx;,具体取决于最后一个元素之前的其他元素的高度。

#parent {
  position: -webkit-sticky;
  position: sticky;
  top: -3em;
}

#some_content {
  height: 3em;
}

#sticky {
  background-color: red;
}

#space {
  height: 200vh;
}
<div id="parent">
  <div id="some_content">Some Content</div>
  <div id="sticky">Sticky div</div>
</div>

<div id="space"></div>
<p>Scroll here</p>


3

2
只要您能控制HTML标记,这是一个不错的概念。但一旦使用WordPress和其他低代码“解决方案”,您就会遇到带有非语义化标记的父容器,例如<div class="wp-block-template-part"。感谢您的明确说明。 - Ingo Steinke

3

有一个小技巧可以尝试。 在某些情况下,它会破坏您的布局,在其他情况下则不会。在我的情况下,我有一个带有一些按钮的标题,但是当我向下滚动时,我想要访问一些位于单行标题内部的操作按钮。唯一的更改是将父级的display属性设置为inline

.parent {
  display: inline;
}

非常酷,谢谢你,你能告诉我原因吗?因为我想了解为什么内联可以解决问题?在父元素中你做了什么? - eror programs

1

如前所述,sticky的工作方式就是这样。但是有一个CSS hack可以让你玩一下。

免责声明

这是一个丑陋的hack,可能会在接下来的内容中造成很多问题。因此,我不建议在大多数用例中使用它。话虽如此...

负边距hack

有一个hack可以让你玩一下,包括负边距。如果你扩展容器的高度,然后给它一些负底部边距,它至少可以“视觉上离开”容器。我修改了你的代码,并创建了一个JSFiddle进行演示。

HTML

<div class="page">
  <div class="parent">
    <div class="child"><p>...<br>...<br>...<br>...<br>...</p></div>
    <div class="child-sticky">
      <p>i want to be sticky, even when I'm outside my parent.</p>
    </div>
    <div class="child"><p>...<br>...<br>...<br>...<br>...</p></div>
    <div class="child"><p>...<br>...<br>...<br>...<br>...</p></div>
  </div>
  <div class="following-content">
  </div>
</div>

CSS (层叠样式表)
.child-sticky {
  height: 200px;
  background: #333366;
  position:sticky;
  top:20px;
  color:#ffffff;
}

.parent {
  height: 1250px;
  background: #555599;
  margin-bottom: -500px;
}
.following-content {
  background: red;
  height:500px;
}

.child {
  background-color: #8888bb;
}

.page {
  height: 3000px;
  background: #999999;
  width: 500px;
  margin: 0 auto;
}

div {
  padding: 20px;
}

https://jsfiddle.net/74pkgd9h/


1

基于https://dev59.com/11YN5IYBdhLWcg3wx6oR#46913147https://dev59.com/HV4b5IYBdhLWcg3w-2Cc#37797978的代码,这里提供了一个综合解决方案,不需要硬编码高度。

$(document).ready(function() {
    // Get the current top location of the nav bar.
    var stickyNavTop = $('nav').offset().top;
  
    // Set the header's height to its current height in CSS
    // If we don't do this, the content will jump suddenly when passing through stickyNavTop.
    $('header').height($('header').height());
  
    $(window).scroll(function(){
        if ($(window).scrollTop() >= stickyNavTop) {
            $('nav').addClass('fixed-header');
        } else {
            $('nav').removeClass('fixed-header');
        }
    });
});
body { margin: 0px; padding: 0px; }

nav {
    width: 100%;
    background-color: red;
}

.fixed-header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 10;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<header>
  <div>
    <h1 style="padding-bottom: 50px; background-color: blue;">
    Hello World!
    </h1>
  </div>
  <nav>
    A nav bar here!
  </nav>
</header>

<main style="height: 1000px;">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</main>


0
你还可以在父元素上使用display: contents来忽略它的粘性行为,但这也会忽略其他所有属性(布局属性、背景颜色等)。

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