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');
}
});
2 Answers 2
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');
}
});
You have an error in your code: if the user scrolls, the page navbar is not fixed to top of the page.
I will give you an example with the source code. Let's try the below code.
Source Code : Sticky Navbar
HTML
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
CSS
.sticky {
position: fixed;
top: 0;
width: 100%;
left: 0;
right: 0;
}
.sticky + .content {
padding-top: 60px;
}
Use this JavaScript code. This code will work when the user scrolls the page 300px from the top; the navbar will stick to the page.
window.onscroll = function() {myFunction()};
var navbar = document.getElementById("navbar");
var sticky = navbar.offsetTop;
function myFunction() {
if (window.scrollY > 300) {
if (window.pageYOffset >= sticky) {
navbar.classList.add("sticky")
} else {
navbar.classList.remove("sticky");
}
}else{
navbar.classList.remove("sticky");
}
}
This will help you to create a sticky navbar.