Make div stick to top of page after scrolling past another div?
Solution 1
I would recommend adding a class to #sticky
when it's ready to be fixed to the top of the screen, and then removing that class when you want to 'unstick' it. Then you can manipulate that class in CSS.
e.g. for a class fixed
you'd put the following in your CSS:
#sticky {
display: none;
background-color: #546bcb;
height: 70px;
}
#sticky.fixed {
display: block;
position: fixed;
top: 0;
width: 100%;
}
And then your jQuery would look like this:
$(window).scroll(function() {
var distanceFromTop = $(this).scrollTop();
if (distanceFromTop >= $('#header').height()) {
$('#sticky').addClass('fixed');
} else {
$('#sticky').removeClass('fixed');
}
});
Here's an updated FIDDLE
I might also recommend some jQuery fade or slide effects (see the fiddle).
Solution 2
You can use position: fixed
and in js detect when user scroll like this:
$(document).scroll(function() {
//detect when user scroll to top and set position to relative else sets position to fixed
$("#sticky").css({
"top": "0",
"position": $(this).scrollTop() > 140 ? "fixed" : "relative"
});
});
body {
margin: 0px;
background-color: #e3e3e3;
}
#header {
background-color: #cb5454;
height: 140px;
}
#sticky {
background-color: #546bcb;
height: 70px;
width: 100%;
position: fixed;
}
#section {
height: 1500px;
}
#footer {
background-color: #cb5454;
height: 140px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header"></div>
<div id="sticky"></div>
<div id="section"></div>
<div id="footer"></div>
References
Solution 3
Hey this is and old question but for new visitors I think u just need to add this css code to #sticky:
#sticky { position:sticky;top:0; }
and no need for javascript.
sticky toggles between relative and fixed, depending on the scroll position.
and don't forget that, the parent also should not have overflow property
Solution 4
In my case, the div I wanted to be sticky was inside of another div (ie. not stuck to the page, but in another fixed div on the side of the page). Here's my adaptation of @bowhart's answer to solving this problem given a React component (sticky_adapter.js):
module.exports.makeItSticky = function(thisReactComponent, parentScrollNode = window) {
const thisNode = $(ReactDOM.findDOMNode(thisReactComponent));
const position = thisNode.position();
// Uncomment for verbose logging
//console.log("Initial position: " + UIUtils.stringify(position));
const scrollContainer = $(parentScrollNode);
scrollContainer.scroll(() => {
const distanceFromTop = scrollContainer.scrollTop();
// Uncomment for verbose logging
//console.log("ScrollTop: " + distanceFromTop);
if (distanceFromTop > position.top) {
thisNode.addClass("stick-to-top");
} else {
thisNode.removeClass("stick-to-top");
}
});
};
Now, to make any React component sticky, I just add to the class:
componentDidMount() {
StickyAdapter.makeItSticky(this, ".some-other-div-which-is-the-container");
}
Finally, the css for the sticky class:
.stick-to-top {
display: block;
position: sticky;
top: 0;
z-index: 10;
}
John
Updated on July 09, 2022Comments
-
John almost 2 years
<div id="header"></div> <div id="sticky"></div> <div id="section"></div> <div id="footer"></div> <style> body { margin: 0px; background-color: #e3e3e3; } #header { background-color: #cb5454; height: 140px; } #sticky { background-color: #546bcb; height: 70px; } #section { height: 1500px; } #footer { background-color: #cb5454; height: 140px; } </style>
Here is my code: http://jsfiddle.net/uaqh018d/
I want #sticky to stick to the top of the page after scrolling past #header. I also want it hidden until stuck. And then of course have it unstick+hide again after scrolling back up to #header.
How can I achieve this?
-
John over 9 yearsALMOST. WE'RE SO CLOSE. I just need to have it unstick when you scroll back up to bottom of #header, not when you scroll up to the very top of page.
-
John over 9 yearsOh, there we go! Your fiddle is working as it should now. Thanks man! I had to accept bowheart's answer. It appears to be more efficient, but thanks again!
-
John over 9 yearsThank you! I believe this to be more efficient!
-
SearchForKnowledge over 9 yearsWhat is the height is dynamic and not known?
-
bowheart over 9 years@SearchForKnowledge You mean the height of the sticky header? jsfiddle.net/uaqh018d/40
-
Si8 over 8 yearsI keep getting this error:
Uncaught TypeError: Cannot read property 'scroll' of null
-
Saghachi over 3 yearsthe fade option in fiddle link make the menu disappear when scrolling back to top