Hello all,
I had been struggling with maintaining nav menu scroll functionality while disabling body scroll. It might be due to a bug in ios. I tried fs-attributes and the memberstack solution. They didn’t work for me (at least on ios). So I used GPT generate me a script for my custom nav and it works like a charm. Here is the code in case anyone is struggling.
Paste this inside head tag
<!-- Disable scrolling when nav is open -->
<style>
@media (max-width: 991px) {
.no-scroll {
overflow: hidden;
}
.nav_menu {
overflow-y: auto;
max-height: 100vh; /* Ensure the nav_menu can scroll within the viewport */
max-width: 100vh; /* Ensure the nav_menu fills width */
-webkit-overflow-scrolling: touch; /* Enable momentum scrolling on iOS */
}
}
</style>
<!-- Disable scrolling when nav is open -->
Paste this before body tag
<!-- Disable scrolling when nav is open -->
<script>
document.addEventListener('DOMContentLoaded', () => {
// Only run the script if the viewport width is 991px or less
if (window.innerWidth <= 991) {
const body = document.body;
const navMenu = document.querySelector('.nav_menu');
const navButtons = document.querySelectorAll('.nav_button');
const navMenuLinks = document.querySelectorAll('.nav_menu_link');
const buttonWrappers = document.querySelectorAll('.button_wrapper');
function preventScroll(event) {
if (!navMenu.contains(event.target)) {
event.preventDefault();
}
}
function disablePageScroll() {
body.classList.add('no-scroll');
document.addEventListener('touchmove', preventScroll, { passive: false });
document.addEventListener('wheel', preventScroll, { passive: false });
}
function enablePageScroll() {
body.classList.remove('no-scroll');
document.removeEventListener('touchmove', preventScroll, { passive: false });
document.removeEventListener('wheel', preventScroll, { passive: false });
}
// Add event listeners to nav buttons to toggle page scroll
navButtons.forEach(button => {
button.addEventListener('click', () => {
if (body.classList.contains('no-scroll')) {
enablePageScroll();
} else {
disablePageScroll();
}
});
});
// Add event listeners to nav menu links and button wrappers to enable page scroll
[...navMenuLinks, ...buttonWrappers].forEach(element => {
element.addEventListener('click', enablePageScroll);
});
// Ensure that the nav menu itself is scrollable
navMenu.addEventListener('touchstart', (e) => {
e.stopPropagation();
}, { passive: false });
navMenu.addEventListener('touchmove', (e) => {
e.stopPropagation();
}, { passive: false });
navMenu.addEventListener('wheel', (e) => {
e.stopPropagation();
}, { passive: false });
}
});
</script>
<!-- Disable scrolling when nav is open -->
Please be sure to change the class names.
For my nav it disables body scrolling while maintaining the scrollability of .nav_menu when nav open and and re-enables body scrolling when either nav is closed or any of these classes .nav_button; .nav_menu_link; and .button_wrapper are clicked.
Also, be sure to add an empty div at the bottom of your nav with a fixed height and/or padding in my case 24 rem worked the best so the div actually overflows even if there are browser components restricting your site’s UI visibiliy.
Hope this helps