小编典典

为什么box-sizing无法在canvas元素上使用width / height属性?

css

让我们考虑以下代码:

.canvas {

  width:150px;

  height:150px;

}

canvas {

  box-sizing:border-box;

  border:5px solid;

}


<canvas height="150" width="150"></canvas>

<canvas class="canvas"></canvas>

我们canvas定义了两个具有相同的宽度/高度,相同的边框和box-sizing:border- box。我们可以清楚地看到,使用CSS属性的画布是尊重的box-sizing(边界从宽度/高度减小),但是用属性定义的第一个忽略box- sizing(边界被添加到宽度/高度)。

我首先认为这与属性的使用有关,但似乎与使用imgor 时不一样iframe

.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元素?


经过一番搜索,我发现应该避免在画布上使用width / height属性,因为它将缩放画布并且不会像我们想象的那样调整其大小。

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正方形,但是我们以一个矩形结尾!这是因为最初是画布300x150(默认尺寸),而正方形是在内部绘制的。然后,我们像对图像一样缩放整个思维,并获得了不想要的结果。

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

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而不是缩小画布?

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

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


阅读 581

收藏
2020-05-16

共1个答案

小编典典

推测一下,我会说这是规范中的这一段。

当其canvas上下文模式为none时,canvas元素不具有渲染上下文,并且其位图必须为完全透明的黑色,其固有宽度等于该元素的width属性的数值,而其固有高度等于该元素的width属性的数值。
height属性,这些值将以CSS像素进行解释,并在设置,更改或删除属性时进行更新。

那就是 位图 必须取自height和width属性。大小调整不起作用。

另请注意,HTML5呈现部分指出:

嵌入,iframe,img,对象或视频元素上的width和height属性,以及在Image
Button状态下具有type属性并且表示图像或用户期望最终表示图像的输入元素,映射到尺寸属性分别在元素上的宽度和高度。

那里没有提到帆布。

2020-05-16