Skip to content

Conversation

@github-actions
Copy link
Contributor

Release
@floating-ui/dom@1.7.4

Diff for packages/dom

Diff
diff --git a/packages/dom/CHANGELOG.md b/packages/dom/CHANGELOG.md
index f3bd98d4..83ea46b5 100644
--- a/packages/dom/CHANGELOG.md
+++ b/packages/dom/CHANGELOG.md
@@ -1,5 +1,11 @@
 # @floating-ui/dom
 
+## 1.7.4
+
+### Patch Changes
+
+- fix(getViewportRect): account for space left by `scrollbar-gutter: stable`
+
 ## 1.7.3
 
 ### Patch Changes
diff --git a/packages/dom/package.json b/packages/dom/package.json
index be24e88e..23f3f1b5 100644
--- a/packages/dom/package.json
+++ b/packages/dom/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@floating-ui/dom",
-  "version": "1.7.3",
+  "version": "1.7.4",
   "description": "Floating UI for the web",
   "publishConfig": {
     "access": "public"
diff --git a/packages/dom/src/platform/convertOffsetParentRelativeRectToViewportRelativeRect.ts b/packages/dom/src/platform/convertOffsetParentRelativeRectToViewportRelativeRect.ts
index 01d1aa91..0b17a0fd 100644
--- a/packages/dom/src/platform/convertOffsetParentRelativeRectToViewportRelativeRect.ts
+++ b/packages/dom/src/platform/convertOffsetParentRelativeRectToViewportRelativeRect.ts
@@ -55,7 +55,7 @@ export function convertOffsetParentRelativeRectToViewportRelativeRect({
 
   const htmlOffset =
     documentElement && !isOffsetParentAnElement && !isFixed
-      ? getHTMLOffset(documentElement, scroll, true)
+      ? getHTMLOffset(documentElement, scroll)
       : createCoords(0);
 
   return {
diff --git a/packages/dom/src/utils/getHTMLOffset.ts b/packages/dom/src/utils/getHTMLOffset.ts
index bdc4bbea..a07a17ce 100644
--- a/packages/dom/src/utils/getHTMLOffset.ts
+++ b/packages/dom/src/utils/getHTMLOffset.ts
@@ -4,16 +4,12 @@ import {getWindowScrollBarX} from './getWindowScrollBarX';
 export function getHTMLOffset(
   documentElement: HTMLElement,
   scroll: NodeScroll,
-  ignoreScrollbarX = false,
 ) {
   const htmlRect = documentElement.getBoundingClientRect();
   const x =
     htmlRect.left +
     scroll.scrollLeft -
-    (ignoreScrollbarX
-      ? 0
-      : // RTL <body> scrollbar.
-        getWindowScrollBarX(documentElement, htmlRect));
+    getWindowScrollBarX(documentElement, htmlRect);
   const y = htmlRect.top + scroll.scrollTop;
 
   return {
diff --git a/packages/dom/src/utils/getViewportRect.ts b/packages/dom/src/utils/getViewportRect.ts
index 9f26d76e..2ab4e0d5 100644
--- a/packages/dom/src/utils/getViewportRect.ts
+++ b/packages/dom/src/utils/getViewportRect.ts
@@ -2,6 +2,12 @@ import type {Rect, Strategy} from '@floating-ui/core';
 import {getWindow, isWebKit} from '@floating-ui/utils/dom';
 
 import {getDocumentElement} from '../platform/getDocumentElement';
+import {getWindowScrollBarX} from './getWindowScrollBarX';
+
+// Safety check: ensure the scrollbar space is reasonable in case this
+// calculation is affected by unusual styles.
+// Most scrollbars leave 15-18px of space.
+const SCROLLBAR_MAX = 25;
 
 export function getViewportRect(element: Element, strategy: Strategy): Rect {
   const win = getWindow(element);
@@ -25,6 +31,32 @@ export function getViewportRect(element: Element, strategy: Strategy): Rect {
     }
   }
 
+  const windowScrollbarX = getWindowScrollBarX(html);
+  // <html> `overflow: hidden` + `scrollbar-gutter: stable` reduces the
+  // visual width of the <html> but this is not considered in the size
+  // of `html.clientWidth`.
+  if (windowScrollbarX <= 0) {
+    const doc = html.ownerDocument;
+    const body = doc.body;
+    const bodyStyles = getComputedStyle(body);
+    const bodyMarginInline =
+      doc.compatMode === 'CSS1Compat'
+        ? parseFloat(bodyStyles.marginLeft) +
+            parseFloat(bodyStyles.marginRight) || 0
+        : 0;
+    const clippingStableScrollbarWidth = Math.abs(
+      html.clientWidth - body.clientWidth - bodyMarginInline,
+    );
+
+    if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {
+      width -= clippingStableScrollbarWidth;
+    }
+  } else if (windowScrollbarX <= SCROLLBAR_MAX) {
+    // If the <body> scrollbar is on the left, the width needs to be extended
+    // by the scrollbar amount so there isn't extra space on the right.
+    width += windowScrollbarX;
+  }
+
   return {
     width,
     height,

Full diff
1.7.3...1.7.4.

@DanielleHuisman DanielleHuisman marked this pull request as ready for review August 30, 2025 07:28
@DanielleHuisman DanielleHuisman enabled auto-merge (squash) August 30, 2025 07:28
@DanielleHuisman DanielleHuisman merged commit 2d07611 into main Aug 30, 2025
8 checks passed
@DanielleHuisman DanielleHuisman deleted the upstream/dom-1.7.4 branch August 30, 2025 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants