13

I've made a JS animation that I want to be the background of my homepage: http://geotheory.co.uk/. But I'm quite new to web development and unclear how to stop the canvas element being an 'inline' object on the page and set it behind other HTML elements. Very grateful for advice. The HTML is:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>geotheory.co.uk</title>
    <style>
        canvas:focus{outline:none;}
        * {
        margin: 0;
        padding: 0;
        }
        h1 {color:#fff;}
        p {color:#fff;}
    </style>

</head>
<body  id="home" bgcolor="black">
    <!-- style="overflow:hidden;" -->
    <h1>Heading</h1>
    <p>paragraph 1</p>
    <p>paragraph 2</p>
    <script src="processing-1.4.1.min.js"></script>
    <div id="canvasContainer">
    <canvas data-processing-sources="rectangles.pde"></canvas>
    </div>
</body>
geotheory
  • 22,624
  • 29
  • 119
  • 196
  • Make sure to put it last in the HTML so it doesn't get in the way of screen readers and such. – DanMan Dec 26 '12 at 16:44
  • possible duplicate of [An html5 canvas element in the background of my page?](http://stackoverflow.com/questions/2719668/an-html5-canvas-element-in-the-background-of-my-page) – Kate Gregory Dec 26 '12 at 17:42
  • I noticed that "outline:none" was used in your stylesheet, so: sort of irrelevant, but also important to note: PLEASE don't overuse outline:none in your stylesheets, as it's really important for accessibility reasons. http://outlinenone.com/ –  Dec 28 '12 at 02:15

2 Answers2

18

In 2018 I'd use

html, body { 
  margin: 0;
  height: 100%;
}
canvas {
  width: 100%;
  height: 100%;
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  z-index: -9999;
}

Here's why:

I used to recommend canvas { width: 100vw; height: 100vh; ...} but sadly mobile browsers broke vh so it's useless and will apparently be useless forever. See this blog post.

display: block; fixes some issues with scrollbars on certain browsers. Some pages use html, body { overflow: none; } but again that doesn't make sense if your page ends up needing to be taller than the screen/window.

position: fixed; makes the canvas position relative to the top of window so it won't scroll with the page. If you use position: absolute then the canvas will scroll off the top if the page is taller than the screen/window. For example this page.

top: 0; left 0; puts it at the top left. Without that it would default to it's default position which is inside the body's margins. Often this is solved by setting body { margin: 0; } but generally that means you end up needing some other container to add a margin back in otherwise your normal content gets positioned at the edge of the window.

z-index: -9999; is there to try to force it further back than anything else just in case the page itself is using some negative values for z-index

Here's an example as a snippet

var ctx = document.querySelector("canvas").getContext("2d");

function resize(canvas) {
  var width = canvas.clientWidth;
  var height = canvas.clientHeight;
  if (width != canvas.width || height != canvas.height) {
    canvas.width = width;
    canvas.height = height;
  }
}

function render(time) {
  time *= 0.001;
  resize(ctx.canvas);
  ctx.save();
  var w = ctx.canvas.width;
  var h = ctx.canvas.height;
  var hw = w / 2;
  var hh = h / 2;
  ctx.clearRect(0, 0, w, h);
  ctx.strokeStyle = "red";
  ctx.translate(hw, hh);
  ctx.rotate(time * 0.1);
  for (var ii = 0; ii < 100; ++ii) {
    ctx.rotate(Math.sin(time * 0.1) * 0.2);
    ctx.strokeRect(-hw, -hh, w, h);
    ctx.scale(0.9, 0.9);
  }
  ctx.restore();

  requestAnimationFrame(render);
}
requestAnimationFrame(render);
html, body {
  margin: 0;
  height: 100%;
}
canvas {
  width: 100%;
  height: 100%;
  display: absolute;
  position: fixed;
  top: 0;
  left: 0;
  z-index: -9999;
}
<canvas></canvas>
<pre>
  some content that is in front of the canvas
  
  Let's
  
  try
  
  to
  
  make
  
  sure
  
  it's 
  
  long 
  
  enough
  
  that 
  
  we 
  
  can
  
  scroll
  
  down
  
  the 
  
  page
  
  so 
  
  we 
  
  can 
  
  see 
  
  that 
  
  position: fixed;
  
  is
  
  a
  
  better
  
  choice
  
  than
  
  position: absolute;
</pre>

And here's an example outside SO so you can view it easier full size.

iframes work as well

Note that there's the issue that if your canvas animation is interactive the elements in front of the canvas will eat the mouse/touch events. There's no easy solution I know of for that. You can mark everything but that canvas/iframe as pointer-events: none and mark the canvas/iframe as pointer-events: auto but then you run into the issue that no text on your page can be selected and no links can be clicked. You could then say set <a> tags to have pointer-events: auto so links work but I'm sure there will be issues here and there depending on what info is on your page (trying to copy an email address, or a location address, etc...)

gman
  • 100,619
  • 31
  • 269
  • 393
  • thank you.. its really interesting and learnt a lot.. trying this out with angularjs – Gour Gopal Aug 01 '18 at 15:03
  • Modern browsers try their best to run your code anyway but using a script tag after closing the HTML body is not valid. Anyone following this example should consider putting it on the last line of the body. Great examples for the CSS either way! – Jabokoe Sep 27 '19 at 17:12
  • Can you point to some official documentation that putting a script tag after the body as invalid? Google's own style guide says otherwise. – gman Sep 28 '19 at 00:14
  • Its against the W3C rec. Maybe https://stackoverflow.com/questions/3037725/is-it-wrong-to-place-the-script-tag-after-the-body-tag answers it better than I do. It also adresses that various places of Google documentation at certain points in time indeed put certain tags out of the body (but that some of those places no longer do so). It also mentions IE10+ would refuse to process these tags so that is something to test, even if it is only IE. Non-chrome mobile browsers might make more of a mess if they stick to W3C instead of current use? – Jabokoe Sep 28 '19 at 17:57
  • [It works fine across all browsers](http://greggman.github.io/doodles/test/scripts/). I prefer proof to superstition. – gman Sep 28 '19 at 18:15
14
canvas {
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
    z-index:-1;
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Muhammad Talha Akbar
  • 9,952
  • 6
  • 38
  • 62
  • well, buddy search for more and learn what all the props in the code i provided do :) This will help in creating your own code onwards! +1 for my code :) – Muhammad Talha Akbar Dec 26 '12 at 16:41
  • 1
    Yeah I'm starting to use HTML/CSS so its just a steep learning curve right now. Cheers for the tip. – geotheory Dec 26 '12 at 16:47