为啥在 HTML Canvas 下方添加小 div 时会出现水平滚动条?

Posted

技术标签:

【中文标题】为啥在 HTML Canvas 下方添加小 div 时会出现水平滚动条?【英文标题】:Why does a horizontal scroll-bar appear when adding small div below HTML Canvas?为什么在 HTML Canvas 下方添加小 div 时会出现水平滚动条? 【发布时间】:2021-12-31 15:28:53 【问题描述】:

我有一个简单的 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 来解决出现水平滚动条的问题,但我想了解它首先出现的原因。

【问题讨论】:

【参考方案1】:

这与&lt;canvas&gt; 无关,其行为与任何其他块元素相同,例如&lt;div&gt;

如果您将&lt;body&gt; 的维度中的唯一元素设置为innerWidth/innerHeight 并且父&lt;body&gt; 没有填充或边距,那么您已经用完了所有空间页面,不需要滚动条。

如果您在整页元素下方添加&lt;div&gt;,则需要垂直滚动条以允许用户向下移动视口以查看它。但是这个新的垂直滚动条现在占用了innerWidth 忽略的一些水平空间,就像docs state:

innerWidth 返回窗口的内部宽度(以像素为单位)。这包括垂直滚动条的宽度(如果存在)。

设置为精确的innerWidth 像素的原始元素现在水平溢出屏幕垂直滚动条的宽度。因此,水平滚动条就变得很有必要了。

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

clientWidth [...] 包括填充,但不包括边框、边距和垂直滚动条(如果存在)。

(您可能需要在运行 sn-p 后单击“整页”才能看到差异):

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?

【讨论】:

以上是关于为啥在 HTML Canvas 下方添加小 div 时会出现水平滚动条?的主要内容,如果未能解决你的问题,请参考以下文章

html5 两个canvas重叠放在一个div里面,每个canvas各填充一张图片,代码怎么写?

如何将div 转化成 html 5 canvas

Fabricjs HTML5 Canvas:为啥图像大小调整得这么差?

Fabric.js Canvas - 使一种对象始终位于另一种对象下方

关于如何利用CSS自动调整图片的大小

为啥 div 的测量宽度与浏览器测量不同?