Bootstrap navigation affix bug - menu becomes jittery, jumpy on long pages - javascript

I'm building a website using bootstrap affix to manage the main menu. It seems to work perfectly on fairly short pages but I find that as page length increases the menu starts to get jumpy, jittery, as you scroll so I created 3 sample pages to illustrate the problem. Other than some extra content to promote additional scrolling the implementation of affix is identical.
Typically when I scroll I use the navigator scrollbar - the behavior appears more pronounced using the scrollbar vs keyboard up/down arrows and perhaps more so on Linux Firefox vs Chrome.
The affix CSS settings:
.affix {
top: 0;
width: 100%;
z-index: 9999 !important;
}
.affix + .affix-content-container
{
position: relative;
top: 50px;
}
.navbar {
margin-bottom: 0px;
}
I use the class, affix-content-container, on the div to contain all the body content following the bootstrap nav. Here are the links to the 3 varying length demo pages:
affix short page
affix medium page
affix long page
I've looked at some other websites which use something like affix, much longer pages, and they seem to behave more smoothly. Any suggestion how to smooth this out?
Here is a link to a video from Firefox. With each page I first use the mouse and scrollbar, then just the arrow keys. The green horizontal line is there for perspective, helps illustrate the problem.
Affix Video Demo
Workaround Solution Update: 2018-01-23
I added CSS transitions to .affix, in-out, etc, but they have no effect. It is still jumpy. So I thought back to the goal which is a navbar that scrolls to the top and smoothly fixes to the top of the page. I'm not much good with javascript, but I found some code and modified it:
<script type="text/javascript">
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 120) {
$('nav').addClass('fix-navbar-position');
} else {
$('nav').removeClass('fix-navbar-position');
}
});
</script>
I set the height of the header to 120, the scroll then fix height:
header { height: 120px; }
I found that if I set it up as: that I was seeing some odd margins or extra vertical padding, so I separated it so that nav would be an outer container only - and this worked:
<nav>
<div class="navbar navbar-default navbar-inverse">
The problem seemed to have something to do with the .navbar styling. To see the workaround solution visit: javascript-scroll-fix

Related

CLS (Cummulative Layout Shift ) in sticky navigations with position: fixed

With the new Web Vitals incoming I have a problem with my sticky navigations/menus. In fact most pages will have :-(
The problem is that I use an approach like bootstrap affix to make the menu sticky when it would leave the viewport. But every time the menu leaves the viewport (and enters it as well) and the position is set from relative/static/absolute to fixed it increases CLS (Cumulative Layout Shift). I realize that changing the position to fixed will result in a layout shift because the element is removed from the layer and all following elements will be shifted to the top.
BUT: That's why I came up with some solutions and the best I think is that I use a wrapper with a specific height around the menu. So when the position of the menu changes to fixed the wrapper still exists and does not change in position or height, which means that no following elements has to shift. But the CLS is still counting up. And I do not know what to do to make my menus sticky without affecting the CLS which is important. Btw I cannot use position: sticky because there is not enough browser support. Because if my researches are correct position: sticky works without negatively affecting the CLS, my solution does not although the user **does not see any difference at all **....
Here comes some pseudo code to be more visual:
...
<body>
<h1>
Headline
</h1>
<p>
Here is some elements an stuff
</p>
<div class="menu-wrapper">
<div class="menu">
<ul>...........</ul>
</div>
</div>
<p>
More elements and stuff. Nothing shifting because the wrapper always has the same height.
</p>
...
</body>
...
.menu-wrapper {
height: 60px;
width: 100%;
}
.menu {
height: 60px;
width: 100%;
position: static;
}
.menu.affix {
position: fixed;
top: 0;
}
Any ideas? Thank you very much!
This may be fixed in Chrome Canary 90.
Context: CLS change log reports couple of improvements in this regards: https://chromium.googlesource.com/chromium/src/+/master/docs/speed/metrics_changelog/cls.md:
Cumulative Layout Shift Changelog
This is a list of changes to Cumulative Layout Shift.
Metric definition improvement: Bug fixes involving changes to transform, effect, clip or position
Metric definition improvement: Consider transform change countering layout shift.
Other fixes from Chrome 89 listed on the same page may apply also.

How can I make a bootstrap navbar stay on top after scrolling down? (It's more complicated)

Here is the picture of my website header.
HERE
How can I make the blue navbar scroll smoothly to the top while i scroll down the page
(only the navbar, not the logo&social media stuff part)?
position:fixed; won't let the navbar move to the very top when I scroll down (obviously).
navbar {
margin: 0;
padding: 0;
overflow: hidden;
}
Try setting the margin and padding of the navigation bar to 0.It should work
I think you are using Bootstrap, so you can use Bootstrap Affix: http://getbootstrap.com/javascript/#affix
With the data-spy, data-offset-top and data-offset-bottom properties you can add affix behavior and define when to toggle the pinning of an element.

Changing the distance an internal link scrolls down the page

Hi I've got a nav menu that changes to fixed once scrolled down the page a certain amount of pixels.
Because the menu is fixed, it overlays the top cutting out the header of that section.
I'm looking to affect how far the page moves when using the menu to move to a section on the page, so sort of negatively offset how far the page scrolls down to show all the menu aswell as section header if possible.
Thanks!
I've come across this issue and came up with the following solution:
<nav class="fixed">
About
...
</nav>
...
<div id="about" class="anchor-helper"></div>
<div class="container-i-actually-want-to-see>
<!-- your content goes here -->
</div>
In the CSS:
nav {
height: 50px;
}
.anchor-helper {
position: relative;
top: -50px; /* however tall your nav is, you want this to be negative that amount */
}
What I like about this solution is that it relies on CSS as much as possible and only uses javascript for smooth scrolling. If someone navigates to http://your-site.com/example-page#about, they will get to where you want them to be.

How can I add a scroll bar to a fixed sidebar that only appears on hover

I'm working on a site where I made the sidebar to be fixed on the left and extended to the full height of the page using this CSS:
sidebar {
position: fixed;
top: 0;
bottom: 0;
}
And that works fine to keep the sidebar in place, but the problem is when the page is re-sized to a smaller height, you can only see the stuff at the top of the sidebar and there's no way to see the stuff at the bottom of the sidebar.
Now, I know I can add a scroll bar using overflow-y: scroll; but what I'm trying to do is have a scroll bar that only appears when the content on the sidebar exceeds the height of the window and only appears on hover. I also want the scroll bar to have some style to it, similar to the sidebar on TheNextWeb or the Facebook chat sidebar.
I know I need some JavaScript to do this, but my skills in JavaScript are very limited so I appreciate any help on this.
overflow-y: auto should work:
For styling you should probably search for a good scrollbar-replacement, as scrollbar-styling only works in webkit (http://css-tricks.com/custom-scrollbars-in-webkit/). It's not a trivial thing to do, but fortunately there are some plugins:
http://cubiq.org/iscroll-4
http://jscrollpane.kelvinluck.com/
http://www.yuiazu.net/perfect-scrollbar/
Just to mention a few.
EDIT:
Thanks to sheba, I made some modfications:
.sidebar:hover{
overflow-y: scroll;
}
http://codepen.io/johannesjo/pen/GcLFn

CSS/JS content scroll UP instead of down

I'm building a site with the navigation bar stretching across the entire site and it's fixed.
Under the navigation bar there is an image, a background image, which is set as a cover. And under the image is the main content.
When you scroll down, the navigation bar covers the image from top to bottom and the main content is now visible, effectively scrolling in a downwards fashion. I would like to "reverse" it. So the navigation is still fixed with the cover image under it but this time, when you scroll down the main content comes up and covers the image from bottom to top. So when you scroll down, the main content scrolls up.
Let's say my image has a 1 at the top and a 2 at the bottom. So, normally when you scroll down the navigation bar covers the image from top to bottom the 1 will disappear and the 2 will be visible until that is also covered. The effect I'm looking for would make the 2 disappear and the 1 would remain in the same place until it is covered by the main content.
I looked into parallax but I'm not sure if that's the right thing to go with. And I have no idea how to do achieve this effect.
Hopefully you'll understand what I'm trying to do here. If you need any more info then just let me know.
Thanks in advance.
EDIT
The effect can be seen on the abduzeedo frontpage
You need the image to be "attached" to the background ?
If so, cannot you just fix it to the background ?
body {
background-attachment:fixed;
}
Source: http://www.w3schools.com/cssref/pr_background-attachment.asp
https://developer.mozilla.org/en-US/docs/Web/CSS/background-attachment
Note: Be careful using W3Schools, their information is often incorrect, see here.
Here's an example with an img element.
Demo
code view
The basic HTML layout:
<nav></nav>
<img src="/image.ext" class="scrollup" />
<div class="main"></div>
Your nav will be positioned fixed, as you said. The image also needs fixed positioning. We set its z-index to -1 to make sure it's covered up.
img {
position: fixed;
width: 100%;
z-index: -1;
top: 20px; left: 0;
}
The main element is positioned relatively. Because our nav and image both have fixed positioning, the top value is relative to the top of the viewport. 100% means that .main starts as soon as we start scrolling.
.main {
background: white;
position: relative;
top: 100%;
}

Categories

Resources