1

I try to overlay a canvas exactly on top of a 256px by 256px image (of 8x8 grids) and draw an 8x8 black square --

    var canvas = document.querySelector("canvas");
    canvas.width = 1024;
    canvas.height = 1024;
    var c = canvas.getContext("2d");
    c.fillRect(0, 0, 8, 8);
    #wrapper {
      margin: 0 auto;
      width: 256px;
    }
    
    #img {
      position: relative;
      top: 0;
      left: 0;
    }
    
    #canvas {
      position: relative;
      margin-top: 0;
      margin-left: 0;
      top: -256px;
      left: 0;
      z-index: 1;
    }
    <html>
      <body>
        <div id="wrapper">
          <img id="img" src="https://i.imgur.com/0qjIa89.png" />
          <canvas id="canvas"></canvas>
        </div>
      </body>
    </html>

However, I don't understand why the black square drawn is slightly offset down relative to the grid image --

enter image description here

complete jsfiddle https://jsfiddle.net/ze8ufqcv/7/

How to position the canvas drawing exactly on top of the image?

kiner_shah
  • 3,939
  • 7
  • 23
  • 37
Jerry Ji
  • 386
  • 1
  • 3
  • 15
  • 2
    https://jsfiddle.net/ze8ufqcv/11/ add display: block; to image – Madhawa Priyashantha Mar 04 '18 at 11:23
  • Thanks @"Fast Snail", that's really _fast_. If you care to put it in the answer with a simple explanation of how "display: block;" does the trick (as oppose to the default "display: inline;" I guess) I'd be more than happy to accept your answer. – Jerry Ji Mar 04 '18 at 11:36

3 Answers3

2

This issue is due to the img having a vertical-align: baseline which causes 3px space to be added at the bottom. You can remove this by adding vertical align: middle to the img. Since vertical-align doesn't apply to block-level elements, display:block does the job as well.

var canvas = document.querySelector("canvas");
canvas.width = 1024;
canvas.height = 1024;
var c = canvas.getContext("2d");
c.fillRect(0, 0, 8, 8);
#wrapper {
  margin: 0 auto;
  width: 256px;
}

#img {
  position: relative;
  vertical-align: middle;
  /*or display: block*/
  /* not necessary
  top: 0;
  left: 0; */
}

#canvas {
  position: relative;
  margin-top: 0;
  margin-left: 0;
  top: -256px;
  left: 0;
  z-index: 1;
}
<body>
  <div id="wrapper">
    <img id="img" src="https://i.imgur.com/0qjIa89.png" />
    <canvas id="canvas"></canvas>
  </div>
</body>
Rocks
  • 1,145
  • 9
  • 13
  • Found a better explanation which you can refer to here: https://stackoverflow.com/questions/10844205/html-5-strange-img-always-adds-3px-margin-at-bottom/10844318 – Rocks Mar 04 '18 at 11:46
  • Thanks a bunch! I wish I can accept your answer as well or have enough reputation to up vote it – Jerry Ji Mar 04 '18 at 11:50
2

The accepted answer is not shifting the image a few pixels down, but actually eliminating the gap between the initial position of the two elements. You can see this by leaving out the top: -256px; and you'll find a few pixels space in between the image and your canvas. This is eliminated by adding the display:block; .

An alternative would be setting the wrapper to position:relative; and the canvas to position:absolute; and deleting the top offset.

Ingo86
  • 86
  • 6
0

Add display: block; to your #img selector.

Like this .

#img {
  position: relative;
  top: 0;
  left: 0;
  display: block;
}
Anzil khaN
  • 1,974
  • 1
  • 19
  • 30
  • 2
    This is the correct answer, however, I'd much appreciate if someone can explain why "display: block;" for img actually shifts the canvas a few pixels up – Jerry Ji Mar 04 '18 at 11:39
  • I don't know the exact reason , when i have extra spacing problem i will do like this. – Anzil khaN Mar 04 '18 at 11:47