让我们考虑以下代码:
.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(边界被添加到宽度/高度)。
canvas
box-sizing:border- box
box-sizing
box- sizing
我首先认为这与属性的使用有关,但似乎与使用imgor 时不一样iframe。
img
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(默认尺寸),而正方形是在内部绘制的。然后,我们像对图像一样缩放整个思维,并获得了不想要的结果。
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而不是缩小画布?
最重要的问题: 这种行为在哪里定义?
我找不到规范的哪一部分正在处理此问题。
推测一下,我会说这是规范中的这一段。
当其canvas上下文模式为none时,canvas元素不具有渲染上下文,并且其位图必须为完全透明的黑色,其固有宽度等于该元素的width属性的数值,而其固有高度等于该元素的width属性的数值。 height属性,这些值将以CSS像素进行解释,并在设置,更改或删除属性时进行更新。
那就是 位图 必须取自height和width属性。大小调整不起作用。
另请注意,HTML5呈现部分指出:
嵌入,iframe,img,对象或视频元素上的width和height属性,以及在Image Button状态下具有type属性并且表示图像或用户期望最终表示图像的输入元素,映射到尺寸属性分别在元素上的宽度和高度。
那里没有提到帆布。