57

I don't get why the following pieces of code produce different results, because css would scale the canvas as it was zoomed in,

<style>
#canvas {
    width: 800px;
    height: 600px;
}
</style>
<canvas id="canvas"></canvas>

In contrast with this approach (that works as expected):

<canvas id="canvas" width="800px" height="600px"></canvas>
Phrogz
  • 296,393
  • 112
  • 651
  • 745
Joaquín L. Robles
  • 6,261
  • 10
  • 66
  • 96
  • Could you explain what you mean by "because css would scale the canvas as it was zoomed in"? Cheers! – polarblau Feb 17 '11 at 21:06
  • 2
    Yes, when you apply the css styling, the canvas fits 800x600 but the content inside it is "enlarged", it's like the canvas coordinate system keeps it's default size, but is "stretched". Let me know if I'm not clear enought. I'm using Firefox 4.0b11 – Joaquín L. Robles Feb 17 '11 at 21:25
  • This may help: http://stackoverflow.com/questions/1977741/resizable-canvas-jquery-ui/2042935 – Xavi Feb 17 '11 at 22:01
  • 8
    Note that the `width` and `height` attributes of the canvas should not have dimensions (unlike CSS). You should have `width="800"`, not `width="800px"`. – Phrogz Feb 18 '11 at 19:30
  • 1
    s/dimensions/explicit pixel units/ – Quentin Feb 19 '11 at 20:19
  • This question is also answered here: http://stackoverflow.com/a/24608862/687677 – superluminary Jul 07 '14 at 10:52
  • @Phrogz why shouldn't it be specified? – Startec Jul 11 '15 at 20:38
  • Possible duplicate of [Canvas is stretched when using CSS but normal with "width" / "height" properties](http://stackoverflow.com/questions/2588181/canvas-is-stretched-when-using-css-but-normal-with-width-height-properties) – Amir Ali Akbari Feb 29 '16 at 14:42
  • une explication claire , précise...et fondamentale ! : https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html – oceanGermanique May 21 '23 at 07:58

3 Answers3

72

Think about what happens if you have a JPG that is 32x32 (it has exactly 1024 total pixels) but specify via CSS that it should appear as width:800px; height:16px. The same thing applies to HTML Canvas:

  • The width and height attributes of the canvas element itself decide how many pixels you can draw on. If you don't specify the height and width of the canvas element, then per the specs:
    "the width attribute defaults to 300, and the height attribute defaults to 150."

  • The width and height CSS properties control the size that the element displays on screen. If the CSS dimensions are not set, the intrinsic size of the element is used for layout.

If you specify in CSS a different size than the actual dimensions of the canvas it must be stretched and squashed by the browser as necessary for display. You can see an example of this here: http://jsfiddle.net/9bheb/5/

Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • 1
    @Phrogz's answer is clearer than the accepted answer. A canvas with pixel dimensions specified by its `height` and `width` HTML attributes (or the default 300x150) will be scaled to the size specified by CSS properties. – Becca Dee Sep 10 '17 at 19:47
  • @Phrogz this seems to be the correct answer in my opinion. – Akshay Gaur Sep 15 '17 at 17:31
  • 2
    As an addition here is what I am using so that the canvas takes it's size from CSS. The `substring` is to remove the `px` from the end of the string `const canvas = document.querySelector("canvas"); const compStyles = window.getComputedStyle(canvas); canvas.width = compStyles.width.substr(0, compStyles.width.length - 2); canvas.height = compStyles.height.substr(0, compStyles.height.length - 2);` – Tibor Udvari Apr 19 '19 at 13:47
  • What if I want to change the _actual_ size of the canvas when the browser is resized? – Ron Inbar Jun 08 '21 at 17:44
  • 1
    @RonInbar The add an event listener for the resize event, and set the `width` and `height` attributes of the canvas element to match the `offsetWidth` and `offsetHeight` properties showing its actual size. For example: https://stackoverflow.com/a/8686566/405017 http://phrogz.net/tmp/canvas-fullscreen.html – Phrogz Jun 08 '21 at 21:28
64

The explanation is here: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#attr-canvas-width as seen in another post, thanks!

The intrinsic dimensions of the canvas element equal the size of the coordinate space, with the numbers interpreted in CSS pixels. However, the element can be sized arbitrarily by a style sheet. During rendering, the image is scaled to fit this layout size.

Joaquín L. Robles
  • 6,261
  • 10
  • 66
  • 96
-3

The best way to size your canvas is to include in a div and style your div with the size that you want.

Here is the CSS

<style>
#divCanvas{
    width: 800px;
    height: 600px;
}
</style>

Here is the HTML

<div id="divCanvas">
    <canvas id="canvas"></canvas>
</div>