如何只让一个child元素粘住而不影响其他元素?

How to make only one child element sticky without affecting the rest?

下面代码中的相关元素是.top.sticky.other

.sticky.other 位于 .navbar 容器内。

现在,让整个 .navbar 变粘很容易。将 position: sticky; top: 0; 添加到该元素即可。这就是我想要的一般行为。

我面临的挑战是:

如何使 .sticky 元素具有粘性,以便其下方的所有内容始终在其下方滚动?

如果您 运行 当前代码,您可以看到 .sticky 元素只保持粘性,直到黄色 .other 元素在其下方滚动。之后 .sticky 元素不再是粘性的。

这就是我要解决的问题。如何让蓝色 .sticky 元素始终保持粘性? (向上滚动到绿色 .top 部分隐藏的位置后)

理想情况下正在寻找 css-only 解决方案。如果那不可能,JavaScript/jQuery 解决方案是可以接受的,但在向上或向下两个方向滚动时必须正常工作。

更新:

我知道从 header 中取出黄色 .other 元素可以解决问题。但问题是黄色 .other 元素需要成为 header 的一部分。 .sticky.other 都需要在大屏幕上显示在彼此旁边,在移动屏幕上显示在彼此下方。这就是为什么它们目前是另一个容器内的 child 元素。因此,在这种情况下,将黄色元素移出 header 并不是我真正可以使用的选项。

.top {
    min-height: 40px;
    background-color: darkgreen;
}
.navbar {
/*            position: sticky;*/
/*            top: 0;*/
}
.sticky {
    min-height: 50px;
    background-color: lightblue;
    position: sticky;
    top: 0;
}
.other {
    min-height: 90px;
    background-color: yellow;
}

.content {
    background-color: lightgray;
    min-height: 600px;
}
.bottom {
    background-color: darkgray;
    min-height: 200px;
}
<div class="top">
   Top
</div>
<div class="middle">
   <header class="navbar">
       <div class="header-container">
           <div id="row-masthead">
               <div class="sticky">
                   Sticky
               </div>
               <div class="other">
                   Other
               </div>
           </div>
       </div>
   </header>
   <main class="content">
      <h2>
          Content
      </h2>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
   </main>
</div>
<div class="bottom">
  <h2>Footer</h2>
   <p>
       Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
   </p>
</div>

根据我对 position:sticky 的理解,您必须重新定义 HTML 结构并使用 class .other 移动元素header。此外,取消注释有关 .navbar class.

的 css 代码

像这样:

.top {
    min-height: 40px;
    background-color: darkgreen;
}
.navbar {
            position: sticky;
            top: 0;
}
.sticky {
    min-height: 50px;
    background-color: lightblue;
    position: sticky;
    top: 0;
}
.other {
    min-height: 90px;
    background-color: yellow;
}

.content {
    background-color: lightgray;
    min-height: 600px;
}
.bottom {
    background-color: darkgray;
    min-height: 200px;
}
 <div class="top">
  Top
  </div>
  <div class="middle">
  <header class="navbar">
   <div class="header-container">
    <div id="row-masthead">
     <div class="sticky">
      Sticky
     </div>
     
    </div>
   </div>
  </header>

  <div class="other">
   Other
  </div>
  
  <main class="content">
     <h2>
      Content
     </h2>
   <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
   </p>
   <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
   </p>
   <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
   </p>
   <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
   </p>
  </main>
  </div>
  <div class="bottom">
    <h2>Footer</h2>
  <p>
   Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
  </p>
  </div>

检查下面的代码,它可能对你有帮助。将其选中为全页或全屏模式,在桌面模式下,粘滞和其他部分并排,在移动视图中,其他 div 在粘滞 div 下。它需要移动视图的媒体查询。

.top 
 { min-height: 40px; background-color: darkgreen; }
 
 .navbar { height:auto;  }

 .sticky {
  min-height: 90px; background-color: lightblue;
  width:50%; float:left;
 }
 
 .row_masthead
 { position: fixed; top: 0; width:100%; }
 
 .other {
  min-height: 90px; background-color: yellow;
  width:50%; float:left;
 }

 .content {
  background-color: lightgray; min-height: 600px;
  margin-top:4%;
 }
 
 .bottom { background-color: darkgray; min-height: 200px; }
 
 @media only screen and (max-width:768px) and (min-width:200px)
 {
  .sticky 
  { width:100%; }
  
  .other 
  { width:100%; float:left; } 
  
  .content
  { margin-top:43%; }
 }
<div class="top">
   Top
</div>
<div class="middle">
   <header class="navbar">
       <div class="header-container">
           <div id="row-masthead" class="row_masthead">
               <div class="sticky">
                   Sticky
               </div>
               <div class="other">
                   Other
               </div>
           </div>
       </div>
   </header>
   <main class="content">
      <h2>
          Content
      </h2>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
   </main>
</div>
<div class="bottom">
  <h2>Footer</h2>
   <p>
       Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
   </p>
</div>

一种解决方案是考虑在粘性元素的容器中使用 display:contents 使它们就像它们不存在一样,你会得到你想要的:

.top {
    min-height: 40px;
    background-color: darkgreen;
}
.navbar,
.header-container,
#row-masthead{
  display:contents /* added this */
}
.sticky {
    min-height: 50px;
    background-color: lightblue;
    position: sticky;
    top: 0;
}
.other {
    min-height: 90px;
    background-color: yellow;
}

.content {
    background-color: lightgray;
    min-height: 600px;
}
.bottom {
    background-color: darkgray;
    min-height: 200px;
}
<div class="top">
   Top
</div>
<div class="middle">
   <header class="navbar">
       <div class="header-container">
           <div id="row-masthead">
               <div class="sticky">
                   Sticky
               </div>
               <div class="other">
                   Other
               </div>
           </div>
       </div>
   </header>
   <main class="content">
      <h2>
          Content
      </h2>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
   </main>
</div>
<div class="bottom">
  <h2>Footer</h2>
   <p>
       Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
   </p>
</div>

另一个 hacky 解决方案是创建所需的 space 粘性元素,使用如下所示的高度和负边距的组合。缺点是您需要找到正确的值以避免在底部创建大量 space 并为粘性提供所需的 space。

.top {
    min-height: 40px;
    background-color: darkgreen;
}
div#row-masthead:after {
    content: "";
    display: block;
    height: 200vh; /*big value here*/
}
div#row-masthead {
  margin-bottom:-200vh; /*same value here*/
}

.sticky {
    min-height: 50px;
    background-color: lightblue;
    position: sticky;
    top: 0;
}
.other {
    min-height: 90px;
    background-color: yellow;
}

.content {
    background-color: lightgray;
    min-height: 600px;
}
.bottom {
    background-color: darkgray;
    min-height: 200px;
}
<div class="top">
   Top
</div>
<div class="middle">
   <header class="navbar">
       <div class="header-container">
           <div id="row-masthead">
               <div class="sticky">
                   Sticky
               </div>
               <div class="other">
                   Other
               </div>
           </div>
       </div>
   </header>
   <main class="content">
      <h2>
          Content
      </h2>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
   </main>
</div>
<div class="bottom">
  <h2>Footer</h2>
   <p>
       Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
   </p>
</div>

配合一些JS可以动态正确计算出值:

var h = document.querySelector('.middle').offsetHeight - document.querySelector('.navbar').offsetHeight;

document.querySelector('#row-masthead').style.setProperty("--h", h+"px");

window.onresize = function(event) {
    h = document.querySelector('.middle').offsetHeight - document.querySelector('.navbar').offsetHeight;
    document.querySelector('#row-masthead').style.setProperty("--h", h+"px");
}
.top {
    min-height: 40px;
    background-color: darkgreen;
}
div#row-masthead:after {
    content: "";
    display: block;
    height: var(--h,0);
}
div#row-masthead {
  margin-bottom:calc(-1*var(--h,0));
}

.sticky {
    min-height: 50px;
    background-color: lightblue;
    position: sticky;
    top: 0;
}
.other {
    min-height: 90px;
    background-color: yellow;
}

.content {
    background-color: lightgray;
    min-height: 600px;
}
.bottom {
    background-color: darkgray;
    min-height: 200px;
}
<div class="top">
   Top
</div>
<div class="middle">
   <header class="navbar">
       <div class="header-container">
           <div id="row-masthead">
               <div class="sticky">
                   Sticky
               </div>
               <div class="other">
                   Other
               </div>
           </div>
       </div>
   </header>
   <main class="content">
      <h2>
          Content
      </h2>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
       <p>
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
       </p>
   </main>
</div>
<div class="bottom">
  <h2>Footer</h2>
   <p>
       Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus non vero quam suscipit veniam ex praesentium id sunt, voluptatibus ad ipsa asperiores enim quis omnis alias maxime saepe aut. Iste.
   </p>
</div>