css - 为什么 box-sizing 不适用于 canvas 元素上的宽度/高度属性?

标签 css html html5-canvas

让我们考虑这段代码:

.canvas {
  width:150px;
  height:150px;
}
canvas {
  box-sizing:border-box;
  border:5px solid;
}
<canvas height="150" width="150"></canvas>
<canvas class="canvas"></canvas>

我们有两个定义了相同宽度/高度、相同边框和 box-sizing:border-boxcanvas。我们可以清楚地看到我们使用 CSS 属性的 Canvas 遵循 box-sizing(边框从宽度/高度减少)但是第一个用属性定义的 Canvas 忽略了 box-sizing (边框添加到宽度/高度)。

我最初认为它与属性的使用有关,但在使用 imgiframe 时似乎无法正常工作。

.canvas {
  width:150px;
  height:150px;
}
iframe,img {
  box-sizing:border-box;
  border:5px solid;
}
<iframe height="150" width="150"></iframe>
<iframe class="canvas"></iframe>

<img height="150" width="150" src="https://picsum.photos/200/300?image=1069">
<img class="canvas" src="https://picsum.photos/200/300?image=1069">

为什么 canvas 元素会有这样的行为?


经过一些搜索,我发现应该避免使用 Canvas 的宽度/高度属性,因为它会缩放 Canvas 并且不会像我们想象的那样调整它的大小。

var canvas = document.querySelector("canvas"),
ctx = canvas.getContext("2d");
ctx.fillRect(0, 0, 150, 150);
canvas {
  width: 150px;
  height: 150px;
  border:1px solid red;
}
<canvas ></canvas>

直觉上,上面的代码应该生成一个 150x150 正方形,但我们以一个矩形结尾!这是因为 Canvas 最初是 300x150(默认尺寸),我们的正方形是在里面绘制的。然后我们像处理图像一样缩放整个想法,我们得到了不需要的结果。

但是,使用属性将创建所需的结果:

var canvas = document.querySelector("canvas"),
ctx = canvas.getContext("2d");
ctx.fillRect(0, 0, 150, 150);
canvas {
  border:1px solid red;
}
<canvas height="150" width="150"></canvas>

这在某种程度上解释了为什么浏览器忽略 box-sizing 以避免收缩效果,但它仍然违反直觉,因为它可能会导致 canvas< 之外的其他不需要的问题。如果这是原因,那么浏览器也应该对 img 执行相同的操作,因为它们面临相同的收缩效果。

那么,为什么会有这样的行为呢?为什么浏览器决定忽略 box-sizing 而不是缩小 Canvas ?

最重要的问题:这种行为是在哪里定义的?

我找不到规范的哪一部分正在处理这个问题。

最佳答案

作为一个猜测,我会说它是 this paragraph from the spec .

When its canvas context mode is none, a canvas element has no rendering context, and its bitmap must be fully transparent black with an intrinsic width equal to the numeric value of the element’s width attribute and an intrinsic height equal to the numeric value of the element’s height attribute, those values being interpreted in CSS pixels, and being updated as the attributes are set, changed, or removed.

也就是说位图必须取自高度和宽度属性。框大小无关紧要。

另请注意,HTML5 渲染部分指出:

The width and height attributes on embed, iframe, img, object or video elements, and input elements with a type attribute in the Image Button state and that either represents an image or that the user expects will eventually represent an image, map to the dimension properties width and height on the element respectively.

那里没有提到 Canvas。

关于css - 为什么 box-sizing 不适用于 canvas 元素上的宽度/高度属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53575931/

相关文章:

html - 如何使用CSS将文本与其阴影分开

javascript - .html() 返回空

javascript - setTimeout 似乎正在改变我的变量!为什么?

javascript - Canvas 在动画之间闪烁

HTML 表单字段和边距显示

css - 使用 ExtJS 和 CSS 在占位符中为星号应用红色

javascript - 在 JavaScript 中绘制文本字段的实现

javascript - 在 EaselJS 中显示/隐藏位图

html - Bootstrap : Well is not aligned to form

html - wordpress 中的代码无法运行,尽管它可以在其他平台上运行