为什么在 HTML Canvas 下面添加小 div 会出现水平滚动条?

Why does a horizontal scroll-bar appear when adding small div below HTML Canvas?

我有一个简单的 HTML canvas 覆盖了整个页面,它本身显示良好。

const canvas = document.getElementById("mainCanvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
window.addEventListener("resize",
  function() {
    canvas.width = innerWidth;
    canvas.height = innerHeight;  
  }
);
body {
  background-color: red;
  margin: 0;
  padding: 0;
}

#mainCanvas {
  display: block;
  background-color: blue;
}
<canvas id = "mainCanvas"></canvas>

但是,当我尝试在其下方添加一个 div 元素时,即使所有元素都小于总宽度,也会立即出现 水平 滚动条(因此不应该有任何水平溢出)。例如:

const canvas = document.getElementById("mainCanvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
window.addEventListener("resize",
  function() {
    canvas.width = innerWidth;
    canvas.height = innerHeight;  
  }
);
body {
  background-color: red;
  margin: 0;
  padding: 0;
}

#mainCanvas {
  display: block;
  background-color: blue;
}

#info {
  width: 50px;
  height: 50px;
  background-color: green;
}
<canvas id = "mainCanvas"></canvas>
<div id = "info"></div>

我知道我可以使用 overflow-x: hidden 解决水平滚动条出现的问题,但我想首先了解它出现的原因。

这与 <canvas> 无关,其行为与 <div> 等任何其他块元素相同。

如果您将 <body> 维度中的单独元素设置为 innerWidth/innerHeight 并且父元素 <body> 没有填充或边距,那么您页面上的所有 space 都用完了,不需要滚动条了。

如果您在整页元素下方添加 <div>,则需要垂直滚动条以允许用户向下移动视口以查看它。但是这个新的垂直滚动条现在占据了一些被 innerWidth 忽略的水平 space,因为 docs state:

innerWidth returns the interior width of the window in pixels. This includes the width of the vertical scroll bar, if one is present.

设置为正好 innerWidth 像素的原始元素现在水平溢出屏幕的宽度为垂直滚动条的宽度。因此,水平滚动条成为必要。

您可以尝试的一个选项是 document.documentElement.clientWidth。作为 docs state:

clientWidth [...] includes padding but excludes borders, margins, and vertical scrollbars (if present).

(您可能需要在 运行 代码段之后单击 'full page' 以查看差异):

const canvas = document.getElementById("main-canvas");
canvas.width = document.documentElement.clientWidth;
canvas.height = document.documentElement.clientHeight;
window.addEventListener("resize", // TODO debounce
  function () {
    canvas.width = document.documentElement.clientWidth;
    canvas.height = document.documentElement.clientHeight;  
  }
);
body {
  background-color: red;
  margin: 0;
  padding: 0;
}

#main-canvas {
  display: block;
  background-color: blue;
}

#info {
  width: 50px;
  height: 50px;
  background-color: green;
}
<canvas id="main-canvas"></canvas>
<div id="info"></div>

另见 How to get the browser viewport dimensions?