Skip to content
Advertisement

What is causing my Canvas element to overflow and what can I do to fix it?

I have a problem with sizing my canvas element properly. The result as seen below is a canvas element (green outline) that extends it’s height outside of it’s parent div. What is causing this problem and what can I do to fix it?

resulting

HTML: Here is the HTML code, there isn’t much to it.

<div id="container">
    <div id="content">
        <div id="menu">
            ...
        </div>
        <div id="canvas-container">
            <canvas>
    
            </canvas>
        </div>
    </div>
</div>

SCSS: The more interesting SCSS code.

* {
    margin: 0;
    padding: 0;
}

html,
body {
    height: 100%;
    font-size: 16px;
    font-family: 'Inter', sans-serif,
}

#container {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;

    #content {
        outline: 2px solid rgb(0, 0, 0);
        width: 80%;
        height: 80%;

        #menu {
            padding: 1em;
            border-bottom: 2px solid black;

            select {
                padding: 1em;
            }

            a {
                background-color: rgb(91, 134, 195);
                text-decoration: none;
                font-weight: bold;
                padding: 0.8em;
                color: white;
            }

            a:hover {
                background-color: rgb(75, 122, 189);
            }

        }

        #canvas-container {
            width: 100%;
            height: 100%;

            canvas {
                outline: 2px solid green;
            }
        }

    }

}

Javascript: And lastly the JS code that actually does the sizing of the Canvas element.

var canvas = document.querySelector('canvas');
fitToContainer(canvas);

function fitToContainer(canvas){
  // Make it visually fill the positioned parent
  canvas.style.width ='100%';
  canvas.style.height='100%';
  // ...then set the internal size to match
  canvas.width  = canvas.offsetWidth;
  canvas.height = canvas.offsetHeight;
}

Advertisement

Answer

Whenever you use a height of 100% and you want the height based on it’s parent, you need to set the parents position to relative.

Also the layout your using looks like it will fit into a flexbox layout nicely.

Lastly, if you want this to be responsive, your going to want to attach a resize event for setting the canvas size.

Below is an example of using these techniques, I’ve also included a footer section, flexbox makes these layout a breeze. hint: run the snippet fullscreen, and resize the window to see the resizing in action.

const c = document.querySelector('canvas');
const cc = document.querySelector('.canvas-container');

function drawSomething() {
  const ctx = c.getContext('2d');
  const w = c.offsetWidth; h = c.offsetHeight;
  const cnt = 25;
  const sw = w / cnt; sh = h / cnt;
  for (let l = 0; l <= cnt; l ++) {
    ctx.moveTo(0, l * sh);
    ctx.lineTo(w - l * sw, 0);
    ctx.moveTo(w, l * sh);
    ctx.lineTo(l * sw, 0);
    ctx.moveTo(0, l * sh);
    ctx.lineTo(w - l * sw, h);
    ctx.moveTo(w, l * sh);
    ctx.lineTo(l * sw, h);
  }
  ctx.stroke();
}

function resize() {
  c.width  = cc.offsetWidth;
  c.height = cc.offsetHeight;
  drawSomething(); 
}

window.addEventListener('resize', resize);
resize();
body {
  margin: 0;
}

.container {
  overflow: hidden;
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.header, .footer {
  color: white;
  background-color: green;
}


.canvas-container {
  flex: 1;
  position: relative;
}

canvas {
  background-color: lightgreen;
  position: absolute;
}
<div class="container">
  <div class="header">This is the menu</div>
  <div class="canvas-container">
    <canvas></canvas>
  </div>
  <div class="footer">footer</div>
</div>
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement