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.
Related
I'm working on a Wordpress blog design, and running into an issue with the entry-header. I would like my entry-header to be offset, going outside the bounds of it's container, yet scrolling with the content, inside the content wrap. Here is a screenshot of what i'm trying to achieve.
]1
I'd like to have the red areas scroll along with the text of the blog post, but so far, the only way I've been able to get the red areas to be offset as seen above, is to set position: absolute. When position is set to relative, it shows up as seen below.
Do you have any ideas that could help me resolve this issue?
Thanks.
give it position relative with higher z-index
position:relative;
z-index:10;
left:-50px;
JSFiddle
As user #divy3993 states a fiddle would be helpful.
Anyway: The overflow of your outer div seems to be hidden. This is the reason why you don't see the left part of your header when position is relative.
Apply the css-property
overflow-x: visible;
to your outer div (the one with the dark background) and the full header should be shown.
EDIT:
Sorry for keep you waiting.. I had a while no look at SO.
Sadly the solution that i was thinking of (with pure CSS) does not work as it is pointed out in https://stackoverflow.com/a/6433475/1402667 the combination of
overflow-x: visible
and
overflow-y: auto
won't work as expected.
So it seems you have to use JavaScript to solve your issue. I had a look at the link that you are pointing out in comments (http://basil-gen.marathonwp.com/blog/) and successfully run the following jQuery code there:
var $headers = $('.site-inner h1');
var $scrollContainer = $('.site-inner .content-sidebar-wrap');
var hideShowHeaders = function(visibleTop, visibleBottom){
$headers.each(function(){
if($(this).show().offset().top < visibleTop || $(this).offset().top + $(this).outerHeight() > visibleBottom){
$(this).hide();
}else{
$(this).show();
}
});
};
$headers.each(function(){
$(this).data('initTop', $(this).position().top);
});
hideShowHeaders($scrollContainer.offset().top, $scrollContainer.offset().top + $scrollContainer.height()); //might consider borders
$scrollContainer.scroll(function(){
$headers.each(function(){
$(this).css('top', $(this).data('initTop') - $scrollContainer.scrollTop() );
});
hideShowHeaders($scrollContainer.offset().top, $scrollContainer.offset().top + $scrollContainer.height()); //might consider borders
});
It essentially repositions the headers whenever your content container is scrolled. When the headers (or a part of those) would not be visible with position:relative those headers are hidden. In all other cases they are shown.
As i mentioned it's jQuery-Code so you need to include jQuery yet and e.g. execute above code inside
$(document).ready(function(){
...code above
});
If you want to straight test it you can browse to your site (http://basil-gen.marathonwp.com/blog/) open Javascript-Console,
inject jQuery via javascript e.g. like
var script = document.createElement('script');
script.src = "http://code.jquery.com/jquery-latest.min.js";
document.getElementsByTagName('head')[0].appendChild(script);
and then execute above code in Javascript-Console (when directly testing it you should not have scrolled before executing javascript code).
I should mention that the code above is not perfect since it only shows and hides headers instead of showing e.g. 50% of it. I couldn't come up quickly with a solution for it. Anyway you could do this with a more complex showHideHeaders-function where marked lines need to be implemented
var hideShowHeaders = function(visibleTop, visibleBottom){
$headers.each(function(){
if($(this).show().offset().top + $(this).outerHeight() < visibleTop){
if($(this).offset().top < visibleTop){
$(this).hide();
}else{
//lower part of this header needs to be displayed
var bottomPxToShow = $(this).offset().top + $(this).outerHeight() - visibleTop;
var hiddenPx = $(this).outerHeight() - bottomPxToShow;
//show lower bottomPxToShow Pxs of header
}
}else if($(this).offset().top + $(this).outerHeight() > visibleBottom){
if($(this).offset().top > visibleBottom){
$(this).hide();
}else{
//upper part of this header needs to be displayed
}
}else{
//show full header
}
});
};
I hope that helps you!
see demo url of the framework i'm using: http://alvarotrigo.com/fullPage/examples/navigationH.html#secondPage
However,using almost same kind of code from above,
when I try to achieve below effect in which title text is excluded from slider. (title text to be static, and content is sliding)
jsfiddle url: http://jsfiddle.net/097wvnot/8/
I can't scroll to see all the content; what's the best code to achieve this effect?
if i want to use the top framework, must i do a lot of hack into its core functions?
if not hacking the top animation framework , what are other recommendations to this effect
Use an absolute positioned element for your title. Fullpage.js calculates the height of your content inside the slide elements. (as they are suppose to be full height...).
If you place anything outside any slide, it would have to be absoluted positioned.
Take a look at the solution I propose: http://jsfiddle.net/097wvnot/11/
I added the following style to your title:
#demo{
position:absolute;
top:50px;
margin: 0;
left:0;
right:0;
text-align:center;
}
It looks like the plugin is calculating the height of the fp-scrollable incorrectly. At least for your use case. I was able to get it looking good by just manually adjusting the fp-scrollable's height attribute to a smaller amount (obviously that is not a long term fix, just something I was doing for testing). I'm not sure if the calculating takes into account your font size, and things like that, so that might effect it.
If you want to hack on the plugin, generally the place you need to make your changes is fairly restricted, and wouldn't be too bad. From the github page. https://github.com/alvarotrigo/fullPage.js/blob/master/jquery.fullPage.js
All you need to do is fix the value being placed into the scrollHeight variable. I'm not sure exactly what it's not accounting for in the scroll height calculation (the scrollHeight needs to be smaller in your case, it's too big), but I think that's an exercise you can try your hand at first :) I've got to get to bed z.z
You also may need to mess with the calculation for the contentHeight, since ostensibly you'll be shrinking the scrollHeight, and the script only puts the scroll bar on there if the content is bigger than the scroll.
function createSlimScrolling(element){
//needed to make `scrollHeight` work under Opera 12
element.css('overflow', 'hidden');
//in case element is a slide
var section = element.closest('.fp-section');
var scrollable = element.find('.fp-scrollable');
//if there was scroll, the contentHeight will be the one in the scrollable section
if(scrollable.length){
var contentHeight = scrollable.get(0).scrollHeight;
}else{
var contentHeight = element.get(0).scrollHeight;
if(options.verticalCentered){
contentHeight = element.find('.fp-tableCell').get(0).scrollHeight;
}
}
var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top'));
//needs scroll?
if ( contentHeight > scrollHeight) {
//was there already an scroll ? Updating it
if(scrollable.length){
scrollable.css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px');
}
//creating the scrolling
else{
if(options.verticalCentered){
element.find('.fp-tableCell').wrapInner('<div class="fp-scrollable" />');
}else{
element.wrapInner('<div class="fp-scrollable" />');
}
element.find('.fp-scrollable').slimScroll({
allowPageScroll: true,
height: scrollHeight + 'px',
size: '10px',
alwaysVisible: true
});
}
}
//removing the scrolling when it is not necessary anymore
else{
removeSlimScroll(element);
}
//undo
element.css('overflow', '');
}
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.
I am trying to duplicate the left nav at http://www.kahuna-webstudio.fr/. If you take a look at http://www.kahuna-webstudio.fr/, and scroll down about 50 pixels or so, you will see a div appear off to the left of the screen that has some navigation in it. I have most of it working, thanks to the help of some of you at stackoverflow. But the one part I do not have working is that the content of my div, images, do not stay stationary in place (or always visible) as you scroll down.
So what I want to happen is: when the div appears at the left of the screen, when the user scrolls down, I want the content of the div to appear always in view.
Right now what I have working is: through animate() I set the height of my left nav div to the document height, and the width grows to 80 pixels, and then some images fadeIn(). But the page is fairly long and as the user scrolls down they are also able to scroll down the height of my left nav div; and I always want the content of my left nav to always appear in view to the user.
I think this person posted a similiar question (Keeping a header always in view) but I am finding it difficult to attach if to my example code. Can anyone help? I appreciate it a lot.
Here is my code:
$(window).scroll(function(){
var wintop = $(window).scrollTop();
var docheight = $(document).height();
var winheight = $(window).height();
var newwidthgrow = 80;
var smallheight = 0;
var smallwidth = 0;
if((wintop > 296)) {
$("#slidebottom").stop().animate({height:docheight +"px"},'fast',function(){
$("#slidebottom").stop().animate({width:newwidthgrow + "px"},'slow',function(){
$("#slidebottomContents").fadeIn();
});
});
}
if((wintop < 25))
{
$("#slidebottom").stop().animate({height:docheight +"px"},'fast',function(){
$("#slidebottomContents").fadeOut(function(){
$("#slidebottom").stop().animate({width:smallwidth + "px"});
});
});
}
});
As far as i'm concerned this can be covered by only css.
To keep the div in the same position you can apply the following css:
css:
div id {
position: fixed;
left: 0px
width: 'your width'
}
position fixed freezes the div in the position you want.
left keeps the div positioned on the left side of you page.
does this answer your question and solve your problem?
if not let me know!
I have a sidebar that contains content larger than the screen. As the user scrolls down I want that content to come into view until the last bit. Then I want it to be fixed so that as much content stays on screen as possible. I actually want it to work exactly like the "Similar Questions" sidebar when you are posting a question in SO. In each of these example links scroll down. In the broken case notice how everything gets all jumpy.
Should work like this = http://jsfiddle.net/mrtsherman/G4Uqm/2/
But broken in this case = http://jsfiddle.net/mrtsherman/G4Uqm/1/
In the broken case it looks like the scroll event is being retriggered when you reach the end of the page. This then causes subsequent scroll events to trigger which then screw everything up. How can I properly handle this case? I just can't figure it out.
$(document).ready(function() {
var dynamic = false;
var topOfSidebar = $("#sidebar").offset().top;
var leftOfSidebar = $("#sidebar").offset().left;
var botOfSidebar = topOfSidebar + $("#sidebar").height();
var botOfScreen = $(window).height() + $(window).scrollTop();
//if sidebar fits on screen then use fixed version of it
if (botOfSidebar < $(window).height()) {
$("#sidebar").addClass("fixed");
$("#sidebar").css("top", topOfSidebar);
$("#sidebar").css("left", leftOfSidebar);
}
else {
dynamic = true;
}
//toggle sidebar class when user scrolls
$(window).scroll(function() {
console.log($("#sidebar").css("position"));
botOfScreen = $(window).height() + $(window).scrollTop();
//return;
if (botOfSidebar < botOfScreen && dynamic) {
$("#sidebar").addClass("fixed");
//$("#sidebar").css("bottom", 0);
//$("#sidebar").css("left", leftOfSidebar);
}
else if (dynamic) {
$("#sidebar").removeClass("fixed");
}
});
});
So I figured this one out on my own. The trick is to wrap the content in a div with a min-height attribute. If we switch the sidebar to fixed then the div holds the place of the sidebar. Therefore no more screen resizing.
.wrap creates the div
.parent gets the sidebar's parent (the new div)
add css properties where min-height is the height of the sidebar. Remove padding and margin
$("#sidebar")
.wrap('')
.parent()
.css("min-height", this.height())
.css("padding", "0px")
.css("margin", "0px");