diff --git a/layout/generic/ReflowOutput.cpp b/layout/generic/ReflowOutput.cpp
index d54684809a371dde17c93a7cd3053c1d01f60c89..a0312dffda9477845408cef49cc121a93584b22f 100644
--- a/layout/generic/ReflowOutput.cpp
+++ b/layout/generic/ReflowOutput.cpp
@@ -11,6 +11,19 @@
 
 namespace mozilla {
 
+static bool IsValidOverflowRect(const nsRect& aRect) {
+  // `IsEmpty` in the context of `nsRect` means "width OR height is zero."
+  // However, in the context of overflow, the rect having one axis as zero is
+  // NOT considered empty.
+  if (MOZ_LIKELY(!aRect.IsEmpty())) {
+    return true;
+  }
+
+  // Be defensive and consider rects with any negative size as invalid.
+  return !aRect.IsEqualEdges(nsRect()) && aRect.Width() >= 0 &&
+         aRect.Height() >= 0;
+}
+
 /* static */
 nsRect OverflowAreas::GetOverflowClipRect(const nsRect& aRectToClip,
                                           const nsRect& aBounds,
@@ -40,12 +53,20 @@ void OverflowAreas::ApplyOverflowClippingOnRect(nsRect& aOverflowRect,
 }
 
 void OverflowAreas::UnionWith(const OverflowAreas& aOther) {
-  InkOverflow().UnionRect(InkOverflow(), aOther.InkOverflow());
-  ScrollableOverflow().UnionRect(ScrollableOverflow(),
-                                 aOther.ScrollableOverflow());
+  if (IsValidOverflowRect(aOther.InkOverflow())) {
+    InkOverflow().UnionRect(InkOverflow(), aOther.InkOverflow());
+  }
+  if (IsValidOverflowRect(aOther.ScrollableOverflow())) {
+    ScrollableOverflow().UnionRect(ScrollableOverflow(),
+                                   aOther.ScrollableOverflow());
+  }
 }
 
 void OverflowAreas::UnionAllWith(const nsRect& aRect) {
+  if (!IsValidOverflowRect(aRect)) {
+    // Same as `UnionWith()` - avoid losing information.
+    return;
+  }
   InkOverflow().UnionRect(InkOverflow(), aRect);
   ScrollableOverflow().UnionRect(ScrollableOverflow(), aRect);
 }
diff --git a/testing/web-platform/tests/css/css-overflow/scrollable-overflow-zero-one-axis.html b/testing/web-platform/tests/css/css-overflow/scrollable-overflow-zero-one-axis.html
new file mode 100644
index 0000000000000000000000000000000000000000..1986a8d48b98fde17fda826c5bbf9d75d870f45e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-overflow/scrollable-overflow-zero-one-axis.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: Scroll Length Calculated Correctly When One Axis Has Zero Length</title>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1800907">
+<style>
+.scroll {
+  overflow: scroll;
+}
+
+.zero-h {
+  width: 100px;
+  height: 0px;
+}
+
+.zero-w {
+  width: 0;
+  height: 100px;
+}
+
+.flex-row {
+  display: flex;
+}
+
+.flex-col {
+  display: flex;
+  flex-direction: column;
+}
+
+.grid {
+  display: grid;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.scroll')">
+<div class="scroll zero-h" data-expected-scroll-height="100">
+  <div class="zero-w"></div>
+</div>
+<div class="scroll zero-w" data-expected-scroll-width="100">
+  <div class="zero-h"></div>
+</div>
+
+<div class="scroll zero-h flex-row" data-expected-scroll-height="100">
+  <div class="zero-w"></div>
+</div>
+<div class="scroll zero-w flex-col" data-expected-scroll-width="100">
+  <div class="zero-h"></div>
+</div>
+
+<div class="scroll zero-h grid" data-expected-scroll-height="100">
+  <div class="zero-w"></div>
+</div>
+<div class="scroll zero-w grid" data-expected-scroll-width="100">
+  <div class="zero-h"></div>
+</div>