object-fit
1 will only take effect when there is a change in aspect ratio (a distortion) and applies solely to replaced elements (canvas
being a replaced element)
Here's a simple example:
var canvas = document.querySelectorAll("canvas");
for (var i = 0; i < canvas.length; i++) {
ctx = canvas[i].getContext("2d");
ctx.fillRect(50, 50, 100, 100);
}
canvas {
width: 100px;
height: 250px;
border: 1px solid red;
display: block;
}
.box {
display: inline-block;
border: 2px solid green
}
<div class="box">
<canvas width="200" height="200"></canvas>
</div>
<div class="box">
<canvas width="200" height="200" style="object-fit:contain;"></canvas>
</div>
<div class="box">
<canvas width="200" height="200" style="object-fit:cover;"></canvas>
</div>
As shown, I set the canvas dimensions to 200x200
(1:1 ratio), then altered it using CSS, breaking the ratio (no longer a square) where object-fit
comes into play to correct this.
A relevant question to grasp the distinction between setting width/height via attribute and with CSS: Why box-sizing is not working with width/height attribute on canvas element?
1According to the specification, all values (except the default fill
) strive to maintain the aspect ratio:
contain
The replaced content is sized to maintain its aspect ratio while fitting within the element’s content box: its concrete object size is resolved as a contain constraint against the element’s used width and height.
cover
The replaced content is sized to maintain its aspect ratio while filling the element’s entire content box: its concrete object size is resolved as a cover constraint against the element’s used width and height.
none
The replaced content is not resized to fit inside the element’s content box: determine the object’s concrete object size using the default sizing algorithm with no specified size, and a default object size equal to the replaced element’s used width and height.
The none
value is a bit tricky but essentially means maintaining the intrinsic default image size without scaling like contain
or cover
var canvas = document.querySelectorAll("canvas");
for (var i = 0; i < canvas.length; i++) {
ctx = canvas[i].getContext("2d");
ctx.fillRect(50, 50, 100, 100);
}
.box canvas {
border: 1px solid red;
display: block;
object-fit:none;
}
.box {
display: inline-block;
border: 2px solid green
}
<canvas width="200" height="200"></canvas>
<div class="box">
<canvas width="200" height="200" style="width:100px;height:200px;"></canvas>
</div>
<div class="box">
<canvas width="200" height="200" style="height:50px;width:200px;"></canvas>
</div>
Related: CSS object-fit: contain; is keeping original image width in layout