Why Box-Sizing Is Not Working with Width/Height Attribute on Canvas Element

Why box-sizing is not working with width/height attribute on canvas element?

As a guess, I'd say it was this paragraph from the spec.

When its canvas context mode is none, a canvas element has no rendering context, and its bitmap must be fully transparent black with an intrinsic width equal to the numeric value of the element’s width attribute and an intrinsic height equal to the numeric value of the element’s height attribute, those values being interpreted in CSS pixels, and being updated as the attributes are set, changed, or removed.

That is the bitmap must be taken from the height and width attributes. Box-sizing plays no part.

Note also that the HTML5 rendering section says that:

The width and height attributes on embed, iframe, img, object or video elements, and input elements with a type attribute in the Image Button state and that either represents an image or that the user expects will eventually represent an image, map to the dimension properties width and height on the element respectively.

Canvas is not mentioned there.

Canvas is stretched when using CSS but normal with width / height properties

It seems that the width and height attributes determine the width or height of the canvas’s coordinate system, whereas the CSS properties just determine the size of the box in which it will be shown.

This is explained in the HTML specification:

The canvas element has two attributes to control the size of the element’s bitmap: width and height. These attributes, when specified, must have values that are valid non-negative integers. The rules for parsing non-negative integers must be used to obtain their numeric values. If an attribute is missing, or if parsing its value returns an error, then the default value must be used instead. The width attribute defaults to 300, and the height attribute defaults to 150.

Canvas width and height in HTML5

The canvas DOM element has .height and .width properties that correspond to the height="…" and width="…" attributes. Set them to numeric values in JavaScript code to resize your canvas. For example:

var canvas = document.getElementsByTagName('canvas')[0];
canvas.width = 800;
canvas.height = 600;

Note that this clears the canvas, though you should follow with ctx.clearRect( 0, 0, ctx.canvas.width, ctx.canvas.height); to handle those browsers that don't fully clear the canvas. You'll need to redraw of any content you wanted displayed after the size change.

Note further that the height and width are the logical canvas dimensions used for drawing and are different from the style.height and style.width CSS attributes. If you don't set the CSS attributes, the intrinsic size of the canvas will be used as its display size; if you do set the CSS attributes, and they differ from the canvas dimensions, your content will be scaled in the browser. For example:

// Make a canvas that has a blurry pixelated zoom-in
// with each canvas pixel drawn showing as roughly 2x2 on screen
canvas.width = 400;
canvas.height = 300;
canvas.style.width = '800px';
canvas.style.height = '600px';

See this live example of a canvas that is zoomed in by 4x.

var c = document.getElementsByTagName('canvas')[0];var ctx = c.getContext('2d');ctx.lineWidth   = 1;ctx.strokeStyle = '#f00';ctx.fillStyle   = '#eff';
ctx.fillRect( 10.5, 10.5, 20, 20 );ctx.strokeRect( 10.5, 10.5, 20, 20 );ctx.fillRect( 40, 10.5, 20, 20 );ctx.strokeRect( 40, 10.5, 20, 20 );ctx.fillRect( 70, 10, 20, 20 );ctx.strokeRect( 70, 10, 20, 20 );
ctx.strokeStyle = '#fff';ctx.strokeRect( 10.5, 10.5, 20, 20 );ctx.strokeRect( 40, 10.5, 20, 20 );ctx.strokeRect( 70, 10, 20, 20 );
body { background:#eee; margin:1em; text-align:center }canvas { background:#fff; border:1px solid #ccc; width:400px; height:160px }
<canvas width="100" height="40"></canvas><p>Showing that re-drawing the same antialiased lines does not obliterate old antialiased lines.</p>

Why do I need to have the width at 400px and height at 200px in a canvas element for this?

The style= defines the scaling - use width= and height= to set the size of the box.

Also explained here (MDN canvas element).

The displayed size of the canvas can be changed using CSS, but if you do this the image is scaled during rendering to fit the styled size, which can make the final graphics rendering end up being distorted.

It is better to specify your canvas dimensions by setting the width and height attributes directly on the elements, either directly in the HTML or by using JavaScript.

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
var a = document.getElementById("3d");
var b = a.getContext("2d");
b.beginPath();
b.moveTo(0,50);
b.lineTo(0,100);
b.lineTo(50,150);
b.lineTo(50,100);
b.lineTo(0,50);
b.lineTo(50,0);
b.lineTo(100,50);
b.lineTo(100,100);
b.lineTo(50,150);
b.lineTo(50,100);
b.lineTo(100,50);
b.stroke();
});
</script>
</head>
<body>
<canvas id="3d" width="200" height="200" style="border:1px solid black"></canvas>
</body>
</html>


Related Topics



Leave a reply



Submit