CSS定位元素在滚动容器内的“fixed”位置

50

我想知道是否有人已经找到了这个问题的解决方案?

我正在寻找一种将元素附加到滚动容器顶部的解决方案。

HTML:

<div class="container">
  <div class="header">title</div>
  <div class="element">......</div>
  ... (about 10-20 elements) ...
  <div class="element">......</div> 
</div>

所有的"元素"都具有position:relative属性,

容器具有以下CSS:

.container {
  position:relative;
  width:200px;
  height:400px;
  overflow-y:scroll;
}

我希望标题能够保持在容器的顶部,不受滚动位置和下方元素的影响。

到目前为止的CSS:

.header {
  position:absolute; /* scrolling out of view :-( */
  z-index:2;
  background-color:#fff;
}
.element{
  position: relative;
}

所有元素都是块级元素,我不能将标题移到容器之外。在这一点上,jQuery不是一个选择。


你可以使用jQuery来实现这个功能。http://www.ruturaj.net/automatic-header-stick-to-scroll-with-jquery/ - Kees Sonnema
如果容器没有相对定位,当绝对定位时,标题将位于其顶部。您的标题是否可以成为容器的前一个兄弟节点(好吧,“容器”现在可能是“内容”或类似的东西),或者您的元素是否有自己的容器且容器上没有position: relative - FelipeAls
@FelipeAlsacreations:position: fixed不会遵循position: relative。它始终相对于文档进行固定。 - Madara's Ghost
如果我正确理解了 OP,那么就不需要使用“fixed”,而是使用“absolute”。 - FelipeAls
jQuery不是一个选择...而且正如之前所说,没有改变结构的机会。position:fixed固定在窗口,而position:absolute意味着如果内容超过容器的高度,则标题将滚动出视图。 - Siggi Gross
我需要的是,无论内容高度是否达到900像素并向下滚动,标题都保持在容器顶部可见。目前它会随着其他内容一起滚动,并且如果容器向下滚动,则看不到它。 - Siggi Gross
10个回答

36
我认为你的解决方案可以使用position:sticky来实现。它看起来像position:fixed,但是会尊重其相对于父元素的位置。
不幸的是,这是一项实验性功能,并且仅受到Chromium的支持。您可以在此测试页面中查看更多详细信息。
我想到的纯CSS解决方案需要对标记稍作更改。你可以为“元素”设置一个容器,如下所示:
<div class="cont_elements">
      <div class="element">......</div>
      .....
</div>
将溢出内容给到这个内部容器。现在,您的标题会固定在顶部。 这是一个有效的演示。

2
请注意,目前这在Chrome中不起作用,它将在IOS中起作用,但在Android的Chrome中不起作用。请参见caniuse.com/#feat=css-sticky。 - Ben Taliadoros
在工作演示中,关键点似乎是1.相对定位的父元素和绝对定位的标题,2.具有指定高度和overflow-y的后续兄弟元素。我理解第一个关键点。您能否解释一下第二个关键点?如果删除任何一个高度或overflow-y,则标题将无法固定在父容器的顶部。 - uoay

9

这是我使用position: sticky想出的解决方案(所以不支持IE):

https://codepen.io/waterplea/pen/JjjMXzR

这个想法是在滚动容器的顶部放置一个高度为0的粘性容器,因此它会固定在那里但不会推动下面的任何内容,然后在其中绝对定位您的内容。这样,您就拥有了宽度,但没有高度,所以只能从顶部定位某些东西,就像我在示例中用按钮做的那样。

编辑:找到了一种方法使其具有100%的高度并且不会推动下面的内容,使用了float。 更新了代码段。由于Firefox中的此错误https://bugzilla.mozilla.org/show_bug.cgi?id=1612561,必须使用calc(100% - 1px)


5
在这种情况下,解决方案是将标题弹出滚动元素之外:
<div class="header">title</div>
<div class="container">
    <div class="element">......</div>
    <div class="element">......</div>
</div>

虽然如果可能的话,最好使用更好的语义化元素(这只是猜测):

<h3>title</h3>
<ul>
    <li>......</li>
    <li>......</li>
</ul>

5
jQuery UI添加了一个名为position()的实用方法,专门用于此目的,可以使您的生活更加轻松。
$( "#someElement" ).position({
    of:  //Element to position against,
    my:  //which position on the element being positioned,
    at:  //which position on the target element eg: horizontal/vertical,
    offset:  // left-top values to the calculated position, eg. "50 50"
});

肯定对我有帮助。

2

你能找到的最佳解决方案在这个链接里:如何在达到一定高度后固定滚动 div,在到达其他 div 后停止滚动? 我希望这能帮助节省某人的谷歌时间。

    var navWrap = $('#navWrap'),
        nav = $('nav'),
        startPosition = navWrap.offset().top,
        stopPosition = $('#stopHere').offset().top - nav.outerHeight();
    
    $(document).scroll(function () {
        //stick nav to top of page
        var y = $(this).scrollTop()
        
        if (y > startPosition) {
            nav.addClass('sticky');
            if (y > stopPosition) {
                nav.css('top', stopPosition - y);
            } else {
                nav.css('top', 0);
            }
        } else {
            nav.removeClass('sticky');
        } 
    });
body {
    height:1600px;
    margin:0;
}
#navWrap {
    height:70px
}
nav {
    height: 70px;
    background:gray;
}
.sticky {
    position: fixed;
    top:0;
}

h1 {
    margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit morb​​,o vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro. Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.</p>
<div id="navWrap">
    <nav>
         <h1>I stick to the top when you scroll down and unstick when you scroll up to my original position</h1>
    </nav>
</div>

<p>Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit​​, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro. Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.</p>
<p>Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit morb​​,o vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro. Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.</p>
<br>
<div id="stopHere">
<h3 style="color:red">I want it stop fixed scrolling here. If I'm back to scrolling up, It will follow also to original position.</h3>
</div>
<br>
<p>Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit morb​​,o vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro. Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.</p>
<p>Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit​​, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro. Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.</p>
<p>Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit morb​​,o vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro. Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.</p>
<p>Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit​​, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro. Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.</p>
<p>Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit morb​​,o vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro. Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.</p>


2

将要滚动的元素与一个容器一起包裹:height: 100%; overflow: scroll

将滚动容器和标题放在另一个具有固定高度的容器内。

然后,在外部容器中使用position: absolute将标题定位。

.scroll-container {
  height: 100%;
  overflow-y: scroll;
}

.outer-container {
  position: relative;
  width: 200px;
  height: 200px;
}

.header {
  position: absolute; /* relative to outer container */
  background-color: pink;
  width: 100%;
  z-index: 2;
}

.element {
  position: relative;
  background-color: gold;
}
<div class="outer-container">
  <div class="header">title</div>
  <div class="scroll-container">
    <div class="element">......</div>
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div>
    <div class="element">......</div>
    <div class="element">......</div>
    <div class="element">......</div>
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div> 
    <div class="element">......</div>
    <div class="element">......</div>
    <div class="element">......</div>
  </div>
</div>


0

#container {
  position: relative;
  width: 400px;
  height: 400px;
}

#fixed {
  position: absolute;
  left: 0px;
  top: 0px;
  Width: 100%;
  height: 100%; // specify your own height
  z-index: 5;
}

#scrollable {
  width: 100%;
  height: 100%;
  overflow-y: scroll;
  overflow-x: hidden;
  z-index: 4;
}
<div id="container">
  <div id="fixed">

  </div>
  <div id="scrollable">

  </div>
</div>


最好在div中放一些内容,以进一步展示您的答案为什么有效。 - Lee Taylor

0

position:sticky和top:0px的使用

使用position: stickytop: 0px来固定您的标题。这样,div将被固定,并从父元素中获取其高度,因此兄弟元素不会与固定的div重叠。

.parent -> 滚动容器

.fixed -> 固定的标题/固定的div

.content -> 溢出的内容。在父级启用overflow: auto后可滚动。

注意:使用overflow: auto而不是overflow: scroll。如果没有滚动条,则auto仅在有滚动时添加滚动条,而overflow:scroll则显示空的滚动区域而没有任何滚动条。

.parent {
  height: 50vh;
  overflow: auto;
  background: yellow;
}

.fixed {
  position: sticky;
  top: 0px;
  background: pink;
}

.content {
  height: 150vh;
}
<div class="parent">
     <div class="fixed">
        Fixed Header
     </div>
     <div class="content">
        <p>content</p>
     </div>
</div>


0

这是我如何在可滚动的 div 中实现静态位置 div 的方法:

<div class="parent">
   <div class="fixFloat">:</div>
   <...some long elements here...>
</div>

.parent {
   position: relative;
   overflow-y: scroll;
}
.fixFloat {
   position: fixed;
   float: right:
}

-1

使用 sticky。绝对有效!

父容器:

position:relative;

子容器:

position: sticky; // fixed on the page

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