Skip to content
Advertisement

html5/css/javascript : How to superpose two canvas in a div

function drawAll() {
  // Upper zone, 8 grey transparent buttons
  let canvas0 = document.getElementById("layer0");
  canvas0.width = 1000;
  canvas0.height = 100;
  let bandeau = canvas0.getContext("2d");
  bandeau.fillStyle = "rgba(128,128,80,0.3)";

  for (var i = 0; i < 8; i++) {
    bandeau.beginPath;
    bandeau.arc(50 + 110 * i, 50, 45, 0, 2 * Math.PI);
    bandeau.fill();
  }

  // Lower zone, a red rectangle partially under the buttons
  let canvas1 = document.getElementById("layer1");
  canvas1.width = 1000;
  canvas1.height = 1000;
  let dessin = canvas1.getContext("2d");
  dessin.fillStyle = "red";
  dessin.fillRect(30, 50, 800, 200);
  canvas0.style.visibility = "visible";
  canvas1.style.visibility = "visible";
}

drawAll()
body {
  background-color: rgb(249, 249, 250);
}

.container {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  z-index: -10;
}

.scrollable {
  position: absolute;
  top: 0px;
  left: 0px;
  z-index: 1;
}

.fixed {
  position: absolute;
  top: 0px;
  left: 0px;
  z-index: 2;
}
<div class="container">
  <canvas id="layer0" class="scrollable"></canvas>
  <canvas id="layer1" class="fixed"></canvas>
</div>

Hello

I’m stuck on a superposition problem of two canvas. Here is a simplified example. Note that in the real application, buttons and drawings are far more complicated and that I want to keep the structure with html5 / css / javascript.

I suppose that I miss something in the css to succeed to have these two canvas superposed, buttons partially covering the red rectangle, but what ?

Thanks if somebody can help.

Advertisement

Answer

The problem is that <body> doesn’t have any height, which makes the .container height of 100% equally zero.

Absolutely positioned elements do no contribute to their parent’s height. As soon as you start giving .container an actual height, you can see its content. In the example below, I went for 100vw and 100vh for width and height, but since your canvases are 1000px wide, you could also use that or any other value.


An absolutely positioned element no longer exists in the normal document layout flow. Instead, it sits on its own layer separate from everything else.

Source: MDN Web Docs


The other option is to remove overflow: hidden; from .container and show everything outside of it.

function drawAll() {
  // Upper zone, 8 grey transparent buttons
  let canvas0 = document.getElementById("layer0");
  canvas0.width = 1000;
  canvas0.height = 100;
  let bandeau = canvas0.getContext("2d");
  bandeau.fillStyle = "rgba(128,128,80,0.3)";

  for (var i = 0; i < 8; i++) {
    bandeau.beginPath;
    bandeau.arc(50 + 110 * i, 50, 45, 0, 2 * Math.PI);
    bandeau.fill();
  }

  // Lower zone, a red rectangle partially under the buttons
  let canvas1 = document.getElementById("layer1");
  canvas1.width = 1000;
  canvas1.height = 1000;
  let dessin = canvas1.getContext("2d");
  dessin.fillStyle = "red";
  dessin.fillRect(30, 50, 800, 200);
  canvas0.style.visibility = "visible";
  canvas1.style.visibility = "visible";
}

drawAll()
body {
  background-color: rgb(249, 249, 250);
}

.container {
  position: relative;
  overflow: hidden;
  z-index: -10;
  height: 100vh;
  width: 100vw;
}

.scrollable {
  position: absolute;
  top: 0px;
  left: 0px;
  z-index: 1;
}

.fixed {
  position: absolute;
  top: 0px;
  left: 0px;
  z-index: 2;
}
<div class="container">
  <canvas id="layer0" class="scrollable"></canvas>
  <canvas id="layer1" class="fixed"></canvas>
</div>
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement