diff --git a/packages/vue-final-modal/src/components/VueFinalModal/useBodyScrollLock.ts b/packages/vue-final-modal/src/components/VueFinalModal/useBodyScrollLock.ts
index dd710360..6c4b0711 100644
--- a/packages/vue-final-modal/src/components/VueFinalModal/useBodyScrollLock.ts
+++ b/packages/vue-final-modal/src/components/VueFinalModal/useBodyScrollLock.ts
@@ -12,6 +12,8 @@ type Lock = {
   options?: BodyScrollOptions
 }
 
+type AxisType = 'x' | 'y'
+
 // stolen from body-scroll-lock
 
 // Older browsers don't support event options, feature detect it.
@@ -40,24 +42,34 @@ const isIosDevice
 
 let locks: Lock[] = []
 let documentListenerAdded = false
-let clientY = 0
-let initialClientY = -1
+let client: Record<AxisType, number> = { x: 0, y: 0 }
+let initialClient: Record<AxisType, number> = { x: -1, y: -1 }
 let previousBodyOverflowSetting: undefined | string
 let previousBodyPaddingRight: undefined | string
+let axis: AxisType | null = null
 
-const hasScrollbar = (el: HTMLElement) => {
+const hasScrollbar = (el: HTMLElement, axis: AxisType) => {
   if (!el || el.nodeType !== Node.ELEMENT_NODE)
     return false
 
   const style = window.getComputedStyle(el)
-  return ['auto', 'scroll'].includes(style.overflowY) && el.scrollHeight > el.clientHeight
+  const overflow = style[`overflow${axis === 'y' ? 'Y' : 'X'}`]
+  const totalScroll = el[`scroll${axis === 'y' ? 'Height' : 'Width'}`]
+  const clientSize = el[`client${axis === 'y' ? 'Height' : 'Width'}`]
+
+  return ['auto', 'scroll'].includes(overflow) && totalScroll > clientSize
 }
 
-const shouldScroll = (el: HTMLElement, delta: number) => {
-  if (el.scrollTop === 0 && delta < 0)
+const shouldScroll = (el: HTMLElement, delta: number, axis: AxisType) => {
+  const totalScroll = el[`scroll${axis === 'y' ? 'Height' : 'Width'}`]
+  const scrolled = el[`scroll${axis === 'y' ? 'Top' : 'Left'}`]
+  const clientSize = el[`client${axis === 'y' ? 'Height' : 'Width'}`]
+
+  if (scrolled === 0 && delta < 0)
     return false
-  if (el.scrollTop + el.clientHeight + delta >= el.scrollHeight && delta > 0)
+  if (scrolled + clientSize + delta >= totalScroll && delta > 0)
     return false
+
   return true
 }
 
@@ -72,18 +84,20 @@ const composedPath = (el: null | HTMLElement) => {
   return path
 }
 
-const hasAnyScrollableEl = (el: HTMLElement | null, delta: number) => {
-  let hasAnyScrollableEl = false
+const hasAnyScrollableEl = (el: HTMLElement | null) => {
   const path = composedPath(el)
-  path.forEach((el) => {
-    if (hasScrollbar(el) && shouldScroll(el, delta))
-      hasAnyScrollableEl = true
-  })
-  return hasAnyScrollableEl
+  for (const el of path) {
+    if (hasScrollbar(el, 'y') && shouldScroll(el, -client.y, 'y'))
+      return true
+
+    if (hasScrollbar(el, 'x') && shouldScroll(el, -client.x, 'x'))
+      return true
+  }
+  return false
 }
 
 // returns true if `el` should be allowed to receive touchmove events.
-const allowTouchMove = (el: HTMLElement | null) => locks.some(() => hasAnyScrollableEl(el, -clientY))
+const allowTouchMove = (el: HTMLElement | null) => locks.some(() => hasAnyScrollableEl(el))
 
 const preventDefault = (rawEvent: TouchEvent) => {
   const e = rawEvent || window.event
@@ -142,21 +156,35 @@ const restoreOverflowSetting = () => {
   }
 }
 // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions
-const isTargetElementTotallyScrolled = (targetElement: HTMLElement) =>
-  targetElement ? targetElement.scrollHeight - targetElement.scrollTop <= targetElement.clientHeight : false
+const isTargetElementTotallyScrolled = (targetElement: any, axis: AxisType): boolean => {
+  if (targetElement) {
+    const totalScroll = targetElement[`scroll${axis === 'y' ? 'Height' : 'Width'}`]
+    const scrolled = targetElement[`scroll${axis === 'y' ? 'Top' : 'Left'}`]
+    const clientSize = targetElement[`client${axis === 'y' ? 'Height' : 'Width'}`]
+    return totalScroll - scrolled <= clientSize
+  }
+  return false
+}
 
-const handleScroll = (event: TouchEvent, targetElement: HTMLElement) => {
-  clientY = event.targetTouches[0].clientY - initialClientY
+const handleScroll = (event: TouchEvent, targetElement: HTMLElement, axis: AxisType) => {
+  const touch = event.targetTouches[0]
+  client = {
+    x: touch.clientX - initialClient.x,
+    y: touch.clientY - initialClient.y,
+  }
+  const initialPos = initialClient[axis]
+  const scrollPos = targetElement && targetElement[`scroll${axis === 'y' ? 'Top' : 'Left'}`]
+  const clientPos = (axis === 'y' ? touch.clientY : touch.clientX) - initialPos
 
   if (allowTouchMove(event.target as HTMLElement | null))
     return false
 
-  if (targetElement && targetElement.scrollTop === 0 && clientY > 0) {
+  if (targetElement && scrollPos === 0 && clientPos > 0) {
     // element is at the top of its scroll.
     return preventDefault(event)
   }
 
-  if (isTargetElementTotallyScrolled(targetElement) && clientY < 0) {
+  if (isTargetElementTotallyScrolled(targetElement, axis) && clientPos < 0) {
     // element is at the bottom of its scroll.
     return preventDefault(event)
   }
@@ -189,13 +217,21 @@ export const disableBodyScroll = (targetElement?: HTMLElement, options?: BodyScr
     targetElement.ontouchstart = (event: TouchEvent) => {
       if (event.targetTouches.length === 1) {
         // detect single touch.
-        initialClientY = event.targetTouches[0].clientY
+        initialClient = {
+          x: event.targetTouches[0].clientX,
+          y: event.targetTouches[0].clientY,
+        }
       }
     }
     targetElement.ontouchmove = (event: TouchEvent) => {
       if (event.targetTouches.length === 1) {
         // detect single touch.
-        handleScroll(event, targetElement)
+        if (!axis) {
+          const distX = Math.abs(initialClient.x - event.targetTouches[0].clientX)
+          const distY = Math.abs(initialClient.y - event.targetTouches[0].clientY)
+          axis = distX > distY ? 'x' : 'y'
+        }
+        handleScroll(event, targetElement, axis)
       }
     }