I want to transition the background colour of a fixed header element on scroll. So as a user scrolls down a full page block website, the header subtly changes to complement the block colours. I have almost achieved this on a Pen , however I can't quite work out how to measure how much has been scrolled as a flag for when to change.
Some extra info: The scroll amount to change at is 400px. The background colours are stored and fetched in an array. For reference my jQuery code is below:
$(document).ready(function(){
var bgArray = ["#252525","#333333","#454545","#777777"];
var scrollHeight = 400;
var scrolled = $(window).scrollTop(); //What is this measuring?
$(window).scroll(function() { //Can these conditions be neatened into one function?
if(scrolled < scrollHeight) {
$('header').css('background', bgArray[0]);
}
if(scrolled > scrollHeight) { // i.e more than 400px
$('header').css('background', bgArray[1]);
}
// and so on (800, 1200...)
})
})
Please refer to the Pen for full code. Any suggestions are greatly appreciated!
To set a background
for the header
based on the current block in view below the header
while scrolling:
because header
has fixed position , we can get the amount by which window has scrolled by using $header.offset().top
,
( index of the current block in view ) is the ratio of ( the amount by which window has scrolled ) to the ( height of each block ),
now adjusting for the height of the header
, the index of the current block in view is Math.floor(($header.offset().top + headerHeight) / sectionHeight)
.
See simplified demo below:
$(function() { var $header = $('header'), $window = $(window), bgArray = ["#252525", "red", "blue", "green"], headerHeight = 50, sectionHeight = 400; $window.scroll(function() { $header.css('background', bgArray[Math.floor(($header.offset().top + headerHeight) / sectionHeight)]); }); });
:root { --header: 50px; /* header height */ --block: 400px; /* block height */ } * { box-sizing: border-box; /* include padding in width / height calculations */ } body { margin: 0; /* reset default margin of body */ } header { height: var(--header); /* sets height of header */ position: fixed; top: 0; left: 0; width: 100%; color: #FFF; padding: 12px 0; background: #252525; /* initial background */ transition: background 1s ease; } .container { margin: 0 auto; } .wrap>div { height: var(--block); /* sets height of each block */ text-align: center; } p { margin: 0; /* reset margin of p */ } .block-1 { background: #27AACC; color: #FFF; } .block-2 { background: #668E99; color: #FFF; } .block-3 { background: #4AFFC1; color: #444; } .block-4 { background: #FF8F8A; color: #FFF; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <header> <div class="container"> Website Title. </div> </header> <div class="wrap"> <div class="block-1"> <div class="container"> <p>This pen was made to solve a problem on a project...</p> </div> </div> <div class="block-2"> <div class="container"> <p>...I needed a sticky header with thr right bg colour.</p> </div> </div> <div class="block-3"> <div class="container"> <p>But this conflicted with the footer, which was the same colour...</p> </div> </div> <div class="block-4"> <div class="container"> <p>So the solution was to subtley change the header's bg on scroll</p> </div> </div> </div>
Check the top
of each block
with respect to how much the window has been scrolled ( scrollTop
) using $(window).scrollTop() > $('.block-1').offset().top
. So now we can use this to change color on entering the block - see demo below:
$(document).ready(function() { var $header = $('header'), $window = $(window), bgArray = ["#252525", "#333333", "#454545", "#777777"], headerHeight = $header.outerHeight(); $window.scroll(function() { for (var i = 1; i < 5; i++) { if ($window.scrollTop() + headerHeight > $('.block-' + i).offset().top) { $header.css('background', bgArray[i - 1]); } } }); });
@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,700'); body { font-family: 'Roboto', sans-serif; font-size: 30px; font-weight: 300; margin-top: 0; } header { width: 100%; height: 50px; line-height: 50px; position: fixed; font-size: 24px; font-weight: 700; color: #FFF; padding: 12px 0; margin: 0; background: #252525; transition: background 1s ease; } .wrap { padding-top: 74px; margin: 0; } .container { width: 960px; margin: 0 auto; overflow: hidden; } .block-1, .block-2, .block-3, .block-4 { height: 400px; text-align: center; } p { margin-top: 185px; } .block-1 { background: #27AACC; color: #FFF; } .block-2 { background: #668E99; color: #FFF; } .block-3 { background: #4AFFC1; color: #444; } .block-4 { background: #FF8F8A; color: #FFF; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <header> <div class="container"> Website Title. </div> </header> <div class="wrap"> <div class="block-1"> <div class="container"> <p>This pen was made to solve a problem on a project...</p> </div> </div> <div class="block-2"> <div class="container"> <p>...I needed a sticky header with thr right bg colour.</p> </div> </div> <div class="block-3"> <div class="container"> <p>But this conflicted with the footer, which was the same colour...</p> </div> </div> <div class="block-4"> <div class="container"> <p>So the solution was to subtley change the header's bg on scroll</p> </div> </div> </div>
Note that this solution needlessly loops through the sections on each scroll update called by the browser - and I don't like the look of it.
you are using scrolled as a fixed variable you should use it directly in your condition
this will make it dynamic for all elements inside wrap div
$(document).ready(function(){
var bgArray = ["#252525","#333333","#454545","#777777"];
$(window).scroll(function() {
for(var i = 1; i < bgArray.length; i++) {
if ($(window).scrollTop() > $('.wrap div:nth-child(' + i + ')').offset().top) {
$('header').css('background', bgArray[i-1]);
}
}
});
})
Try Like this:
$(document).ready(function(){
var bgArray = ["#252525","#333333","#454545","#777777"];
var scrollHeight = 400;
$(window).scroll(function() {
var scrolled = $(window).scrollTop();
var index=Number((scrolled/scrollHeight).toFixed());
if(bgArray[index]!=undefined)
$('header').css('background', bgArray[index]);
});
})
This is current scroll, so it should be inside: $(window).scrollTop()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.