如何为子canvas元素保持1:1宽高比(Flex+ResizeObserver场景)
修复方案
问题根源是flex布局中,flex-grow:1的.parent元素默认min-height:auto,当内部canvas尺寸超出分配空间时,会撑开父元素,导致整个布局高度超过视口,挤掉底部的.hint。同时canvas的固定初始尺寸也会加剧这个问题。
以下是具体修复步骤:
1. 调整父容器CSS
给.parent添加以下样式,确保它严格遵守flex分配的空间,同时让canvas居中显示:
.parent { border: 4px solid red; flex-grow: 1; min-height: 0; /* 允许flex子元素高度小于内容高度,避免撑开布局 */ display: flex; justify-content: center; /* 水平居中canvas */ align-items: center; /* 垂直居中canvas */ overflow: hidden; /* 隐藏canvas超出父容器的部分 */ }
2. 重置canvas初始样式
去掉canvas的固定宽高,由ResizeObserver动态设置:
canvas { background-color: yellow; border: 4px green dotted; box-sizing: border-box; }
3. 保留ResizeObserver逻辑(可选但推荐)
原有的ResizeObserver逻辑可以保留,用来动态设置canvas的1:1尺寸,同时如果你的PixiJS需要根据实际尺寸调整渲染分辨率,可以在回调中添加对应的逻辑:
const parentElement = document.getElementById("parent"); const childElement = document.getElementById("child"); const resizeObserver = new ResizeObserver((entries) => { for (let entry of entries) { const { width, height } = entry.contentRect; const minDimension = Math.min(width, height); console.log(`parent: ${width} x ${height} -> child: ${minDimension} x ${minDimension}`); childElement.style.width = `${minDimension}px`; childElement.style.height = `${minDimension}px`; // 如果是PixiJS项目,这里可以添加: // renderer.resize(minDimension, minDimension); } }); resizeObserver.observe(parentElement);
修改后的完整代码
HTML
<div class="flexRoot"> <div class="status">Game #1 Score1:Score2</div> <div class="parent" id="parent"> <canvas id="child"></canvas> </div> <div class="hint">A game hint to do this and that...</div> </div>
CSS
html, body { margin: 0; padding: 0; overflow: hidden; } .flexRoot { display: flex; flex-direction: column; justify-content: space-between; align-items: stretch; width: 100%; height: 100vh; } .parent { border: 4px solid red; flex-grow: 1; min-height: 0; display: flex; justify-content: center; align-items: center; overflow: hidden; } canvas { background-color: yellow; border: 4px green dotted; box-sizing: border-box; } .hint, .status { background: lightblue; font-style: italic; text-align: center; flex-grow: 0; }
JavaScript
const parentElement = document.getElementById("parent"); const childElement = document.getElementById("child"); const resizeObserver = new ResizeObserver((entries) => { for (let entry of entries) { const { width, height } = entry.contentRect; const minDimension = Math.min(width, height); console.log(`parent: ${width} x ${height} -> child: ${minDimension} x ${minDimension}`); childElement.style.width = `${minDimension}px`; childElement.style.height = `${minDimension}px`; } }); resizeObserver.observe(parentElement);
内容的提问来源于stack exchange,提问作者Alexander Farber
相关产品推荐
相关产品推荐

