让我们考虑以下代码:
.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
(边界被添加到width /高度)。
我首先认为它与属性的使用有关,但似乎与使用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
(默认尺寸),而正方形是在内部绘制的。然后我们像对图像一样缩放整个思维,并获得不需要的结果。
但是,使用属性会创建所需的结果:
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
而不是缩小画布?
最重要的问题:在哪里定义了这种行为?
我找不到规范的哪一部分正在处理此问题。
答案 0 :(得分:3)
我猜是this paragraph from the spec。
当其画布上下文模式为none时,画布元素没有渲染上下文,并且其位图必须为完全透明的黑色,其固有宽度等于该元素的width属性的数值,固有高度等于该数值元素的height属性的值,这些值将以CSS像素进行解释,并随着属性的设置,更改或删除而更新。
这是位图,必须从height和width属性中获取。大小调整不起作用。
还请注意,HTML5呈现部分指出:
嵌入,iframe,img,对象或视频元素上的width和height属性以及在Image Button状态下具有type属性的输入元素,它们要么表示图像,要么用户期望最终表示图像,地图分别设置为元素的尺寸属性的宽度和高度。
那里没有提到帆布。
答案 1 :(得分:1)
对于,这些将取决于所加载的资源,但是对于光栅图像,它非常简单地将使用介质中定义的图像。
因此,要使案例与您的
.canvas {
width:150px;
height:150px;
}
iframe,img {
box-sizing:border-box;
border:5px solid;
}
<!-- equivalent to
<canvas width="150" height="150"></canvas>
load a 150x150px image -->
<img src="https://picsum.photos/150/150?image=1069">
<!-- equivalent to
<canvas class="canvas"></canvas>
load a 300x150px image -->
<img class="canvas" src="https://picsum.photos/300/150?image=1069">
现在,我们看到
当计算出的width
和height
为auto
时,box-sizing
不起作用,其固有的 width 和 height 正在被使用。
通过CSS进行设置时,CSS会胜出,并且box-sizing
个母版。