Explain Codes LogoExplain Codes Logo

How to disable scroll without hiding it?

web-development
responsive-design
performance
smooth-scrolling
Anton ShumikhinbyAnton Shumikhin·Oct 16, 2024
TLDR

Freeze scrolling while maintaining scrollbar visibility via CSS. Use overflow-y to keep the scrollbar and position to cease scrolling. Compensate layout shifts with equal padding-right and use top to preserve the user's scroll position:

body.no-scroll { overflow-y: scroll; /* Preserve scrollbar */ position: fixed; /* Disable scrolling, just for fun */ width: 100%; /* Stop content from running away */ top: calc(-1 * var(--scroll-position)); /* Don't forget where we were */ }

Toggle the .no-scroll class on the <body> tag when you decide to put scrolling on ice.

When toggling on, remember the scroll position:

const scrollY = document.documentElement.style.getPropertyValue('--scroll-position', window.scrollY); document.documentElement.style.setProperty('--scroll-position', `${scrollY}px`); document.body.classList.add('no-scroll'); /* Time to chill */

When you're done, toggle off and defrost:

const scrollY = document.documentElement.style.getPropertyValue('--scroll-position'); document.documentElement.style.removeProperty('--scroll-position'); window.scrollTo(0, parseInt(scrollY || '0')); document.body.classList.remove('no-scroll'); /* Ready to roll */

Enjoy a seamless user experience with this freezing effect on scrolling, no nasty layout shifts and user's scroll position remembered.

Layout shifts prevention

Ensure that our content remains cool and doesn't jump or shift upon scrolling off:

1. Apply `width: 100%` on `<body>` when `position: fixed` to ensure a stable layout. 2. Use the `inline-size` property to sustain even width across browsers. 3. Leverage CSS variables for dynamic width adjustments if required. 4. Research on **double scrollbar issues** and implement community-approved solutions like specific media queries.

Detecting page length: Beware of overflow and apply the treatment accordingly.

const hasVerticalScrollbar = document.body.scrollHeight > window.innerHeight; if (hasVerticalScrollbar) { // Unleash the no-scroll technique here }

User experience enhancement

  • Remember the scroll position before freezing and apply it afterwards for user-friendly transitions.
  • Indulge in smooth scrolling with scroll-behavior: smooth; in your CSS or the JavaScript techniques referenced in SitePoint.

JQuery tips

If jQuery is your weapon of choice, here's how you can tame the scroll:

$.fn.disableScroll = function() { this.each(function() { $(this).css({ overflow: 'scroll', position: 'fixed', width: '100%', top: `-${$(window).scrollTop()}px` /* Because rememberance matters */ }); }); }; $.fn.enableScroll = function() { const scrollY = this.css('top'); this.css({ overflow: '', position: '', top: '', width: '' }); $('html, body').scrollTop(-parseInt(scrollY || '0')); /* Resume from where we paused */ }; $('body').disableScroll(); /* Chill out */ $('body').enableScroll(); /* Let's rock and roll again */

Handling events and cleanup with jQuery’s .off() can also prove to be handy.