I am trying to get a self-resizing canvas following the recipe here (end of section 4, under "What to do instead"). So I have a ResizeObserver
hooked up to watch for changes on my canvas element. The canvas element has 100% height and is inside of a container element which is itself a child of a flex
element. This exact set of circumstances seems to lead to a chain reaction in which the canvas's height continually increases over time.
The reason I want this is because I want the canvas to fill its container, hence the 100% height, but I don't want its actual rendered content to be stretched by the browser.
Here's a JSFiddle and here's a minimum example in code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body
{
display: flex;
}
main
{
max-height: 1000px; /* not necessary, for convenience */
}
canvas
{
height: 100%;
background-color: pink;
}
</style>
</head>
<body>
<main>
<canvas></canvas>
</main>
<script>
let canvas = document.querySelector("canvas");
let renderer = canvas.getContext("2d");
let resizeObserver = new ResizeObserver(render);
resizeObserver.observe(canvas);
function render()
{
renderer.canvas.height = renderer.canvas.clientHeight;
}
</script>
</body>
</html>
This is because your canvas has its display
set to inline-block
, it thus is affected by the line-height
value of the parent <main>
and will take more space in this parent than it's actual size.
To avoid that, either set the <main>
's line-height
to 0
,
let canvas = document.querySelector("canvas");
let renderer = canvas.getContext("2d");
let resizeObserver = new ResizeObserver(resize);
resizeObserver.observe(canvas, { box: "content-box"});
i = 0;
function resize()
{
canvas.height = canvas.clientHeight;
}
body
{
display: flex;
}
main
{
line-height: 0;
}
canvas
{
height: 100%;
background-color: pink;
}
<main>
<canvas></canvas>
</main>
Or set the <canvas>
display to block
.
let canvas = document.querySelector("canvas");
let renderer = canvas.getContext("2d");
let resizeObserver = new ResizeObserver(resize);
resizeObserver.observe(canvas, { box: "content-box"});
i = 0;
function resize()
{
canvas.height = canvas.clientHeight;
}
body
{
display: flex;
}
canvas
{
height: 100%;
background-color: pink;
display: block;
}
<main>
<canvas></canvas>
</main>