zer0ruth
zer0ruth

Reputation: 89

CSS overlay menu that freezes background scroll

Is it possible to create a CSS overlay menu which freezes the scroll of the main content that it overlays? That is to say, when the menu overlay is active you can scroll the menu, but the not the content behind it.

I've created a menu overlay, but when you scroll through the menu, it scrolls the background content as well. Is there anyway to freeze the content behind when the menu overlay is active?

Here's the javascript I created for the menu

// open menu overlay / hide background content   
function openNav() {
    document.querySelector("nav").style.display = "block";
    document.querySelector("body").style.background = "#999";
    document.getElementById("btn-menuclose").style.display = "block";
    document.getElementById("btn-menu").style.display = "none";
    document.getElementById("background").style.display = "none";  
}

//close menu overlay, reveal background content again
function closeNav() {
    document.querySelector("nav").style.display = "none";
    document.querySelector("body").style.background = "#fff";
    document.getElementById("btn-menuclose").style.display = "none";
    document.getElementById("btn-menu").style.display = "block";
    document.getElementById("background").style.display = "block";  
}

Upvotes: 0

Views: 1483

Answers (3)

Piotr Wicijowski
Piotr Wicijowski

Reputation: 2115

I recently faced the same problem, and the only solution that worked:

  • consistently
  • across different devices and form factors (iOS Safari being the most painful to work around)
  • satisfying all requirements (the body does not scroll to top on popup, there is no weird overscroll and navigation chrome toggling on iOS Safari)

is a javascript library body-scroll-lock. It is not pure css (and I doubt that such solution exists at the moment) but since you already have methods for opening and closing the navigation in js, then this should not be an issue.

Upvotes: 0

David Deprost
David Deprost

Reputation: 5110

Add overflow: hidden; to the selector that shouldn't scroll (and unset it back to visible afterwards), e.g.:

// open menu overlay / hide background content   
function openNav() {
document.querySelector("nav").style.display = "block";
document.querySelector("body").style.background = "#999";
document.getElementById("btn-menuclose").style.display = "block";
document.getElementById("btn-menu").style.display = "none";
document.getElementById("background").style.display = "none";  
document.getElementById("background").style.overflow = "hidden";  
}

//close menu overlay, reveal background content again
function closeNav() {
document.querySelector("nav").style.display = "none";
document.querySelector("body").style.background = "#fff";
document.getElementById("btn-menuclose").style.display = "none";
document.getElementById("btn-menu").style.display = "block";
document.getElementById("background").style.display = "none";  
document.getElementById("background").style.overflow = "visible";
}

You can also set it directly on the body if necessary.

Upvotes: 1

Nighthawk2730
Nighthawk2730

Reputation: 173

Add overflow:none to the body when the overflow:visible when it is off.

// open menu overlay / hide background content   
function openNav() {
document.querySelector("nav").style.display = "block";
document.querySelector("body").style.background = "#999";
document.getElementById("btn-menuclose").style.display = "block";
document.getElementById("btn-menu").style.display = "none";
document.getElementById("background").style.display = "none"; 
document.querySelector("body").style.overflow ="none";


}

//close menu overlay, reveal background content again
function closeNav() {
document.querySelector('"body".style.overflow = "visible";
document.querySelector("body").style.background = "#fff";
document.getElementById("btn-menuclose").style.display = "none";
document.getElementById("btn-menu").style.display = "block";
document.getElementById("background").style.display = "none";  
document.querySelector("nav").style.display = "none";

}

Upvotes: 1

Related Questions