Full screen nav jumps due to lack of scrollbar - html

I have a site with a full screen overlay nav, which when triggered hides the overflow on the html element. This is to stop the page behind the nav being scrolled when the nav is open.
Stripped down SCSS (when nav is active) looks like this:
html.nav-is-active {
overflow: hidden
}
nav.active {
display: block;
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 1600000;
}
My problem is when the nav is open the scrollbar disappears causing the page to jump - this is especially disorientating as there is a close button on the nav overlay which is supposed to line up with a menu button on the site.
My question is how can I best solve this? I can remove the overflow:hidden from the html element to preserve the scrollbar, but that then means the site can be scrolled unintentionally when the nav is open.
Any help appreciated
Mike

This is really hacky, but it should do what you want...
html {
overflow-y: hidden;
}
body {
overflow-y: scroll; // causes an empty scrollbar
height: auto; //set height = content so body can't overflow
}
You can make your scrollbar visible the same way in the overlay.
OR If you can figure out the width of the scrollbar (typically 15px on Mac and I think similar in Win 10) you can subtract from the overlay size or add padding. This is slightly better than setting the overlay to overflow-y: scroll since it won't cause scrolling INSIDE the overlay on small screens.
nav.active {
width: calc(100vw - 15px); // could be done with javascript
}

An alternative to block scroll without overflow: hidden; is position: fixed; overflow-y:scroll; so simply change this:
html.nav-is-active {
overflow: hidden;
}
with this:
html.nav-is-active {
position: fixed;
overflow-y:scroll;
}
You'll se an empty scroll bar, but the page will not "jump" anymore.

Related

Sidebar scroll is not working. Only page scroll is working

I am designing a webpage in which I have a sidebar and some other stuff like shown below
Here, Your Friends is the sidebar I am talking about. whenever I put my cursor over that sidebar and scroll, the page is scrolling instead of the sidebar.
What I am expecting to happen is that, when I put my cursor outside of that sidebar and scroll, the main page should scroll down. and when I keep it on the sidebar and scroll the sidebar should scroll down.
This is the CSS of my sidebar
header .c-header-container .c-side-bar-right {
position: fixed;
top: 80px;
bottom: 37px;
right: 0px;
background-color: var(--side-bar-color);
display: flex;
flex-direction: column;
padding: 1rem;
border: 4px solid black;
border-top: none;
width: 20%;
z-index: -1;
overflow-y: scroll;
}
Is there any way I can achieve this?
I really see no flaw in your codes but could you please try setting the z-index to a positive value or better still remove it?
Relative to which element did you set the z-index and what are the css properties of this element?.. We're still working
The sidebar isn't scrolling probably because of its z-index. Try setting it to high value, maybe 99 or more. This should fix the problem.
.sidebar-class {
z-index: 99;
}

iOS safari: scrolling is broken inside position: fixed; elements

Inside a position: fixed; element, scrolling elements will "lock" if you try to scroll them the wrong way at the start of a touch.
Example: touch the screen and drag downwards, then back up. The element won't scroll. If you release, wait a few seconds, then try dragging upwards, it will scroll.
http://12me21.github.io/scroll-test.html
body {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
#scroll-container {
overflow-y: scroll;
height: 100%;
}
#scroller {
height: 200vh;
font-size: 50px;
}
<body>
<div id=scroll-container>
<div id=scroller>Test<br>more text</div>
</div>
</body>
This answer: https://stackoverflow.com/a/51733026/6232794 seems to be the same problem I'm having, but the fix no longer works. It seems to happen inside all fixed elements and isn't caused by -webkit-overflow-scrolling: touch; anymore.
Is there any way to fix this now? Or do I just need to avoid position: fixed; entirely?
Adding overflow: hidden; to <html> or <body> seems to fix it.
I'm not sure why this works, but I assume the problem is that safari is trying to scroll html/body instead of the element you want.
Because the scrollable section is inside a position:fixed element, scrolling the body has no visual effect, so it looks like nothing is happening.
I had a same problem and overflow hidden help to stop scrolling body element, but it also disable scrolling webpage if visitor wants to. So I created JQ solution to add class .overflow-hidden to body element, only when I need it. In my case when sidebars has active class.
$(document).click(function(){
if ($(".siderbar_menu").hasClass("side-menu-active")) {
$("body").addClass("overflow-hidden-mobile");
} else {
$("body").removeClass("overflow-hidden-mobile");
};
});
Works for me.

Can I set overflow: hidden but still show a scrollbar?

I want to disable scrolling for when there's a popup, but I hate how the entire page changes size when you add/remove the scrollbar. Is there a way to disable scrolling without hiding the scrollbar?
Kind of like when you set overflow:scroll to an element that doesn't have enough content to scroll: it still shows the scrollbar but it's disabled.
//when popup is open, disable scroll on body
body.popupOpen {
overflow: hidden;
}
Make sure that the overflow (the scroll bar) is on the body element then add an overlay that will simply cover the body and its scroll bar when the popup is shown.
Here is a simplified example with only the overlay where you cannot scroll:
body {
overflow: auto;
margin: 0;
max-height: 100vh; /* no more than the height of the viewport*/
}
html {
overflow: hidden; /* This one is important to avoid the propagation */
}
.overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
}
.content {
min-height: 500vh;
}
<div class="overlay">
</div>
<div class="content">
</div>
The answer is no, but you can set 'hidden' and create a element to simulate the scrollbar, but why would you do this, it only makes the user confused.
You can create a div that fullfils the whole page view, and just make it transparent, this way you can just enable/disable the div scroll to mantain a scrollbar:
.theDivInactive {
background: none;
pointer_events: none;
width: 100vw;
height: 100vh;
overflow: hidden;
}
and switch the class when the popup is on the screen:
.theDivActive {
background: none;
pointer_events: none;
width: 100vw;
height: 100vh;
overflow: scroll;
}
`
I have fixed the issue the same way bootstrap does. Just in case other methods doesn't work for you, here's the JS trick to calculate scrollbar width for a given browser. Then on modal open, you can set the padding-right to body element:
const documentWidth = document.documentElement.clientWidth;
const scrollbarWidth = Math.abs(window.innerWidth - documentWidth);
document.body.style.paddingRight = `${scrollbarWidth}px`;
Note: this will only work well if you set overflow-y: scroll to popup bg or put the popup over the white strap that was created as the side effect of the padding-right property.
Note 2: If elements are positioned absolutely relative to body width, they will still "jump" so you need to add padding to them as well or wrap them with div that has position: relative

How to hide scroll bar without using overflow "hidden"?

image1
in this image, there is no scroll bar but if I scroll down inside diagram component div element scrollbar will occur
image2 with scrollbar
how can I hide that scrollbar without setting overflow: hidden
references
Just use the CSS of it like that:
selector-with-overflow::-webkit-scrollbar {
width: 10px;
visibility: hidden;
display: none;
}
notice doesnt work on all browsers but should work on the most common ones
I'm not sure why you'd ever want to hide the indication that a page is overflowing, see this JSFiddle: http://jsfiddle.net/2nT38/868/ for the css for a scrollbar that isn't visible yet still scrollable. Here's the breakdown:
::-webkit-scrollbar {
-webkit-appearance: none;
}
::-webkit-scrollbar:vertical {
width: 0px;
}
::-webkit-scrollbar:horizontal {
height: 0px;
}
Hope this helps!

Allow content to overflow, but without stretching the viewport

I'm working on a header that's intended to overflow. It's got white-space: nowrap rule applied in order to prevent breaking the text into two or more lines.
The problem is, the viewport now stretches to fit the text and then the page is scrollable on the x-axis. Applying overflow-x: hidden hides the scrollbar, but it's still possible to scroll the page on mobile, and on desktop through middle mouse button drag.
I know I could use position: fixed, but that's not a solution for me. I want the header to stay where it is.
Here's a fiddle with all my attempts so far.
Ok, try applying this:
CSS:
.wrapper {
position: absolute;
width: 98%;
overflow: hidden;
}
.text {
font-size: 500%;
white-space: nowrap;
display: block;
width: 100%;
float: left;
}
edit: oh, and remove overflow-x: hidden; from html,body