76

I wonder how to make a sticky header shrink(with animation) when you scroll down the page and goes back to normal state when the page is scrolled up to the top. Here are two examples to clearify:

http://themenectar.com/demo/salient/

http://www.kriesi.at/themes/enfold/

I get the part to make it fixed, but how should I do to shrink my header when the user scrolls down?

Thanks a ton

asked May 8, 2013 at 13:28
2
  • 6
    Post your code. Let's see what you have tried thus far. Commented May 8, 2013 at 13:29
  • Is there a name for this type of animated header? Commented Mar 21, 2017 at 1:23

6 Answers 6

107

This should be what you are looking for using jQuery.

$(function(){
 $('#header_nav').data('size','big');
});
$(window).scroll(function(){
 if($(document).scrollTop() > 0)
{
 if($('#header_nav').data('size') == 'big')
 {
 $('#header_nav').data('size','small');
 $('#header_nav').stop().animate({
 height:'40px'
 },600);
 }
}
else
 {
 if($('#header_nav').data('size') == 'small')
 {
 $('#header_nav').data('size','big');
 $('#header_nav').stop().animate({
 height:'100px'
 },600);
 } 
 }
});

Demonstration: http://jsfiddle.net/jezzipin/JJ8Jc/

answered May 8, 2013 at 13:50
Sign up to request clarification or add additional context in comments.

5 Comments

Your solution is almost perfect, but I wanted to addClass() instead of adjusting the height BUT without losing the animation. Possible?
Does anyone knows why this works every browser except Safari for iOS? cc @jezzipin
I'm afraid I'm not sure. Now that Safari is only available on the Mac I do not have the capacity to test this on Safari (as I hate Macs and avoid them at all costs) so I'm afraid I won't be able to come up with a solution for you.
It would be more efficient to just add/remove a class and do the size transition with a CSS transformation.
As I mention below on Sinky's answer, using CSS limits your browser support meaning that the effect will not occur on IE8 and IE9. If you want full browser support then you will need to use this method over CSS.
88

Here a CSS animation fork of jezzipin's Solution, to seperate code from styling.

JS:

$(window).on("scroll touchmove", function () {
 $('#header_nav').toggleClass('tiny', $(document).scrollTop() > 0);
});

CSS:

.header {
 width:100%;
 height:100px;
 background: #26b;
 color: #fff;
 position:fixed;
 top:0;
 left:0;
 transition: height 500ms, background 500ms;
}
.header.tiny {
 height:40px;
 background: #aaa;
}

http://jsfiddle.net/sinky/S8Fnq/

On scroll/touchmove the css class "tiny" is set to "#header_nav" if "$(document).scrollTop()" is greater than 0.

CSS transition attribute animates the "height" and "background" attribute nicely.

answered Sep 3, 2013 at 7:06

4 Comments

Nice work. Bare in mind that for user of IE9 and IE8 the transition will not kick in as this property is unsupported in these browsers. Apart from that, it's a great solution as it good for anyone wanting to cut down the amount of dom manipulation in their code. caniuse.com/#search=transition
@Sinky You could do the class toggle in one line $('#header_nav').toggleClass('tiny', $(document).scrollTop() > 0);
Should be the accepted answer. By far the cleanest solution.
A bit old, but one should add a $(window).trigger("scroll") if page is not displayed at top initially.
5

http://callmenick.com/2014/02/18/create-an-animated-resizing-header-on-scroll/

This link has a great tutorial with source code that you can play with, showing how to make elements within the header smaller as well as the header itself.

answered Oct 17, 2014 at 10:39

1 Comment

The link is dead now
3

Based on twitter scroll trouble (http://ejohn.org/blog/learning-from-twitter/).

Here is my solution, throttling the js scroll event (usefull for mobile devices)

JS:

$(function() {
 var $document, didScroll, offset;
 offset = $('.menu').position().top;
 $document = $(document);
 didScroll = false;
 $(window).on('scroll touchmove', function() {
 return didScroll = true;
 });
 return setInterval(function() {
 if (didScroll) {
 $('.menu').toggleClass('fixed', $document.scrollTop() > offset);
 return didScroll = false;
 }
 }, 250);
 });

CSS:

.menu {
 background: pink;
 top: 5px;
}
.fixed {
 width: 100%;
 position: fixed;
 top: 0;
}

HTML:

<div class="menu">MENU FIXED ON TOP</div>

http://codepen.io/anon/pen/BgqHw

answered Sep 24, 2014 at 11:58

1 Comment

Very helpful link and improved solution taking into account performance issues with running code on every scroll event...thanks! You cached the $(document) element, but you could also cache the $('.menu) el so the code doesn't retrieve it every time.
0

I did an upgraded version of jezzipin's answer (and I'm animating padding top instead of height but you still get the point.

 /**
 * ResizeHeaderOnScroll
 *
 * @constructor
 */
var ResizeHeaderOnScroll = function()
{
 this.protocol = window.location.protocol;
 this.domain = window.location.host;
};
ResizeHeaderOnScroll.prototype.init = function()
{
 if($(document).scrollTop() > 0)
 {
 $('header').data('size','big');
 } else {
 $('header').data('size','small');
 }
 ResizeHeaderOnScroll.prototype.checkScrolling();
 $(window).scroll(function(){
 ResizeHeaderOnScroll.prototype.checkScrolling();
 });
};
ResizeHeaderOnScroll.prototype.checkScrolling = function()
{
 if($(document).scrollTop() > 0)
 {
 if($('header').data('size') == 'big')
 {
 $('header').data('size','small');
 $('header').stop().animate({
 paddingTop:'1em',
 paddingBottom:'1em'
 },200);
 }
 }
 else
 {
 if($('header').data('size') == 'small')
 {
 $('header').data('size','big');
 $('header').stop().animate({
 paddingTop:'3em'
 },200);
 } 
 }
}
$(document).ready(function(){
 var resizeHeaderOnScroll = new ResizeHeaderOnScroll();
 resizeHeaderOnScroll.init()
})
answered Feb 21, 2017 at 22:13

Comments

0

I took Jezzipin's answer and made it so that if you are scrolled when you refresh the page, the correct size applies. Also removed some stuff that isn't necessarily needed.

function sizer() {
 if($(document).scrollTop() > 0) {
 $('#header_nav').stop().animate({
 height:'40px'
 },600);
 } else {
 $('#header_nav').stop().animate({
 height:'100px'
 },600);
 }
}
$(window).scroll(function(){
 sizer();
});
sizer();
answered May 18, 2020 at 18:48

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.