0

My problem is along the lines of these previous issues on StackOverflow but with a slight difference.

Previous issues: Stopping fixed position scrolling at a certain point? Sticky subnav when scrolling past, breaks on resize

I have a sub nav that starts at a certain position in the page. When the page is scrolled the sub nav needs to stop 127px from the top. Most of the solutions I have found need you to specify the 'y' position of the sub nav first. The problem with this is that my sub nav will be starting from different positions on different pages.

This is the JS code i'm currently using. This works fine for one page but not all. Plus on mobile the values would be different again.

 var num = 660; //number of pixels before modifying styles

 $(window).bind('scroll', function () {
     if ($(window).scrollTop() > num) {
         $('.menu').addClass('fixed');
     } else {
         $('.menu').removeClass('fixed');
     }
 });

I'm looking for a solution that stops the sub nav 127px from the top no matter where on the page it started from.

Stephen Smith
  • 89
  • 2
  • 6

3 Answers3

1

You can use position: sticky and set the top of the sub-nav to 127px.

See example below:

body {
  margin: 0;
}

.main-nav {
  width: 100%;
  height: 100px;
  background-color: lime;
  position: sticky;
  top: 0;
}

.sub-nav {
  position: sticky;
  width: 100%;
  height: 50px;
  background-color: red;
  top: 100px;
}

.contents {
  width: 100%;
  height: 100vh;
  background-color: black;
  color: white;
}

.contents p {
  margin: 0;
}
<nav class="main-nav">Main-nav</nav>

<div class="contents">
  <p>Contents</p>
</div>

<nav class="sub-nav">Sub-nav</nav>

<div class="contents">
  <p>More contents</p>
</div>

Please see browser support for sticky here

Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
  • I'll give this a go. Much more comfortable with CSS than JS so this might be a more suitable solution. I'll let you know how this goes. – Stephen Smith Feb 06 '19 at 11:20
  • @StephenSmith ok, the key is to use `position: sticky`. It basically acts as a normally positioned element and then transforms into a `fixed` element once it reaches the `top` attribute – Nick Parsons Feb 06 '19 at 11:22
  • Such a simple solution but works perfectly. Why didn't I think of this :) Excellent, simple solution Nick. Thank you so much!! – Stephen Smith Feb 06 '19 at 11:25
  • @StephenSmith no worries! `position: sticky` can be a lifesaver sometimes :P – Nick Parsons Feb 06 '19 at 11:26
1

You should change your code to the below, should work fine:

 $(window).bind('scroll', function () {
     if ($(window).scrollTop() > $(".menu").offset().top) {
         $('.menu').addClass('fixed');
     } else {
         $('.menu').removeClass('fixed');
     }
 });
  • Hi Andy. Thanks for your response. I've added this in and I think its working but I get massive flickering when scrolling. – Stephen Smith Feb 06 '19 at 11:20
  • Andy. I have implemented the CSS solution below. More familiar with CSS so it makes sense to use this code. Thank you for your quick response. Much appreciated. – Stephen Smith Feb 06 '19 at 11:26
0

Maybe you can try this:

  • Find navigation div (.menu)
  • Find the top value of the .menu (vanilla JS would be menuVar.getBoundingClientRect().top, not sure how jQuery does this).
  • Get top value of browserscreen.
  • Calculate the difference - 127px.
  • When the user scrolls and reaches the top value of the menu -127px -> addClass('fixed').