Skip to content

Instantly share code, notes, and snippets.

@barneycarroll
Last active March 20, 2026 10:00
Show Gist options
  • Select an option

  • Save barneycarroll/6550066 to your computer and use it in GitHub Desktop.

Select an option

Save barneycarroll/6550066 to your computer and use it in GitHub Desktop.
Lock and unlock a page's scroll position.

jquery.scrollLock.js

Useful for when a blocking user experience is needed (in my case, didn't want people unwittingly loosing their place by scrolling while a modal required their attention): $.scrollLock() locks the body in place, preventing scroll until it is unlocked.

// Locks the page if it's currently unlocked
$.scrollLock();

// ...or vice versa
$.scrollLock();

// Locks the page
$.scrollLock( true );

// Unlocks the page
$.scrollLock( false );
$.scrollLock = ( function scrollLockClosure() {
'use strict';
var $html = $( 'html' ),
// State: unlocked by default
locked = false,
// State: scroll to revert to
prevScroll = {
scrollLeft : $( window ).scrollLeft(),
scrollTop : $( window ).scrollTop()
},
// State: styles to revert to
prevStyles = {},
lockStyles = {
'overflow-y' : 'scroll',
'position' : 'fixed',
'width' : '100%'
};
// Instantiate cache in case someone tries to unlock before locking
saveStyles();
// Save context's inline styles in cache
function saveStyles() {
var styleAttr = $html.attr( 'style' ),
styleStrs = [],
styleHash = {};
if( !styleAttr ){
return;
}
styleStrs = styleAttr.split( /;\s/ );
$.each( styleStrs, function serializeStyleProp( styleString ){
if( !styleString ) {
return;
}
var keyValue = styleString.split( /\s:\s/ );
if( keyValue.length < 2 ) {
return;
}
styleHash[ keyValue[ 0 ] ] = keyValue[ 1 ];
} );
$.extend( prevStyles, styleHash );
}
function lock() {
var appliedLock = {};
// Duplicate execution will break DOM statefulness
if( locked ) {
return;
}
// Save scroll state...
prevScroll = {
scrollLeft : $( window ).scrollLeft(),
scrollTop : $( window ).scrollTop()
};
// ...and styles
saveStyles();
// Compose our applied CSS
$.extend( appliedLock, lockStyles, {
// And apply scroll state as styles
'left' : - prevScroll.scrollLeft + 'px',
'top' : - prevScroll.scrollTop + 'px'
} );
// Then lock styles...
$html.css( appliedLock );
// ...and scroll state
$( window )
.scrollLeft( 0 )
.scrollTop( 0 );
locked = true;
}
function unlock() {
// Duplicate execution will break DOM statefulness
if( !locked ) {
return;
}
// Revert styles
$html.attr( 'style', $( '<x>' ).css( prevStyles ).attr( 'style' ) || '' );
// Revert scroll values
$( window )
.scrollLeft( prevScroll.scrollLeft )
.scrollTop( prevScroll.scrollTop );
locked = false;
}
return function scrollLock( on ) {
// If an argument is passed, lock or unlock depending on truthiness
if( arguments.length ) {
if( on ) {
lock();
}
else {
unlock();
}
}
// Otherwise, toggle
else {
if( locked ){
unlock();
}
else {
lock();
}
}
};
}() );
$.scrollLock = ( function scrollLockSimple(){
var locked = false;
var $body;
var previous;
function lock(){
if( !$body ){
$body = $( 'body' );
}
previous = $body.css( 'overflow' );
$body.css( 'overflow', 'hidden' );
locked = true;
}
function unlock(){
$body.css( 'overflow', previous );
locked = false;
}
return function scrollLock( on ) {
// If an argument is passed, lock or unlock depending on truthiness
if( arguments.length ) {
if( on ) {
lock();
}
else {
unlock();
}
}
// Otherwise, toggle
else {
if( locked ){
unlock();
}
else {
lock();
}
}
};
}() );
@webmaster-jhon

Copy link
Copy Markdown

Thanks for this file. I downloaded jquery.scrollLock.js but $.scrollLock(true) not working properly on my page. When i call this function scroll bar remains same i.e. still scroll able.

@RyKilleen

Copy link
Copy Markdown

Thank you, worked flawlessly. I needed to modify from scroll to hidden and feared having to tinker, but you had clearly prepared for that scenario. Very much appreciated.

@dsandstrom

Copy link
Copy Markdown

Thanks for this. Unfortunately the simple version does not work well on iOS. The page still scrolls underneath my overlay, overflow: hidden doesn't perform the same on Apple devices. I can't find documentation of this (go figure), but here is the fix I was using. However, when I use that CSS, the page scrolls to the top. Yet, the original version seems to work fine and locks the body scroll position in place.

@ahmednooor

Copy link
Copy Markdown

hi i am a novice and just know html and css a lil bit. i tried some solutions on the web but couldnt figure out how to tweak them according to my project and i hope this may work as it is not specified to some predefined classes. so could you plz tell the procedure to use it? like,

  1. where should i put the calling function?
  2. would i have to link to the jquery library in head too? or it will work on its own?
  3. if i have to put in my project specific class or id if it requires where should i put it?

for example i have a class .overlay which is hidden by default and when i click on on an anchor tag which is targeted to a div having the class .overlay and an id to get targeted and a modal opens i want to disable the body from scrolling when modal is opened.

sorry for asking an annoying question.

@jazcam

jazcam commented Mar 29, 2016

Copy link
Copy Markdown

Nice. Well done. Took a bit of doing, but between here and your demo on jsfiddle, I figured it out and have it working.

@xizon

xizon commented Apr 24, 2016

Copy link
Copy Markdown

Thanks!

@sanketj14

Copy link
Copy Markdown

You sir, are my hero! you can't imagine just how much of my efforts are saved with this wonderful library. worked right off the bat! Thanks, keep up the good work!

@mrlaseptima

Copy link
Copy Markdown

hey men thank you

@m11z

m11z commented Feb 9, 2017

Copy link
Copy Markdown

Thanks!

@tscrady

tscrady commented Apr 19, 2017

Copy link
Copy Markdown

Thank you very much, works on ios10, Firefox 51.0.1, Chrome Version 56.0.2924.87

@jessevdp

Copy link
Copy Markdown

๐Ÿ‘

@mhshakouri

Copy link
Copy Markdown

this is a great tool I really recommend it
Thanks

@nitin00709

Copy link
Copy Markdown

Thanks a lot for this wonderful library. It worked flawlessly. I had been trying for so long to hide scrolling on body while a pop-up window appears on ios, you have saved a lot of my time. Very much appreciated. I really recommend it. For those who are dealing with such issue I really recommend you to use this one it works on ios devices too.

@Dylan-Harrington

Dylan-Harrington commented Feb 13, 2018

Copy link
Copy Markdown

This is incredible. Multiple days of searching for an answer and trying a thousand different things finally concluded thanks to this little library. I hope everyone grinding their teeth over this issue finds it soon. Thank you SO much!

@leonardoervilha

Copy link
Copy Markdown

Thanks brother , God bless you

@techlemur

Copy link
Copy Markdown

Thank you! Works perfectly except for an occasional error with "styleAttr.split". Easily fixed by changing line 33 to the following:
try { styleStrs = styleAttr.split(/;\s/); } catch (err) { return; }

@hiddebijnerds

Copy link
Copy Markdown

Works perfectly ๐Ÿ‘

@StrangerPings

Copy link
Copy Markdown

Thank you for this! ๐Ÿ˜ƒ

@nilay255

nilay255 commented May 2, 2018

Copy link
Copy Markdown

How do I check if the scrollLock is active or not for jquery.scrollLock.js? Like how do I check the locked status is true or false. @barneycarroll

@rajakhoury

Copy link
Copy Markdown

Thanks alot for sharing

@BeholdPL

BeholdPL commented Nov 20, 2018

Copy link
Copy Markdown

Works great! But when scroll is locked, then every position: fixed elements on site are disappear. Is there possibility to avoid that?

@locopump

Copy link
Copy Markdown

Do you have any example of use of this code ??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment