JSFiddle - React, Tailwind, and code Playground

by Dipak1991

HTML

<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>


<div class="wrapper">

  <div>
    <h1 class="fixontop">heading 1</h1>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
    <p>1 content</p>
  </div>
  <div>
    <h1 class="fixontop">heading 2</h1> 2nd content goes here.
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    <p>2 content</p>
    . . . . . . . . . . . . . . . long paragraph.
  </div>
  <div>
    <h1 class="fixontop">heading 3</h1> . . .
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    <p>3 content</p>
    . . . . . . . . . . . . 3nd content goes here.
  </div>

</div>

<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other content</p>
<p>other...

CSS

html,
body {
  padding: 0;
  margin: 0;
  
}
* {
  box-sizing: border-box;
}

.wrapper > div {
  background: #eaeaea;
}

.wrapper > div h1 {
  margin: 0;
}

.heading-fixed {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  background: #cacaca;
  width: 100%;
}

.wrapper {
  position: relative;
  overflow-y: scroll;
  height: 300px;
}

JavaScript

var breakpoints = [];

function fix_heading(heading, top) {
  heading.css('top', top);
  if (heading.hasClass('heading-fixed'))
    return

  heading
    .addClass('heading-fixed')

}

function unfix_heading(heading) {
  if (!heading.hasClass('heading-fixed'))
    return

  heading
    .removeClass('heading-fixed')
    .css('top', 0);
}

function fix_headings(breakpoints) {
  $(breakpoints).each(function() {
    var breakpoint = this;
    var breakpoint_heading = $('.fixontop[data-fix-on=' + breakpoint + ']')

    if ($('.wrapper').scrollTop() >= breakpoint) {
      fix_heading(breakpoint_heading, $('.wrapper').scrollTop())
    }

    if ($('.wrapper').scrollTop() <= (breakpoint)) {
      unfix_heading(breakpoint_heading)
    }


    if ($('.wrapper').scrollTop() >= (breakpoint + breakpoint_heading.parents('div').outerHeight())) {
      unfix_heading(breakpoint_heading)
    }
  });
}

$(function() {
  $('.fixontop').each(function() {
    breakpoints.push($(this).position().top)
    $(this).attr('data-fix-on', $(this).position().top)
  })
  $('.wrapper').scroll(function() {
    fix_headings(breakpoints)
  })
})