Issue
I have some simple Javascript. When scrolling down the header disappears. When scrolling up the header appears. This all works fine:
var prevScrollpos = window.pageYOffset;
window.onscroll = function() {
var currentScrollPos = window.pageYOffset;
if (prevScrollpos > currentScrollPos) {
document.querySelector("header").style.top = "0";
} else {
document.querySelector("header").style.top = "-7.2rem";
}
prevScrollpos = currentScrollPos;
}
header {
background-color: rgb(255, 255, 255);
height: 7.2rem;
position: fixed;
top: 0;
left: 0;
right: 0;
transition: top 0.2s ease-in-out;
z-index: 100;
}
However, when the page is at the top of the window, and the user scrolls down, even by 1px, the header disappears, leaving a great big blank space where the header used to be. Is it possible that this show / hide on scroll script only starts once the header has disappeared off the top of the browser window? i.e. the effect only kicks in after the height of the header has been scrolled (so that the user doesn't see the empty white space) i.e. the header is not fixed, but relative. It scrolls up and out of the window. Then the effect starts: scroll down = no header / scroll up = header is fixed at the top of the window.
Solution
There are 2 ways you can do this, depending on what behaviour you would like. In both cases we want to get the header element and it's position:
var headerDiv = document.querySelector("header");
var headerBottom = headerDiv.offsetTop + headerDiv.offsetHeight;
This means that in the scroll, we can check if we have passed the header:
if (window.pageYOffset >= headerBottom)
1: Header scrolls out of view as normal, Fixed to top on scrolling up
In this version, the header scrolls out of view when scrolling down, but when you start to scroll up it will appear fixed to the top of the screen.
Full Working Example:
var prevScrollpos = window.pageYOffset;
/* Get the header element and it's position */
var headerDiv = document.querySelector("header");
var headerBottom = headerDiv.offsetTop + headerDiv.offsetHeight;
window.onscroll = function() {
var currentScrollPos = window.pageYOffset;
/* if scrolling down, let it scroll out of view as normal */
if (prevScrollpos <= currentScrollPos ){
headerDiv.classList.remove("fixedToTop");
headerDiv.style.top ="-7.2rem";
}
/* otherwise if we're scrolling up, fix the nav to the top */
else{
headerDiv.classList.add("fixedToTop");
headerDiv.style.top = "0";
}
prevScrollpos = currentScrollPos;
}
body{ margin: 0;}
header {
background: blue;
height: 7.2rem;
transition: all 0.2s ease-in-out;
z-index: 100;
}
.content {
height:1000px;
}
header.fixedToTop {
position: fixed;
top: 0;
left: 0;
right: 0;
}
/* add space for fixed header when it's fixed to top */
header.fixedToTop + .content{
margin-top:8rem;
}
<header></header>
<div class="content" id="contentdiv">
<h1>My Page</h1>
<p>Content 1</p><p>Content 2</p><p>Content 3</p><p>Content 4</p><p>Content 5</p>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
</div>
How This Works
We need to remove the fixed positioning from the header and add it to a class (e.g. fixedToTop
) that we will apply on scrolling:
header {
height: 7.2rem;
transition: all 0.2s ease-in-out;
z-index: 100;
}
header.fixedToTop {
position: fixed;
top: 0; left: 0; right: 0;
}
Now the logic for our scroll function is very simple:
- If we're scrolling down then let the header scroll out of view - remove the
fixedToTop
class. - If we are scrolling up, add our
fixedToTop
class which will make it appear
Note, we need to explicitly set the value for top
to make the transition animation to work, so we do that in the code also.
Putting this together, we get the following scroll function:
window.onscroll = function() {
var currentScrollPos = window.pageYOffset;
/* if scrolling down, let it scroll out of view as normal */
if (prevScrollpos <= currentScrollPos ){
headerDiv.classList.remove("fixedToTop");
headerDiv.style.top ="-7.2rem";
}
/* otherwise if we're scrolling up, fix the nav to the top */
else{
headerDiv.classList.add("fixedToTop");
headerDiv.style.top = "0";
}
prevScrollpos = currentScrollPos;
}
2: Header is fixed until we scroll passed where it would normally have disappeared; Fixed to top on on scrolling up
In this case the header is fixed until we scroll passed it's "natural" position where it would disappear.
Working Example:
var prevScrollpos = window.pageYOffset;
/* Get the header element and it's position */
var headerDiv = document.querySelector("header");
var headerBottom = headerDiv.offsetTop + headerDiv.offsetHeight;
window.onscroll = function() {
var currentScrollPos = window.pageYOffset;
/* if we're scrolling up, or we haven't passed the header,
show the header at the top */
if (prevScrollpos > currentScrollPos || currentScrollPos < headerBottom){
headerDiv.style.top = "0";
}
else{
/* otherwise we're scrolling down & have passed the header so hide it */
headerDiv.style.top = "-7.2rem";
}
prevScrollpos = currentScrollPos;
}
header {
background: blue;
height: 7.2rem;
position: fixed;
top: 0;
left: 0;
right: 0;
transition: top 0.2s ease-in-out;
z-index: 100;
}
.content {
height:1000px;
margin-top:8rem; /* add space for fixed header */
}
<header></header>
<div class="content" id="contentdiv">
<h1>My Page</h1>
<p>Content 1</p><p>Content 2</p><p>Content 3</p><p>Content 4</p><p>Content 5</p>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
</div>
How This Works
The logic in your scroll function is like this:
- If we're scrolling up, then show the header:
- If we are scrolling down...
- ...if we've scrolled passed the header, hide it
- ... otherwise show it
Putting this together, we get the following scroll function:
var prevScrollpos = window.pageYOffset; // save the current position
window.onscroll = function() {
var currentScrollPos = window.pageYOffset;
/* if we're scrolling up, or we haven't passed the header, show the header */
if (prevScrollpos > currentScrollPos || currentScrollPos < headerBottom){
headerDiv.style.top = "0";
}
else{
/* otherwise we're scrolling down & have passed the header so hide it */
headerDiv.style.top = "-7.2rem";
}
prevScrollpos = currentScrollPos;
}
Answered By - FluffyKitten
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.