2

I tried to find some solution for the following scenario:

  1. Header height is all different
  2. Mouse scroll down
  3. Fixed headers

Does anyone know how to make multiple sticky headers like this?

(1) init

enter image description here

(2) scroll down (using mouse)

enter image description here

(3) scroll down (using mouse)

enter image description here

6
  • What do you want to achieve in the end? Is there any special reason why you can't use position: fixed with different top attributes? Commented Apr 9, 2015 at 5:17
  • are you trying to implement an accordion? Commented Apr 9, 2015 at 5:20
  • I tried to like this, but it not fixed header A, B, C... Multiple Sticky Headers Commented Apr 9, 2015 at 5:35
  • And when you click on a header, the content below is displayed? What's the behaviour of it? Commented Apr 9, 2015 at 5:37
  • It's not an accordion, just scroll down using mouse. Commented Apr 9, 2015 at 5:43

3 Answers 3

6

hmm...

DEMO

$(window).scroll(function() {
  var $headers = $(".header");
  var scrollTop = $(this).scrollTop();

  if (scrollTop <= 0) {
    // reset all
    $headers.css({
      position: "relative",
      top: "0px"
    });
  } else {
    $headers.each(function(index, $el) {

      var $curHeader = $($headers).eq(index);
      var curTop = $curHeader.offset().top;
      var curHeight = $curHeader.height();

      // scroll up
      var isRelative = ($el.isFixed && scrollTop <= $el.exTop);

      // scroll down
      var isFixed = (curTop <= scrollTop);

      var position = "";
      var top = 0;

      if (isRelative) {
        // reset
        positon = "relative";
        top = 0;

        $el.isFixed = false;
      } else if (isFixed) {
        position = "fixed";
        if (0 < index) {
          for (var i = 0; i < index; i++) {
            top += $($headers).eq(i).height();
          }
        }
        scrollTop += curHeight;

        if (!$el.isFixed) {
          $el.isFixed = true;
          $el.exTop = curTop;
        }
      }

      $($el).css({
        position: position,
        top: top + "px"
      });
    });
  }
});
body {
  height: 10000px;
}
div {
  height: 200px;
  background: gray;
  width: 100%;
}

.header {
  height: 50px;
  background: green;
}

div.header:nth-child(7) {
  height: 100px;
}
<!DOCTYPE html>
<html>

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <meta charset="utf-8">
    <title>JS Bin</title>
</head>

<body>
    <div>content 0</div>
    <div class="header">header 1</div>
    <div>content 1</div>
    <div class="header">header 2</div>
    <div>content 2</div>
    <div class="header">header 3</div>
    <div>content 3</div>
</body>

</html>

Sign up to request clarification or add additional context in comments.

Comments

1

Here is a simple example:

I'm calculating the height of the headers and setting the top property.

DEMO

  $(window).scroll(function () {
var $headers = $(".header");
if ($(this).scrollTop() > 50) {
    $headers.each(function (index, el) {
        var height = 0;
        if (index == 0) {
            height = "0px";
        } else {
            for ( var x = index - 1; x >= 0; x--) {
                height += $headers.eq(x).height();
            }
        }
        height = height + "px";
        $(el).css({
            "position": "fixed",
                "top": height
        });
    });
} else {
    $headers.css({
        position: "relative",
        top: "0"
    });
}
});
body {
  height: 10000px;
}
div {
  height: 100px;
  background: green;
  width: 100%;
}

.header {
  height: 50px;
  background: red;
}
.header:first-child {
  height: 20px;
}
div.header:nth-child(5) {
  height: 100px;
}
<!DOCTYPE html>
<html>

<head>
    <script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
    <meta charset="utf-8">
    <title>JS Bin</title>
</head>

<body>
    <div class="header">header 1</div>
    <div>content 1</div>
    <div class="header">header 2</div>
    <div>content 2</div>
    <div class="header">header 3</div>
    <div>content 3</div>
</body>

</html>

1 Comment

Yours all appear to collapse/sticky together at once. They are supposed to happen one at a time when each header hits the next one.
1

With only css Codepen-FollowMe Headers

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

.second {
  height:50px;
  background:blue;
  height: 10rem;
  
}
.third {
  height:50px;
  background:green;
  height: 10rem;
  
}

.stickyContainer {
  .sticky {
    position: sticky;
    top: 0;
    height: 2rem;
    background: white;
  }
}
<div class="first stickyContainer">
  <div class="sticky"><h1>1</h1></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 class="second stickyContainer">
  <div class="sticky"><h1>2</h1></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 class="third stickyContainer">
  <div class="sticky"><h1>3</h1></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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.