让我们考虑一下这段代码:
.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
(边框添加到宽度/高度)。
我首先认为它与属性的使用有关,但在使用img
or时似乎不像预期的那样工作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
元素有这种行为?
经过一番搜索,我发现应该避免对画布使用宽度/高度属性,因为它会缩放画布并且不会像我们想象的那样调整它的大小。
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
而不是缩小画布?
最重要的问题:这种行为在哪里定义?
我无法找到规范的哪一部分正在处理这个问题。
作为猜测,我会说这是spec 中的这一段。
当其canvas上下文模式为none时,canvas元素没有渲染上下文,其位图必须是全透明黑色,固有宽度等于元素width属性的数值,固有高度等于元素的数值height 属性,这些值在 CSS 像素中被解释,并随着属性的设置、更改或删除而更新。
即位图必须取自高度和宽度属性。盒子尺寸无关紧要。
还要注意 HTML5 渲染部分说:
embed、iframe、img、object 或 video 元素上的 width 和 height 属性,以及在 Image Button 状态下具有 type 属性且表示图像或用户期望最终表示图像的 input 元素,映射到维度分别为元素的宽度和高度属性。
那里没有提到画布。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句