pure CSS multiple stacked position sticky?

别说谁变了你拦得住时间么 提交于 2019-12-01 09:27:29

You need to make all the elements to stick to the same container (containing block) by adding some offsets.

Here is a basic example where the elements will stick to the body:

body {
  margin:0;
  min-height:200vh;
  border:2px solid;
}
.first {
  height:50px;
  background:red;
  position:sticky;
  top:0;
}

.second {
  height:50px;
  background:blue;
  position:sticky;
  top:52px;
}
.third {
  height:50px;
  background:green;
  position:sticky;
  top:104px;
}
<div class="first"></div>
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<div class="second"></div>
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<div class="third"></div>
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>

It will not work if they are in different containers:

body {
  margin: 0;
  min-height: 300vh;
}
body > div {
  border:2px solid;
}

.first {
  height: 50px;
  background: red;
  position: sticky;
  top: 0;
}

.second {
  height: 50px;
  background: blue;
  position: sticky;
  top: 52px;
}

.third {
  height: 50px;
  background: green;
  position: sticky;
  top: 104px;
}
<div>
  <div class="first"></div>
  <p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
    lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
</div>
<div>
  <div class="second"></div>
  <p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
    lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
</div>
<div>
  <div class="third"></div>
  <p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
    lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
</div>

A stickily positioned element is an element whose computed position value is sticky. It's treated as relatively positioned until its containing block crosses a specified threshold (such as setting top to value other than auto) within its flow root (or the container it scrolls within), at which point it is treated as "stuck" until meeting the opposite edge of its containing block ref

The most important part here is the last one. So if all the elements aren't in the same container each one will reach the edge of its container and the sticky behavior will stop there. Note how, in the last example, each element will stop moving when reaching the bottom-border of its containing block


In case you want to handle dynamic height you can consider this solution: How can I properly reflect different levels of headers with position:sticky?


Another related question to get more examples: css sticky - not sticky to bottom of parent

All you need to do is keep nesting elements with position:sticky into one another. And then set top:2em incrementally to succeeding sticky headers. Your pen contained two columns so I assumed that you needed two scroll-boxes, Hence the long code snippet.

body {
  display: flex;
  flex-direction: row;
  margin: 0;
  padding: 0;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background: #222;
}

.mainParent {
  height: 90%;
  width: 80%;
  background: rgba(222, 222, 222, 0.10);
  color: #ddd;
  overflow-y: scroll;
  border: 4px solid #ddd;
}

.mainParent {
  margin: 0.5em
}

.header {
  position: sticky;
  padding: 0.5em;
  background: #ddd;
  color: #222;
  text-align: center;
}

#header01 {
  top: 0;
}

#header02 {
  top: 2em;
}

#header03 {
  top: 4em;
}

#header04 {
  top: 6em;
}

#header05 {
  top: 8em;
}

.content {
  text-align: center
}
<div class="mainParent">
  <div class="header" id="header01">Header 01</div>
  <div id="content01" class="content">
    <br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br>Content 1-1<br><br>
    <div class="header" id="header02">Header 02</div>
    <div id="content02" class="content">
      <br><br><br><br><br><br><br><br><br><br><br><br>
      <br><br><br><br><br><br><br><br><br>Content 1-2<br><br>
      <div class="header" id="header03">Header 03</div>
      <div id="content03" class="content">
        <br><br><br><br><br><br><br><br><br><br><br><br>
        <br><br><br><br><br><br><br><br><br>Content 1-3<br><br>
        <div class="header" id="header04">Header 04</div>
        <div id="content04" class="content">
          <br><br><br><br><br><br><br><br><br><br><br><br>
          <br><br><br><br><br><br><br><br><br>Content 1-4<br><br>
          <div class="header" id="header05">Header 05</div>
          <div id="content05" class="content">
              <br><br><br><br><br><br><br><br><br><br><br><br>
              <br><br><br><br><br><br><br><br><br>Peace &#128406;
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
<div class="mainParent">
  <div class="header" id="header01">Header 01</div>
  <div id="content01" class="content">
    <br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br>Content 2-1<br><br>
    <div class="header" id="header02">Header 02</div>
    <div id="content02" class="content">
      <br><br><br><br><br><br><br><br><br><br><br><br>
      <br><br><br><br><br><br><br><br><br>Content 2-2<br><br>
      <div class="header" id="header03">Header 03</div>
      <div id="content03" class="content">
        <br><br><br><br><br><br><br><br><br><br><br><br>
        <br><br><br><br><br><br><br><br><br>Content 2-3<br><br>
        <div class="header" id="header04">Header 04</div>
        <div id="content04" class="content">
          <br><br><br><br><br><br><br><br><br><br><br><br>
          <br><br><br><br><br><br><br><br><br>Content 2-4<br><br>
          <div class="header" id="header05">Header 05</div>
          <div id="content05" class="content">
              <br><br><br><br><br><br><br><br><br><br><br><br>
              <br><br><br><br><br><br><br><br><br>Peace &#128406;
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

You can find this code as pen here.

I hope this answer helps you.

Peace 🖖

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!