[html] Canvas width and height in HTML5

Is it possible to fix the width and height of an HTML5 canvas element?

The usual way is the following :

<canvas id="canvas" width="300" height="300"></canvas>

This question is related to html canvas

The answer is


A canvas has 2 sizes, the dimension of the pixels in the canvas (it's backingstore or drawingBuffer) and the display size. The number of pixels is set using the the canvas attributes. In HTML

<canvas width="400" height="300"></canvas>

Or in JavaScript

someCanvasElement.width = 400;
someCanvasElement.height = 300;

Separate from that are the canvas's CSS style width and height

In CSS

canvas {  /* or some other selector */
   width: 500px;
   height: 400px;
}

Or in JavaScript

canvas.style.width = "500px";
canvas.style.height = "400px";

The arguably best way to make a canvas 1x1 pixels is to ALWAYS USE CSS to choose the size then write a tiny bit of JavaScript to make the number of pixels match that size.

function resizeCanvasToDisplaySize(canvas) {
   // look up the size the canvas is being displayed
   const width = canvas.clientWidth;
   const height = canvas.clientHeight;

   // If it's resolution does not match change it
   if (canvas.width !== width || canvas.height !== height) {
     canvas.width = width;
     canvas.height = height;
     return true;
   }

   return false;
}

Why is this the best way? Because it works in most cases without having to change any code.

Here's a full window canvas:

_x000D_
_x000D_
const ctx = document.querySelector("#c").getContext("2d");_x000D_
_x000D_
function render(time) {_x000D_
  time *= 0.001;_x000D_
  resizeCanvasToDisplaySize(ctx.canvas);_x000D_
 _x000D_
  ctx.fillStyle = "#DDE";_x000D_
  ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);_x000D_
  ctx.save();_x000D_
 _x000D_
  const spacing = 64;_x000D_
  const size = 48;_x000D_
  const across = ctx.canvas.width / spacing + 1;_x000D_
  const down = ctx.canvas.height / spacing + 1;_x000D_
  const s = Math.sin(time);_x000D_
  const c = Math.cos(time);_x000D_
  for (let y = 0; y < down; ++y) {_x000D_
    for (let x = 0; x < across; ++x) {_x000D_
      ctx.setTransform(c, -s, s, c, x * spacing, y * spacing);_x000D_
      ctx.strokeRect(-size / 2, -size / 2, size, size);_x000D_
    }_x000D_
  }_x000D_
  _x000D_
  ctx.restore();_x000D_
  _x000D_
  requestAnimationFrame(render);_x000D_
}_x000D_
requestAnimationFrame(render);_x000D_
_x000D_
function resizeCanvasToDisplaySize(canvas) {_x000D_
   // look up the size the canvas is being displayed_x000D_
   const width = canvas.clientWidth;_x000D_
   const height = canvas.clientHeight;_x000D_
_x000D_
   // If it's resolution does not match change it_x000D_
   if (canvas.width !== width || canvas.height !== height) {_x000D_
     canvas.width = width;_x000D_
     canvas.height = height;_x000D_
     return true;_x000D_
   }_x000D_
_x000D_
   return false;_x000D_
}
_x000D_
body { margin: 0; }_x000D_
canvas { display: block; width: 100vw; height: 100vh; }
_x000D_
<canvas id="c"></canvas>
_x000D_
_x000D_
_x000D_

And Here's a canvas as a float in a paragraph

_x000D_
_x000D_
const ctx = document.querySelector("#c").getContext("2d");_x000D_
_x000D_
function render(time) {_x000D_
  time *= 0.001;_x000D_
  resizeCanvasToDisplaySize(ctx.canvas);_x000D_
 _x000D_
  ctx.fillStyle = "#DDE";_x000D_
  ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);_x000D_
  ctx.save();_x000D_
 _x000D_
  const spacing = 64;_x000D_
  const size = 48;_x000D_
  const across = ctx.canvas.width  / spacing + 1;_x000D_
  const down   = ctx.canvas.height / spacing + 1;_x000D_
  const s = Math.sin(time);_x000D_
  const c = Math.cos(time);_x000D_
  for (let y = 0; y <= down; ++y) {_x000D_
    for (let x = 0; x <= across; ++x) {_x000D_
      ctx.setTransform(c, -s, s, c, x * spacing, y * spacing);_x000D_
      ctx.strokeRect(-size / 2, -size / 2, size, size);_x000D_
    }_x000D_
  }_x000D_
  _x000D_
  ctx.restore();_x000D_
  _x000D_
  requestAnimationFrame(render);_x000D_
}_x000D_
requestAnimationFrame(render);_x000D_
_x000D_
function resizeCanvasToDisplaySize(canvas) {_x000D_
   // look up the size the canvas is being displayed_x000D_
   const width = canvas.clientWidth;_x000D_
   const height = canvas.clientHeight;_x000D_
_x000D_
   // If it's resolution does not match change it_x000D_
   if (canvas.width !== width || canvas.height !== height) {_x000D_
     canvas.width = width;_x000D_
     canvas.height = height;_x000D_
     return true;_x000D_
   }_x000D_
_x000D_
   return false;_x000D_
}
_x000D_
span { _x000D_
   width: 250px; _x000D_
   height: 100px; _x000D_
   float: left; _x000D_
   padding: 1em 1em 1em 0;_x000D_
   display: inline-block;_x000D_
}_x000D_
canvas {_x000D_
   width: 100%;_x000D_
   height: 100%;_x000D_
}
_x000D_
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus venenatis metus. Mauris ac nibh at odio scelerisque scelerisque. Donec ut enim <span class="diagram"><canvas id="c"></canvas></span>_x000D_
vel urna gravida imperdiet id ac odio. Aenean congue hendrerit eros id facilisis. In vitae leo ullamcorper, aliquet leo a, vehicula magna. Proin sollicitudin vestibulum aliquet. Sed et varius justo._x000D_
<br/><br/>_x000D_
Quisque tempor metus in porttitor placerat. Nulla vehicula sem nec ipsum commodo, at tincidunt orci porttitor. Duis porttitor egestas dui eu viverra. Sed et ipsum eget odio pharetra semper. Integer tempor orci quam, eget aliquet velit consectetur sit amet. Maecenas maximus placerat arcu in varius. Morbi semper, quam a ullamcorper interdum, augue nisl sagittis urna, sed pharetra lectus ex nec elit. Nullam viverra lacinia tellus, bibendum maximus nisl dictum id. Phasellus mauris quam, rutrum ut congue non, hendrerit sollicitudin urna._x000D_
</p>
_x000D_
_x000D_
_x000D_

Here's a canvas in a sizable control panel

_x000D_
_x000D_
const ctx = document.querySelector("#c").getContext("2d");_x000D_
_x000D_
function render(time) {_x000D_
  time *= 0.001;_x000D_
  resizeCanvasToDisplaySize(ctx.canvas);_x000D_
_x000D_
  ctx.fillStyle = "#DDE";_x000D_
  ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);_x000D_
  ctx.save();_x000D_
 _x000D_
  const spacing = 64;_x000D_
  const size = 48;_x000D_
  const across = ctx.canvas.width / spacing + 1;_x000D_
  const down = ctx.canvas.height / spacing + 1;_x000D_
  const s = Math.sin(time);_x000D_
  const c = Math.cos(time);_x000D_
  for (let y = 0; y < down; ++y) {_x000D_
    for (let x = 0; x < across; ++x) {_x000D_
      ctx.setTransform(c, -s, s, c, x * spacing, y * spacing);_x000D_
      ctx.strokeRect(-size / 2, -size / 2, size, size);_x000D_
    }_x000D_
  }_x000D_
  _x000D_
  ctx.restore();_x000D_
  _x000D_
  requestAnimationFrame(render);_x000D_
}_x000D_
requestAnimationFrame(render);_x000D_
_x000D_
function resizeCanvasToDisplaySize(canvas) {_x000D_
   // look up the size the canvas is being displayed_x000D_
   const width = canvas.clientWidth;_x000D_
   const height = canvas.clientHeight;_x000D_
_x000D_
   // If it's resolution does not match change it_x000D_
   if (canvas.width !== width || canvas.height !== height) {_x000D_
     canvas.width = width;_x000D_
     canvas.height = height;_x000D_
     return true;_x000D_
   }_x000D_
_x000D_
   return false;_x000D_
}_x000D_
_x000D_
// ----- the code above related to the canvas does not change ----_x000D_
// ---- the code below is related to the slider ----_x000D_
const $ = document.querySelector.bind(document);_x000D_
const left = $(".left");_x000D_
const slider = $(".slider");_x000D_
let dragging;_x000D_
let lastX;_x000D_
let startWidth;_x000D_
_x000D_
slider.addEventListener('mousedown', e => {_x000D_
 lastX = e.pageX;_x000D_
 dragging = true;_x000D_
});_x000D_
_x000D_
window.addEventListener('mouseup', e => {_x000D_
 dragging = false;_x000D_
});_x000D_
_x000D_
window.addEventListener('mousemove', e => {_x000D_
  if (dragging) {_x000D_
    const deltaX = e.pageX - lastX;_x000D_
    left.style.width = left.clientWidth + deltaX + "px";_x000D_
    lastX = e.pageX;_x000D_
  }_x000D_
});
_x000D_
body { _x000D_
  margin: 0;_x000D_
}_x000D_
.frame {_x000D_
  display: flex;_x000D_
  align-items: space-between;_x000D_
  height: 100vh;_x000D_
}_x000D_
.left {_x000D_
  width: 70%;_x000D_
  left: 0;_x000D_
  top: 0;_x000D_
  right: 0;_x000D_
  bottom: 0;_x000D_
}  _x000D_
canvas {_x000D_
  width: 100%;_x000D_
  height: 100%;_x000D_
}_x000D_
pre {_x000D_
  padding: 1em;_x000D_
}_x000D_
.slider {_x000D_
  width: 10px;_x000D_
  background: #000;_x000D_
}_x000D_
.right {_x000D_
  flex 1 1 auto;_x000D_
}
_x000D_
<div class="frame">_x000D_
  <div class="left">_x000D_
     <canvas id="c"></canvas>_x000D_
  </div>_x000D_
  <div class="slider">_x000D_
  _x000D_
  </div>_x000D_
  <div class="right">_x000D_
     <pre>_x000D_
* controls_x000D_
* go _x000D_
* here_x000D_
_x000D_
&lt;- drag this_x000D_
     </pre>_x000D_
  </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

here's a canvas as a background

_x000D_
_x000D_
const ctx = document.querySelector("#c").getContext("2d");_x000D_
_x000D_
function render(time) {_x000D_
  time *= 0.001;_x000D_
  resizeCanvasToDisplaySize(ctx.canvas);_x000D_
 _x000D_
  ctx.fillStyle = "#DDE";_x000D_
  ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);_x000D_
  ctx.save();_x000D_
 _x000D_
  const spacing = 64;_x000D_
  const size = 48;_x000D_
  const across = ctx.canvas.width / spacing + 1;_x000D_
  const down = ctx.canvas.height / spacing + 1;_x000D_
  const s = Math.sin(time);_x000D_
  const c = Math.cos(time);_x000D_
  for (let y = 0; y < down; ++y) {_x000D_
    for (let x = 0; x < across; ++x) {_x000D_
      ctx.setTransform(c, -s, s, c, x * spacing, y * spacing);_x000D_
      ctx.strokeRect(-size / 2, -size / 2, size, size);_x000D_
    }_x000D_
  }_x000D_
  _x000D_
  ctx.restore();_x000D_
  _x000D_
  requestAnimationFrame(render);_x000D_
}_x000D_
requestAnimationFrame(render);_x000D_
_x000D_
function resizeCanvasToDisplaySize(canvas) {_x000D_
   // look up the size the canvas is being displayed_x000D_
   const width = canvas.clientWidth;_x000D_
   const height = canvas.clientHeight;_x000D_
_x000D_
   // If it's resolution does not match change it_x000D_
   if (canvas.width !== width || canvas.height !== height) {_x000D_
     canvas.width = width;_x000D_
     canvas.height = height;_x000D_
     return true;_x000D_
   }_x000D_
_x000D_
   return false;_x000D_
}
_x000D_
body { margin: 0; }_x000D_
canvas { _x000D_
  display: block; _x000D_
  width: 100vw; _x000D_
  height: 100vh;  _x000D_
  position: fixed;_x000D_
}_x000D_
#content {_x000D_
  position: absolute;_x000D_
  margin: 0 1em;_x000D_
  font-size: xx-large;_x000D_
  font-family: sans-serif;_x000D_
  font-weight: bold;_x000D_
  text-shadow: 2px  2px 0 #FFF, _x000D_
              -2px -2px 0 #FFF,_x000D_
              -2px  2px 0 #FFF,_x000D_
               2px -2px 0 #FFF;_x000D_
}
_x000D_
<canvas id="c"></canvas>_x000D_
<div id="content">_x000D_
<p>_x000D_
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus venenatis metus. Mauris ac nibh at odio scelerisque scelerisque. Donec ut enim vel urna gravida imperdiet id ac odio. Aenean congue hendrerit eros id facilisis. In vitae leo ullamcorper, aliquet leo a, vehicula magna. Proin sollicitudin vestibulum aliquet. Sed et varius justo._x000D_
</p>_x000D_
<p>_x000D_
Quisque tempor metus in porttitor placerat. Nulla vehicula sem nec ipsum commodo, at tincidunt orci porttitor. Duis porttitor egestas dui eu viverra. Sed et ipsum eget odio pharetra semper. Integer tempor orci quam, eget aliquet velit consectetur sit amet. Maecenas maximus placerat arcu in varius. Morbi semper, quam a ullamcorper interdum, augue nisl sagittis urna, sed pharetra lectus ex nec elit. Nullam viverra lacinia tellus, bibendum maximus nisl dictum id. Phasellus mauris quam, rutrum ut congue non, hendrerit sollicitudin urna._x000D_
</p>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Because I didn't set the attributes the only thing that changed in each sample is the CSS (as far as the canvas is concerned)

Notes:

  • Don't put borders or padding on a canvas element. Computing the size to subtract from the number of dimensions of the element is troublesome

Thank you very much! Finally I solved the blurred pixels problem with this code:

<canvas id="graph" width=326 height=240 style='width:326px;height:240px'></canvas>

With the addition of the 'half-pixel' does the trick to unblur lines.