7
\$\begingroup\$

When I had to create a fixed header on scroll, I found a few examples on Stack Overflow but they were terrible in the sense that they relied on a fixed page height. Have a look at what I created which does not rely on a wrapper around the header and the content.

Default

default

On Scroll

enter image description here

Demo on CodePen.


HTML

<header>
  <div class="header-banner">
    <a href="/" class="logo"></a>
    <h1>Art in Finland</h1>
  </div>

  <nav>
    <ul>
      <li><a href="/archive">Archive</a></li>
      <li><a href="/events">Events</a></li>
      <li><a href="/contact">Contact</a></li>
    <ul>
  </nav>
</header>

CSS

header {
  height:360px;
  z-index:10;
}
.header-banner {
  background-color: #333;
  background-image: url('http://37.media.tumblr.com/8b4969985e84b2aa1ac8d3449475f1af/tumblr_n3iftvUesn1snvqtdo1_1280.jpg');
  background-position: center -300px;
  background-repeat: no-repeat;
  background-size: cover;
  width: 100%;
  height: 300px;
}

header .logo {
  background-color: transparent;
  background-image: url('http://www.futhead.com/static//img/14/clubs/1887.png');
  background-position: center top;
  background-repeat: no-repeat;
  position: absolute;
  top: 72px; 
  height: 256px;
  width: 256px;
}
header h1 {
  position: absolute;
  top: 72px; 
  left: 240px;
  color: #fff;
}

.fixed-header {
  position: fixed;
  top:0; left:0;
  width: 100%; 
}

nav {
  width:100%;
  height:60px;
  background: #292f36;
  postion:fixed;
  z-index:10;
}

nav ul { 
  list-style-type: none;
  margin: 0 auto;
  padding-left:0;
  text-align:right;
  width: 960px; 
}
nav ul li { 
  display: inline-block; 
  line-height: 60px;
  margin-left: 10px;
}
nav ul li a {
  text-decoration: none; 
  color: #a9abae;
}


/* demo */
.content{ width: 960px; max-width: 100%; margin:0 auto; padding-top: 60px; }
article { width: 720px; float: left; }
article p:first-of-type { margin-top: 0; }
aside { width: 120px; float: right; }
aside img { max-width: 100%; }
body { 
  color: #292f36;
  font-family: helvetica;
  line-height: 1.6;
}

jQuery

$(window).scroll(function(){
    if ($(window).scrollTop() >= 300) {
       $('nav').addClass('fixed-header');
    }
    else {
       $('nav').removeClass('fixed-header');
    }
});
\$\endgroup\$
12
\$\begingroup\$

HTML

You might want to id that nav. It's because it might not be the only nav on the page, and the JS will pick it up and add .fixed-header to it. Something like:

<nav id="main-navigation">

CSS

On the CSS part, if only the nav gets a the .fixed-header class, you might want to consider declaring the CSS for .fixed-header like:

nav.fixed-header{...}

That way, it only applies to nav with that class. Scenario: You have another header that wants to be fixed at a certain position. It's logical to name it .fixed-header but it's not a nav. If you didn't do it this way, this style will also apply to the sidebar.

JS

It would be better if you cached the value of jQuery DOM pickups, rather than re-fetching them every time the scroll event fires. Additionally, as mentioned in the HTML section, it's better to identify that <nav>. This time, it's for performance.

When you do $('nav'), what jQuery does is pick up all <nav> in the page, and stores them in an array. When you call functions on it, jQuery loops through each one of them, and applies the function. You would want to avoid that looping, and so, you must limit what is being looped by being more specific with your query. Querying an id would be best since id should only happen once on the page.

var $window = $(window);
var nav = $('#main-navigation');
$window.scroll(function(){
    if ($window.scrollTop() >= 300) {
       nav.addClass('fixed-header');
    }
    else {
       nav.removeClass('fixed-header');
    }
});
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.