Lemon Kazi
Lemon Kazi

Reputation: 3311

Fixed header shaking when scrolling down

When I use a fixed header, it's shaking when adding my is-sticky CSS class. It's starting with top:0; for it's animation when scrolling down. I want it to stay fixed smoothly on top in a way that will not cause noticeable jitter. For Example: http://www.lazada.com.my/
Here is my demo.

$(window).load(function(){
  $(window).scroll(function(){
    if($(window).scrollTop()>0){
      if( ! ($('#scroller').hasClass('is-sticky'))) {
        $('#scroller')
        .addClass('is-sticky')
        .css('top',9)
        .animate({
          'top': 84
        },'1000');
      }



    } else {
      if($('#scroller').hasClass('is-sticky')) {
        $('#scroller')
        .removeClass('is-sticky')
        .css('top',9)
        .animate({
          'top':84
        },1000);

      }
    }
  });
});
body{
    height:1000px;
    margin:0;
    padding:0;
    position:relative;
}
#scroller {
    position: absolute;
    left: 0;
    top: 84px;
    width: 100%;
    z-index: 30;
    background:#CCC;
    height:20px;
}
#scroller.is-sticky {
    position: fixed;
    width: 100%;
    left: 0;
    top: 9px;
    margin-top: -31px;
    height: 53px;
    z-index: 701;
    background: #CCC;
    opacity: .97;
    filter: alpha(opacity = 97);
    -webkit-box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.1);
    -moz-box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.1);
    box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<body>
  <div id="scroller">Some controls</div>
</body>

Upvotes: 5

Views: 8523

Answers (3)

Zeus
Zeus

Reputation: 1275

You can create a fixed navbar and divide it into two parts vertically and when user scroll just hide the above part with .slideUp() animation and when user again scrolls on top show it with .slideDown() animation. Here is the code :

$(window).load(function(){
  $(window).scroll(function(){
    if($(window).scrollTop()>0){
      //check if it is visisble
      if($('#nav-part-to-hide').is(':visible')) {
        //if yes then lets hide it
        $('#nav-part-to-hide').slideUp();           
      }
    } else {
      if(!$('#nav-part-to-hide').is(':visible')) {
        $('#nav-part-to-hide').slideDown();        
      }
    }
  });
});
body
{
  height:1000px;  
}
#sticky-navbar
{
  position:fixed;
  top:0;
  left:0;
  width:100%;
  height:80px;
}
#nav-part-to-hide
{
  height:40px;
  width:100%;
  background:#333;
  color:#fff;
}
#nav-part-stays
{
  height:40px;
  width:100%;
  background:#bbb;
  color:#333;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>
  <div id="sticky-navbar">
    <div id="nav-part-to-hide">
      this conetent hides
    </div>
    <div id="nav-part-stays">
      this conetent stays on page
    </div>
  </div>  
</body>

Upvotes: 0

justinw
justinw

Reputation: 3966

The effect, from the website you linked, is actually quite easy to do.

Firstly, you want your header element to have position: fixed; there is no need to add this dynamically via javascript. It should have this property by default (as it shows in the website you linked).

What they are doing is hiding the top navigation which is within the header at a certain scroll point.

You can use jquery to do this very simply.

DEMO

var $el = $('header .two');
$(window).scroll(function(){
    if ($(this).scrollTop() > 200) {
        $el.addClass('hide');
    } else {
        $el.removeClass('hide');
    }
});
* {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

body {
    margin: 0;
    padding: 0;
}

header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    text-align: center;
}

header .one {
    height: 20px;
    width: 100%;
    background: lime;
    position: relative;
    z-index: 10;
}

header .one.hide {
    height: 0;
}

header .two {
    background: red;
    height: 40px;
    position: relative;
    z-index: 20;
    -webkit-transition: -webkit-transform .25s;
    transition: transform .25s;
}

header .two.hide {
    -webkit-transform: translateY(-20px);
    transform: translateY(-20px);
}

main {
    background: lightblue;
    height: 1200px;
    width: 100%;
    padding-top: 60px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<header>
    <div class="one">div</div>
    <div class="two">fixed</div>
</header>
<main>
    content
</main>
<footer>footer</footer>

Upvotes: 3

Alex
Alex

Reputation: 8695

You have to check .scrollTop when is reached to 84. In addition, you don't need to use jquery .animate function, you can achieve that effect by css transition.

Jsfiddle

Upvotes: 2

Related Questions