math4tots math4tots - 1 year ago 50
CSS Question

Setting canvas 'width/height' in CSS results in surprising behavior

I have two HTML canvas elements, and I've drawn some lines on them.

The two canvases are basically identical except that in one I have specified the width and height using tag attributes (canvas-1), and in the other one I have specified the width and height in CSS (canvas-2).

I've found that when I log width and height (I do this in

below), the height for canvas-2 is 150 instead of 300 as I would have expected. I find it surprising that even with
very wrong, the lines were drawn basically where I would have expected them, except blurry. What is going on here? Is there a simple mental model I could adopt of HTML/CSS/canvas that could explain this?

I am on Chrome in Windows in case it is relevant.

Pic of the two canvases

Demo here: codepen link


<canvas id="canvas-1" class="outlined" width=300 height=300></canvas>
<span> __ </span>
<canvas id="canvas-2" class="outlined"></canvas>


#canvas-1 {
outline-style: solid;
#canvas-2 {
width: 300px;
height: 300px;
outline-style: solid;


function drawDividers(eid) {
var canvas = document.getElementById(eid);
var width = canvas.width;
var height = canvas.height;
console.log(eid, width, height);
var ctx = canvas.getContext('2d');
ctx.lineWidth = 1;
for (var i = 1; i <= 2; i++) {
ctx.moveTo(i*width/3, 0.1*height);
ctx.lineTo(i*width/3, 0.9*height);
ctx.moveTo(0.1*width, i*height/3);
ctx.lineTo(0.9*width, i*height/3);



This is what's happening:

A canvas has a default width of 300 pixels and a height of 150 pixels.

When you don't set them explicitly in the markup, your JavaScript lines

var width = canvas.width;
var height = canvas.height;

Return the default 300 and 150 respectively.

So the drawing is done in an area of 300x150 pixels, and then your css resizes the canvas to 300x300, and the blurring happens because of that. (like when sizing a picture beyond its original size, blurring happens.)