I have a header on a website that is fixed 20px from the top of the page.
However, I want this to catch the top of the page when scrolling and become fixed to the top of the screen once the user has scrolled that 20px down.
CSS
#header{
padding: 0px 0px 0px 0px;
background: url(../images/header-fill2.jpg) repeat-x top;
position: fixed;
height: 60px;
width: 100%;
top: 20px;
z-index: 5000;
}
I imagine some form of JavaScript is required but have little to no JavaScript experience, so any help would be greatly appreciated.
Just listen for the scroll event and read the value of $(window).scrollTop() and set the top according to that.
Something like:
$(window).on('scroll', function() {
$('#header').css('top', $(window).scrollTop() > 20 ? '0px' : '20px');
});
Example on jsFiddle
The scroll event tells you when the window scrolls. Then, use the scrollTop to find out how much closer to 0 to go:
$(window).on("scroll", function() {
$("#header").css("top", Math.max(0, 20 - $(window).scrollTop()));
});
Live Example
Or to avoid constantly re-creating objects:
(function() {
var $wnd = $(window),
$header = $("#header");
$wnd.on("scroll", function() {
$header.css("top", Math.max(0, 20 - $wnd.scrollTop()));
});
})();
Live Example
Thats how I do that with jQuery.
The position is also cached, for performance reasons:
Here is a fiddle:
http://jsfiddle.net/StephanWagner/u3yrS/
$(document).ready(function() {
var cfixed_nav = false, wscroll;
var setScroll = function() {
wscroll = $(window).scrollTop();
var fixed_nav = wscroll > 20; // Set pixel amount here
if (fixed_nav != cfixed_nav) {
$('body')[fixed_nav ? 'addClass' : 'removeClass']('fixed');
cfixed_nav = fixed_nav;
}
};
setScroll();
$(document).scroll(setScroll);
});
With CSS you set the fixed position:
.fixed #header {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%
}
Also remember, that when the header gets the fixed position, those 20px of the header are missing. So you can add a body padding for example:
.fixed {
padding-top: 20px;
}
Or you add an element with 20 Pixel height and swap display none / block depending on the .fixed class in the body
Related
I am trying to fix and animate a header navigation so that it pops down from outside of the browser window when a user scrolls past 80px from the top. I then want to reverse the animation when the user scrolls back past <80px. I have gotten this far (have set throttle function earlier in the code):
var e = $(window).scrollTop();
$(window).on("scroll", throttle(function() {
var t = $(window).scrollTop();
t > 80 ? t > e ? $(header).animate({
top: "-150px"
}, 200) :
At the 'else' point I am totally stuck. I've been looking at other similar functions and trying to interpret the code but really struggling. Any help hugely appreciated.
Why are you comparing it with e (which will be usually 0). That's no point. If you want something to happen when the window's scrollTop becomes 80px, just use the following code. Also please not the single true parameter in the animate's stop() function.
$(function () {
$(".peek-a-boo").css({
top: -200
});
$(window).scroll(function () {
if ($(window).scrollTop() > 80)
$(".peek-a-boo").stop(true).animate({
top: 0
}, 200);
else
$(".peek-a-boo").animate({
top: -200
}, 200);
});
});
* {box-sizing: border-box;}
.peek-a-boo {position: fixed; background-color: #99f; width: 100%; top: 0; left: 0; padding: 5px; text-align: center;}
.heighter {height: 1000px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<header class="peek-a-boo">Peek</header>
<div class="heighter"></div>
I want a sharing wrapper to stick to the top of the window when it reaches the top on scroll. It just appends a sticky class to the element with a fixed position. However, how would I go about adding an offset to the top? I have a fixed header that's 60px in height and currently the div is sticking to the very top of the window, hiding the top 60px of it. Instead, I want it to stick 60px from the top of the window.
My JS:
(function () {
var $stickyShare, $window, top;
$window = $(window);
$stickyShare = $('.share-container');
top = $stickyShare.offset().top;
$window.scroll(function () {
return $stickyShare.toggleClass('sticky-fixed', $window.scrollTop() > top);
});
}.call(this));
A JSfiddle: http://jsfiddle.net/h6afrtpk/1/
You can update your .sticky-fixed class to set top to 60px instead of 0.
.share-container.sticky-fixed {
position: fixed;
top: 60px;
left: auto;
right: auto;
background-color: #fff;
border-bottom: 1px solid #ccc;
}
And update the function to check against top - 60.
return $stickyShare.toggleClass('sticky-fixed', $window.scrollTop() > top - 60);
A Fiddle
I have a "sticky" sidebar contact form with jQuery, which turns to fixed-positioned div when page is scrolled down. My problem is that it overlaps the footer when scrolled down all the way. Is there a way where I could set it not to scroll down any further once its bottom margin starts hitting the footer? I'm not sure how I would detect that event, if at all possible, because it's a responsive site and footer's height varies.
CSS:
.sticky {
margin-top: 38px;
max-width: 300px;
padding-top: 20px;
z-index: 0;
}
jQuery:
jQuery(function(){ // document ready
if (!!jQuery('.sticky').offset()) { // make sure ".sticky" element exists
var stickyTop = jQuery('.sticky').offset().top; // returns number
jQuery(window).scroll(function(){ // scroll event
var windowTop = jQuery(window).scrollTop(); // returns number
if (stickyTop < windowTop){
jQuery('.sticky').css({ position: 'fixed', top: 0 });
}
else {
jQuery('.sticky').css('position','static');
}
});
}
Thanks all in advance.
I am using following code to make a menu sticky when the window is scrolled down. It works fine if the window height is enough to scroll down the full header area, but it it creates problem is the height is just close enough to scroll, in that case it starts flashing and does not let scroll.
Here is the demo of the problem, refresh couple of times and try to scroll down. I have set the body height to 622px to reproduce the problem:
http://jsbin.com/ipEROYO/1
Here's the code I'm trying:
$(document).ready(function() {
var stickyNavTop = $('.nav').offset().top;
var stickyNav = function(){
var scrollTop = $(window).scrollTop();
if (scrollTop > stickyNavTop) {
$('.nav').addClass('sticky');
} else {
$('.nav').removeClass('sticky');
}
};
stickyNav();
$(window).scroll(function() {
stickyNav();
});
});
CSS:
.sticky {
position: fixed;
width: 100%;
left: 0;
top: 0;
z-index: 100;
border-top: 0;
}
It's because when you are setting the navigation div to position:fixed you are shortening the length of the document (by the height of that div), which then causes the scroll bar to go away, which causes the scrollTop() value to be 0 which causes the .nav div to be position:static and it is an endless cycle if you keep scrolling down.
Here's my quick solution:
$(document).ready(function() {
var height = $('.nav').outerHeight();
$(window).scroll(function() {
if($(this).scrollTop() > height)
{
$('.nav').css('position','fixed');
$('body').css('padding-bottom',height+'px');
}
else if($(this).scrollTop() <= height)
{
$('.nav').css('position','static');
$('body').css('padding-bottom','0');
}
});
$(window).scroll();
});
Just modified the JSbin. Check it out. You were really close, just doing more than you needed to like setting the sticky class on load of the page rather than when the function first runs. Let me know if this helps.
try that
$(window).scroll(function () {
var scroll_top = $(this).scrollTop();
if (scroll_top > 66) {//height of header
$('.nav').addClass('sticky');
} else {
$('.nav').removeClass('sticky');
}
});
Strongly recommend a CSS only solution for this layout. No one seems to know what to call this method, so I've been referring to it as the absolute stretch technique, but in my experience it works beautifully across mobile devices and PC's including all major browsers except IE6 and below. There is some discussion of it here.
body, .header, .nav, .mainContent{
position: absolute;
top: 0;
left: 0;
right: 0;
}
body, .mainContent {
bottom: 0;
}
.header{
height: 120px;
}
.nav{
height: 70px;
top: 120px;
}
.mainContent{
top: 190px;
overflow: auto;
}
You'll find you can get very robust, concise, well organized layouts in this manner, and fixed headers, footers and sidebars follow very easily.
I've a sticked element which gets the top-alignment from current scroll-offset. Problem is, that the layout is not "retriggerd" if the space from it is free. So there stays a ghost-gap where the sticked element was...
http://fiddle.jshell.net/pPc4V/
The markup is pretty simple:
...
as well as the js:
var $win = $(this);
var sticked = document.querySelector('a.sticked');
$win.on('scroll', function () {
var scrollTop = $win.scrollTop();
sticked.style.top = scrollTop + 'px';
// $win.resize();
});
...and the css looks good so far:
a {
display: inline-block;
width: 90px;
height: 90px;
background: deepskyblue;
}
.sticked {
position: relative;
top: 0;
left: 0;
background: tomato;
}
I tried to trigger the resize-event on scroll (as you see above uncommented), but no success! Any ideas, how to retrigger the layout so that the free-gap is filled with the next floated element?
Update
To clarify what I mean I made a simple image-timelime:
Step 1
Step 2
Step 3
The issue is that you are setting position fixed on an element which is displayed inline. That will cause that space to occur. I have redid your jsFiddle with proper alignment.
To fix it, I added the class "stuck" only when the document's scrollTop position is greater than the scrollTop position of your target element.
jsFiddle: http://fiddle.jshell.net/pPc4V/44/
HMTL:
<div id="grid">
etc...
</div>
CSS:
#grid {
height:1000px;
overflow:hidden;
float:left
}
#grid > a {
display: inline-block;
width: 90px;
height: 90px;
background: deepskyblue;
}
.stuck {
position: fixed;
background: navy !important;
}
JS:
$(window).on('scroll', function () {
var $doc = $(document),
parentElement = $('#grid'),
childToGetStuck = parentElement.find('a:nth-child(5)');
if ($doc.scrollTop() > childToGetStuck.scrollTop()) {
childToGetStuck.addClass('stuck');
//console.log($('.stuck').scrollTop())
} else {
childToGetStuck.removeClass('stuck');
}
});