pure CSS multiple stacked position sticky?

Solution 1:

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


Related questions to get more details/examples:

Why element with position:sticky doesn't stick to the bottom of parent?

'position: sticky' not working when 'height' is defined

How can I create different levels of sticky headers?

Solution 2:

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 🖖