Kakar
Kakar

Reputation: 5609

Fix an element when it reaches the top of the screen using javascript and css

I have an element, that I wish to stick on top after it reaches the top of the screen.

<div id="HeaderWrapper">
  ...
  <div id="Navigation">
    Navigation
  </div>
  ...
</div>

I am adding an event listener on scroll, which would call a function to check the posting of the element by using getBoundingClientRect() method. If the top or the y of the element is less then 0 relative to the viewport, then I would like to fix/stick the header. Again if its more than 0 then I would like to remove the fix position. In both the cases, I am adding and removing a class name of fixed_navbar which has the property of fix position.

document.addEventListener("scroll", function() {
  const el = document.getElementById("Navigation");
  let rect = el.getBoundingClientRect();
  if (rect.top <= 0) {
    el.classList.add("fixed_navbar");
  } else {
    el.classList.remove("fixed_navbar");
  }
});

You can also the check the codepen demo.

When the position top of the element is more than zero it works fine. Also when scrolling down to the position where the element's top position is less than 0 it sticks to the page and has the fixed propery. But again when scrolling back to the position when the element's top is more than 0, the element still has the fixed propery and stick's to the top of the screen. How can I make the element stick to the top when it reaches the top of the screen and again when the element is below the top of the screen remove the fixed postion?

Upvotes: 6

Views: 3901

Answers (3)

Husain Ahmmed
Husain Ahmmed

Reputation: 351

@Rounin provide an awesome solution. Although I fix your issue in JavaScript. you can check this

document.addEventListener("scroll", function() {
  const el = document.getElementById("Navigation");
  let rect = el.getBoundingClientRect();
  if (rect.top <= 0) {
    el.classList.add("fixed_navbar");
  } else {
   window.onscroll = function() {myFunction()};

function myFunction() {
    if ( document.body.scrollTop < 100 ) {
        el.classList.remove("fixed_navbar");
    } 
  }
  }
});
* {
  margin: 0;
  padding: 0;
}

#HeaderWrapper {
  background: lightgrey;
  height: 1500px;
}

.box {
  background: skyblue;
  width: 100%;
  height: 100px;
}

#Navigation {
  background: green;
}

.fixed_navbar {
  position: fixed;
  z-index: 1000;
  width: 100%;
  left: 0;
  top: 0;
}
<div id="HeaderWrapper">
  <div class="box"></div>
  <div id="Navigation">
    Navigation
  </div>
</div>

Upvotes: 0

Rounin
Rounin

Reputation: 29511

You can achieve this with CSS alone, by using:

position: sticky

When declaring position: sticky; you will also need to declare a top style (eg. top: 0;) to indicate at which point you want the element to become "stuck".

Working Example:

header {
height: 600px;
}

.navigation {
position: sticky;
top: 0;
margin-top: 150px;
}
<header>
<div class="navigation">Navigation</div>
</header>


Further Information:

position: sticky works in the following browsers:

https://caniuse.com/#feat=css-sticky

Upvotes: 7

Rajan Prajapati
Rajan Prajapati

Reputation: 33

Try This

 if (rect.top <= 0) {

In if condition you write rect.top < 0 that is wrong for your requirement

Upvotes: 1

Related Questions