Position fixed acting like position relative ( scrolling with page ) - javascript

I'm styling an element with position fixed and other css in a certain condition ( basically if the user scrolls up ), but the element is behaving like a relative positioned element. In other words, it is scrolling with the page and not remaining fixed.
I tried isolating this issue, but this issue only exists in this site as a whole and I need it to work in this site.
var lastScrollTop = 0;
$(window).scroll(function(){
var st = $(this).scrollTop();
if(st<=lastScrollTop){
//scroll up
if($(this).scrollTop()>235) $('#searchInput').removeClass('slideIn').addClass('stickySearch');
else $('#searchInput').removeClass('stickySearch').addClass('slideIn');
}
else $('#searchInput').removeClass('stickySearch').removeClass('slideIn');
lastScrollTop = st;
});
Right now the class .slideIn has no styling associated with it, but .stickySearch does.
Here is the CSS:
.stickySearch{
width:56% !important;
position:fixed !important;
left:0;
right:0;
}
I checked in developer tools and the class is being applied and the styles are being applied, but the position fixed is just not working.
Here is a live URL: http://goo.gl/ns6UEQ
Note, it helps to have a small window in height so you can scroll. Scroll down so that the header is hidden up top and then scroll up and the search bar should appear, but the moment the header comes back into view the search bar will go back into place in the header.

This is a bug that exists in CSS and in Chrome and Firefox's implementation of CSS.
When you have a parent element that has backface-visibility or is transformed, its children can not be fixed.
More here: http://www.sitepoint.com/forums/showthread.php?1129352-CSS3-tip-of-the-week-No-1&highlight=chrome+bug+fixed
Solution: remove the transform and backface visibility styling from #container

Change the if statement to something like below
var lastScrollTop=0;
$(window).scroll(function(){
if($(this).scrollTop()>150 && lastScrollTop>$(this).scrollTop()){
$('#fixedinput').addClass('fixed');
} else {
$('#fixedinput').removeClass('fixed');
}
lastScrollTop=$(this).scrollTop();
});
JSFiddle demo
As you scroll down past the grey part the will not be fixed, but once you start scrolling up it will.

Related

Scroll to bottom button behaviour when scroll is 100% bottom

I am using jquery-smooth-scroll for controlling anchor scrolling. There is a feature/option to decide behaviour after scroll. I chose to hide the button after it gets to the bottom anchor. I then implemented some jquery to bring that button back when scroll was no longer 100% at the bottom of the page.
What I am struggling to do is make sure that the button always fades away when scroll is 100% down. The same way a standard back to top works but opposite ends of the page in my case.
Please see this fiddle I have put together https://jsfiddle.net/k253jvt8/
/* show and hide button*/
$(window).bind("mousewheel DOMMouseScroll scroll", function (e) {
if (document.body.scrollTop == 0) {
$('.saveForm').fadeIn();
//below isnt working to fade away .saveform when scroll is 100% bottom
} else {
$('.saveForm').fadeOut();
}
});
The above is the code I use to bring back the button after it disappears, but then cant get it to disappear again when manually scroll to the bottom, it only disappears again when I use the button to get to the bottom - have a play with my fiddle and you will see what I mean.
In your fiddle, your wrapping <div class="reportFormPage"> is positioned absolute in relation to the document.
As a result your <body> element does not take it in to account when determining its height; hence it always has a height value of 0. Because of this your 'else' condition never occurs.
Removing the position: absolute; css rule resolves this issue.
Try this
if ($(window).scrollTop() ==0) {
$('.saveForm').fadeIn();
} else if($(window).scrollTop() < $(document).height()) {
$('.saveForm').fadeOut();
}
});
along with removing position:absolute as dommmm has said.
Here is the working fiddle https://jsfiddle.net/sd6sh4v6/2/
See if you like the change I brought to your smoothScroll by using no-js fallback.

Translate div on scroll

I have a div in a div.
The first div has a unknown height. The second one has the height of 125px.
I want to make the second one a sticky div which is only sticky in this div.
The grey box is the container and the social media div next to it should be sticky.
After the container more content will come, so I cant use position: fixed. I tried to use position: absolute and change the top value or the transform: translate, but when I Do that Chrome is jittering around.
Code that I tried to use:
$offset = $(".social-media").offset().top;
$containerHeight = $(".sticky-container").height();
$bottom = $containerHeight + $(".sticky-container").offset().top;
$maxPoint = $containerHeight - $(".social-media").height();
$(window).scroll(function(){
if($(window).scrollTop() >= $offset){
if($(window).scrollTop() >= $bottom){
$(".social-media").css({transform: "translate(0px,"+$maxPoint+"px)"});
}else{
$scroll = $(window).scrollTop() - $offset;
$(".social-media").css({transform: "translate(0px,"+$scroll+"px)"});
}
}else{
$(".social-media").css({transform: "translate(0px,0px)"});
}
});
Since the jsbin you provided shows the solution works without jittering, the problem might lie in the repaints triggered by other elements of your site, not the code you pasted. Have a look at the Google's repaint optimization guidelines, it might help you identify the issues that cause the jittering.

Grow height of element on scroll safari bug

I have a fixed header div with a 200px height. On scroll, the height is reduced until it reaches a certain height (40px). This gives the effect of the header turning into a fixed header once user reaches the content container.
This works smooth in Firefox and Chrome, however, Safari is glitchy. Particularly, when user scrolls back up and the header increases in height. See JS Fiddle here.
$(window).scroll(function () {
var $scrollTop = $(window).scrollTop(),
$element = $('.content-container').offset().top,
$distance = ($element - $scrollTop);
if ($scrollTop < $element - $newHeight) {
header.height($distance);
}
});
What is causing safari to glitch so much on the height increase? What can I do to smooth this out?
The way to smoothen out this effect in Safari is to change the approach all together. Instead of changing the height of the header on scroll, make the content container position:relative; and set a higher z-index. Then when scroll reaches the bottom of your header (or wherever point you'd like to make the header sticky), change the z-index of the header to be higher than the content container and set it's height to your desired size.
Here is the JS. Please see this JS Fiddle for demo and the rest of code (css, html).
$(window).scroll(function () {
if ($scrollTop > $element - $newHeight) {
header.height($newHeight).css("z-index", 1000);
}
else {
header.css("z-index", 100).height($oldHeight);
}
});
Also, consider using requestAnimationFrame instead of onScroll. It''ll be lighter weight.

Using Jquery to toggle on and off items based distance to top

I am creating a site in which there are a number of fixed background images that you scroll past. Associated with each fixed background is an image slider (or text) that is hidden until the title is clicked on. These items are all fixed positioned.
I was able to make this work by using z-index to place items in order top to bottom/first to last and then have each disappear in turn using:
$(document).scroll(function() {
$('#porttitle').toggle($(this).scrollTop() < 225);
});
However, I am unable to use this because the length pixel distance down on the page changes based on the screen size. I am pretty new to Jquery but wanted to try to use .offset .top to have the item disappear not based on the pixel length to the top of the page but instead when an element appears on the screen. This is what I have so far but it isn't seeming to work.
$(document).scroll(function() {
$('#porttitle').toggle($(this).scrollTop() < $(‘article.post-100’).offset().top);
});
Here is the link to the site: http://s416809079.onlinehome.us (not final location - just developing)
Any thoughts?
Thanks!
I think this may work for you, read the comments on the code for a line by line explanation.
Working Example
$(window).scroll(function () { // When the user scrolls
$('div').each(function () { // check each div
if ($(window).scrollTop() < $(this).offset().top) { // if the window has been scrolled beyond the top of the div
$(this).css('opacity', '1'); //change the opacity to 1
} else { // if not
$(this).css('opacity', '0'); // change the opacity to 0
}
});
});
I'm conditionally changing the opacity rather than using toggle because:
...jQuery does not support getting the offset coordinates of hidden
elements or accounting for borders, margins, or padding set on the
body element.
While it is possible to get the coordinates of elements with
visibility:hidden set, display:none is excluded from the rendering
tree and thus has a position that is undefined.
Related documentation:
.offset()
.each()
.scroll()
.scrollTop()

Sticky div offset from top window using waypoint

I am hoping someone can kindly help. I'm by no means a programmer, and I'm trying to learn how to create a slightly different sticky div than normal. This is what I want to achieve:
when the div #projectwrapper scrolls up the screen, and is 150px from the top of the window, it should stick and stay there while the rest of the page scrolls
when scrolling back down the page, the div should return to its normal place in the page when that comes into view.
I have been trying the demos and examples, and I can nearly get it working. But it will only get activated when it goes to the very top of the window, and it stick at the very top. However I need the activation and sticking to happen 150px from the top.
This is what I have so far.
$(document).ready(function() {
$('#projectwrapper').waypoint(function(event, direction) {
}, {
offset: 150
}).find('#projectdescription').waypoint(function(event, direction){
$(this).parent().toggleClass('sticky', direction === "down");
event.stopPropagation();
});
});
I haven't used waypoint. You can do using some simple jQuery:
var projectWrapperPosition = $('#projectwrapper').position().top; //div position
$(window).scroll(function() { //when window scrolls
if($(window).scrollTop() > (projectWrapperPosition - 150)) //check if position of the window is 150px or smaller than the position of specified div has
$('#projectwrapper').addClass('change-position'); //.change-position position fixed the div
else
$('#projectwrapper').removeClass('change-position');
});
css:
.change-position {
top:150px;
position:fixed;
width:100%;
background:red;
}
Check demo: http://jsbin.com/uxizab/2/ (scroll to see the effect)

Categories

Resources