How to fix a header on scroll
You need some JS to do scroll events. The best way to do this is to set a new CSS class for the fixed position that will get assigned to the relevant div when scrolling goes past a certain point.
HTML
<div class="sticky"></div>
CSS
.fixed {
position: fixed;
top:0; left:0;
width: 100%; }
jQuery
$(window).scroll(function(){
var sticky = $('.sticky'),
scroll = $(window).scrollTop();
if (scroll >= 100) sticky.addClass('fixed');
else sticky.removeClass('fixed');
});
Example fiddle: http://jsfiddle.net/gxRC9/501/
EDIT: Extended example
If the trigger point is unknown but should be whenever the sticky element reaches the top of the screen, offset().top
can be used.
var stickyOffset = $('.sticky').offset().top;
$(window).scroll(function(){
var sticky = $('.sticky'),
scroll = $(window).scrollTop();
if (scroll >= stickyOffset) sticky.addClass('fixed');
else sticky.removeClass('fixed');
});
Extended example fiddle: http://jsfiddle.net/gxRC9/502/
I have modified the Coop's answer. Please check the example FIDDLE Here's my edits:
$(window).scroll(function(){
if ($(window).scrollTop() >= 330) {
$('.sticky-header').addClass('fixed');
}
else {
$('.sticky-header').removeClass('fixed');
}
});
Coop's answer is excellent.
However it depends on jQuery, here is a version that has no dependencies:
HTML
<div id="sticky" class="sticky"></div>
CSS
.sticky {
width: 100%
}
.fixed {
position: fixed;
top:0;
}
JS
(This uses eyelidlessness's answer for finding offsets in Vanilla JS.)
function findOffset(element) {
var top = 0, left = 0;
do {
top += element.offsetTop || 0;
left += element.offsetLeft || 0;
element = element.offsetParent;
} while(element);
return {
top: top,
left: left
};
}
window.onload = function () {
var stickyHeader = document.getElementById('sticky');
var headerOffset = findOffset(stickyHeader);
window.onscroll = function() {
// body.scrollTop is deprecated and no longer available on Firefox
var bodyScrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (bodyScrollTop > headerOffset.top) {
stickyHeader.classList.add('fixed');
} else {
stickyHeader.classList.remove('fixed');
}
};
};
Example
https://jsbin.com/walabebita/edit?html,css,js,output
I know Coop has already answered this question, but here is a version which also tracks where in the document the div is, rather than relying on a static value:
http://jsfiddle.net/gxRC9/16/
Javascript
var offset = $( ".sticky-header" ).offset();
var sticky = document.getElementById("sticky-header")
$(window).scroll(function() {
if ( $('body').scrollTop() > offset.top){
$('.sticky-header').addClass('fixed');
} else {
$('.sticky-header').removeClass('fixed');
}
});
CSS
.fixed{
position: fixed;
top: 0px;
}
Glorious, Pure-HTML/CSS Solution
In 2019 with CSS3 you can do this without Javascript at all. I frequently make sticky headers like this:
body {
overflow-y: auto;
margin: 0;
}
header {
position: sticky; /* Allocates space for the element, but moves it with you when you scroll */
top: 0; /* specifies the start position for the sticky behavior - 0 is pretty common */
width: 100%;
padding: 5px 0 5px 15px;
color: white;
background-color: #337AB7;
margin: 0;
}
h1 {
margin: 0;
}
div.big {
width: 100%;
min-height: 150vh;
background-color: #1ABB9C;
padding: 10px;
}
<body>
<header><h1>Testquest</h1></header>
<div class="big">Just something big enough to scroll on</div>
</body>