How to fix a header on scroll

322,634

Solution 1

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/

Solution 2

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');
   }
});

Solution 3

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

Solution 4

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;
}

Solution 5

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>
Share:
322,634
Paul Designer
Author by

Paul Designer

Hey, Im a UX designer trying to improve my code. Would love all your help !

Updated on October 31, 2021

Comments

  • Paul Designer
    Paul Designer over 2 years

    I am creating a header that once scrolled to a certain amount of pixels it fixes and stays in place.

    Can I do this using just css and html or do i need jquery too?

    I have created a demo so you can understand. Any help would be great!

    http://jsfiddle.net/gxRC9/4/

    body{
         margin:0px;
         padding:0px;
    }
     .clear{
         clear:both;
    }
     .container{
         height:2000px;
    }
     .cover-photo-container{
         width:700px;
         height: 348px;
         margin-bottom: 20px;
         background-color:red;
    }
     .small-box{
         width:163px;
         height:100px;
         border:1px solid blue;
         float:left;
    }
     .sticky-header{
         width:700px;
         height:50px;
         background:orange;
         postion:fixed;
    }