我的简单布局包含<header>
,内容<div>
和<footer>
,使用flexbox包裹在<main>
内。目的是当视口调整大小而页眉/页脚保持静止时,中间的画布增大/缩小,3个组件组合总是填充100%的视口空间而不显示滚动条。
当视口调整大小时(由于flex),内容<div>
会自动调整大小,但内部画布需要显式重新标注尺寸。
我在窗口的resize
事件中使用Javascript执行此操作,方法是通过<div>
请求内容getBoundingClientRect()
的新维度。
当增加窗口的高度时,这非常有效,但在收缩时拒绝工作。 getBoundingClientRect()
函数似乎永远不会为height
返回较小的值。
由于某种原因,水平调整大小会导致返回的height
显着增加。这令人难以置信的混乱。
我无法确定这是否是我使用flexbox,使用画布或使用getBoundingClientRect()
的问题。
以下是fiddle showing the problem,以下是相关的代码:
HTML:
<main>
<header>
<h1>This is my header</h1>
</header>
<div id="content">
<canvas id="canvas"></canvas>
</div>
<footer>
<span>Simple footer text</span>
</footer>
</main>
CSS:
main {
/* Main page container with a standard column layout of header -> content -> footer */
display: flex;
flex-direction: column;
/* Ensure our main container is always 100% height */
min-height: 100vh;
}
canvas {
display: block; /* Avoiding unexplainable weird behaviour */
}
#content {
flex: 1; /* Stretch the content div to fill the <main> */
overflow-y: auto;
}
使用Javascript:
var contentDiv = document.getElementById('content');
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
var pattern;
// Load up an image and create a pattern
img.onload = function() {
pattern = ctx.createPattern(img, 'repeat');
resize();
draw();
};
img.src = 'http://www.html5canvastutorials.com/demos/assets/wood-pattern.png';
// Resizes the <canvas> to match its parent, which has been sized by flex
function resize () {
// Here is the problem. INCREASING the height of the flexbox works
// perfectly. The canvas is resized appropriately. However, DECREASING
// it does nothing. Even though the contentDiv is sized by flexbox,
// its getBoundingClientRect() doesn't return a smaller height when
// shrinking it.
var boundingRect = contentDiv.getBoundingClientRect();
canvas.height = boundingRect.height;
canvas.width = boundingRect.width;
}
function draw () {
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = pattern;
ctx.fill();
}
window.addEventListener('resize', function () {
resize();
draw();
});
答案 0 :(得分:1)
那是因为你正在使用
min-height: 100vh;
由于你只施加了一个最小值,当你减小窗口高度时,画布不会神奇地缩小,因为约束已经存在。
相反,你应该使用
height: 100vh;
var contentDiv = document.getElementById('content');
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
var pattern;
// Load up an image and create a pattern
img.onload = function() {
pattern = ctx.createPattern(img, 'repeat');
resize();
draw();
};
img.src = 'http://www.html5canvastutorials.com/demos/assets/wood-pattern.png';
// Resizes the <canvas> to match its parent, which has been sized by flex
function resize () {
// Here is the problem. INCREASING the height of the flexbox works perfectly. The canvas is resized appropriately. However, DECREASING it does nothing. Even though the contentDiv is sized by flexbox, its getBoundingClientRect() doesn't return a smaller height when shrinking it.
var boundingRect = contentDiv.getBoundingClientRect();
canvas.height = boundingRect.height;
canvas.width = boundingRect.width;
}
function draw () {
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = pattern;
ctx.fill();
ctx.font = "14pt Verdana";
ctx.fillStyle = "lime";
ctx.fillText('Resize the window vertically.', 40, 40);
ctx.fillText('Watch the canvas increase in', 40, 70);
ctx.fillText('height but NOT decrease!', 40, 100);
}
window.addEventListener('resize', function () {
resize();
draw();
});
&#13;
html, body {
margin: 0;
padding: 0;
box-sizing: border-box;
}
header > h1 {
margin: 0;
}
header, footer {
background-color: #CCC;
}
main {
/* Main page container with a standard column layout of header -> content -> footer */
display: flex;
flex-direction: column;
/* Ensure our main container is always 100% height */
height: 100vh;
}
canvas {
display: block; /* Avoiding unexplainable weird behaviour */
}
#content {
flex: 1; /* Stretch the content div to fill the <main> */
overflow-y: auto;
}
&#13;
<main>
<header>
<h1>This is my header</h1>
</header>
<div id="content">
<canvas id="canvas"></canvas>
</div>
<footer>
<span>Simple footer text</span>
</footer>
</main>
&#13;