12

I'm creating a header that'll stick in place when the user scrolls down past a set amount of pixels. My header is 121 pixels high, but the part of the header I want to stick is the bottom 42 pixels of the header; which does work, but at the point it begins to stick the page jumps up about 50 pixels.

My thought on what could be causing the issue is $('#header').css({position: 'fixed'});. I think once fixed is applied the content, the content div no longer takes the margin into account. I've tried to play around with the different positions, but nothing has worked out for me.

I created a JSFIDDLE to better illustrate my issue.

JQUERY CODE

$(window).scroll(function()
{
    if( $(window).scrollTop() > 79 )
    {
        $('#header').css({position: 'fixed'});
    } 
    else 
    {
        $('#header').css({position: 'static', top: '-79px'});
    }
});

CSS CODE

body {
    margin: 0;
    padding: 0;
}
#header {
    width: 100%;
    height: 121px;
    background: url(http://libertyeaglearms.com/dev/admin/graphics/header-bg.png);
}
#content {
    margin: 10px auto;
    width: 300px;
    min-height: 600px;
}

HTML

<div id="header">header</div>
<div id="content">content goes here</div>
Mike
  • 1,760
  • 5
  • 21
  • 40
  • Did you notice that it works fine when you click and drag the scroll bar versus using the scroll wheel? At least it does for me... not sure if that'll point to an issue. Also I'm using Chrome. Also it appears to only happen on the very first scroll. If I scroll back up and then back down it works... this is weird. I like working on weird :) – Iron3eagle Jul 24 '13 at 18:48
  • Hm, that is strange. I'm using chrome and I get jumping either way. – Mike Jul 24 '13 at 18:52
  • I just added `$('#header').css({position: 'fixed', top: '-79px'});` to the fixed portion and it seems to have stopped. – Iron3eagle Jul 24 '13 at 18:54
  • At first I tried playing around with setting a margin to the content div once the sticky is initiated, but it started changing the placement of the header. – Mike Jul 24 '13 at 18:55
  • I added `top: '-79px'` to the fixed part and it didn't change anything for me. I'm sure it's one of these easy fixes that requires some little trick, lol. – Mike Jul 24 '13 at 18:58
  • Not sure if it matters but I'm using Chrome Version 28.0.1500.72 on Windows 7. I'm going to read the API documentation a bit and see if there is a clue. Also tested in IE9 on Windows 7 and your code works as is with no changes... silly javascript cross browser compatibility issues... – Iron3eagle Jul 24 '13 at 19:00
  • Hm, well I appreciate your time on this. I'm using Chrome Version 28.0.1500.72 m on WIN7. I will try other browsers as well. – Mike Jul 24 '13 at 19:05

2 Answers2

31

Here is the problem:

When the header has a "static" positioning, it pushes the content down so it does not overlap with it. When the positioning changes from "static" to "fixed", it no longer cares whether it overlaps with the content so the content "jumps up" to the top of the page because it thinks there is nothing in it's way.

There are multiple fixes to this problem:

The easiest one is probably to add another element that essentially takes up the space that the header did when the positioning changes.

I did this by changing the display of the element to "block" when the header is "fixed" and "none" when the header is "static"

Here is an updated JSFiddle: http://jsfiddle.net/6kPzW/2/

HTML Code:

<div id="header">header</div>
<div id="header_placeholder"></div>
<div id="content">Content</div>

CSS Code:

body {
    margin: 0;
    padding: 0;
}
#header {
    width: 100%;
    height: 121px;
    background: url(http://libertyeaglearms.com/dev/admin/graphics/header-bg.png);
}
#content {
    margin: 10px auto;
    width: 300px;
    min-height: 600px;
}
#header_placeholder {
    height:121px;
    width:100%;
    display:none;
}

JQuery Code:

$(window).scroll(function()
{
    if( $(window).scrollTop() > 79 )
{
        $('#header').css({position: 'fixed'});
        $('#header_placeholder').css({display: 'block'});
} 
else 
{
        $('#header').css({position: 'static', top: '-79px'});
        $('#header_placeholder').css({display: 'none'});
}
});
Harrison
  • 688
  • 7
  • 15
  • For me the fiddle has the entire header stay static rather than just the bottom grey section. Other than that what you're saying makes sense. – Iron3eagle Jul 24 '13 at 19:18
  • @defaultNINJA, what browser are you using? – Harrison Jul 24 '13 at 19:23
  • I tried it and it worked in my version of Chrome. I also think I found a solution, what do you guys think : http://jsfiddle.net/6kPzW/4/ – Mike Jul 24 '13 at 19:28
  • @Mike, that should work great as long as the content div is the only one that relies on the position of the header div – Harrison Jul 24 '13 at 19:30
  • I tried the way I came up with and it failed, yours works perfect. Thank you :) – Mike Jul 24 '13 at 20:47
  • Google Chrome is displaying a red phishing warning on the JSFiddle URL mentioned in this answer. – Aamir Oct 18 '22 at 13:36
0

You can simply use css for this like:

header{
position:sticky;
top:0;
z-index:9;
}
Salman Aziz
  • 426
  • 8
  • 15