Yevhen Klymentiev
dark
light
console
darkness
y.klymentiev@gmail.com
Reusable Snippets|Practical utility code for everyday use — custom-built and ready to share

lockUnlockBodyScroll

Toggles body scroll lock. When locked, sets overflow:hidden and compensates for scrollbar width.

TypeScript
Copied!
1/**
2 * Toggles body scroll lock.
3 * When locked, sets overflow:hidden and compensates for scrollbar width.
4 */
5export function toggleBodyScroll(): void {
6  const body = document.body;
7  const isLocked = body.style.overflow === 'hidden';
8
9  if (isLocked) {
10    body.style.overflow = '';
11    body.style.paddingRight = '';
12  } else {
13    const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
14    body.style.overflow = 'hidden';
15    body.style.paddingRight = `${scrollbarWidth}px`;
16  }
17}
  • Prevents Layout Shift

    Adds padding-right equal to scrollbar width when scroll is locked, avoiding content jump due to scrollbar disappearance.

  • Simple Toggle Logic

    Provides a single, reusable function to both lock and unlock scroll with minimal code and clear state detection.

  • Native Scroll Lock

    Relies on native overflow: hidden CSS behavior, ensuring wide compatibility across modern browsers.

  • No External Dependencies

    Fully self-contained utility that doesn't require third-party libraries or complex setup.

Tests | Examples

TypeScript
Copied!
1test('toggleBodyScroll locks body scroll when not locked', () => {
2  document.body.style.overflow = '';
3  document.body.style.paddingRight = '';
4
5  const initialWidth = window.innerWidth;
6  Object.defineProperty(document.documentElement, 'clientWidth', {
7    configurable: true,
8    value: initialWidth - 20,
9  });
10
11  toggleBodyScroll();
12
13  expect(document.body.style.overflow).toBe('hidden');
14  expect(document.body.style.paddingRight).toBe('20px');
15
16  // Restore
17  Object.defineProperty(document.documentElement, 'clientWidth', {
18    configurable: true,
19    value: initialWidth,
20  });
21});
22
23test('toggleBodyScroll unlocks body scroll when already locked', () => {
24  document.body.style.overflow = 'hidden';
25  document.body.style.paddingRight = '20px';
26
27  toggleBodyScroll();
28
29  expect(document.body.style.overflow).toBe('');
30  expect(document.body.style.paddingRight).toBe('');
31});

Common Use Cases

  • Modal or Dialog Handling

    Lock background scroll when modals, lightboxes, or side drawers are open.

  • Mobile Navigation Drawers

    Prevent body scrolling when a mobile menu or full-screen overlay is active.

  • Focus-Driven Experiences

    Create immersive flows by disabling background interaction during onboarding steps or alerts.

  • Prevent Scroll During Transitions

    Temporarily block scroll during animations or transitions that affect layout or user flow.

Codebase: Utilities -> Browser & DOM -> lockUnlockBodyScroll | Yevhen Klymentiev