添加horizontalFlexContainer后,verticalFlexContainer为何无法随浏览器宽度缩小?
问题描述
原本运行正常的网页,在浏览器窗口宽度缩小时,通过ResizeObserver可以调整带兔子棋盘的canvas元素尺寸,保持1:1宽高比。
但在所有元素外层添加horizontalFlexContainer容器(用于左侧放置带4个选项的灰色菜单)后,出现问题:浏览器宽度缩小时,verticalFlexContainer拒绝缩小,导致页面出现横向滚动。
问题代码
JavaScript
const parentElement = document.getElementById("parent"); const childElement = document.getElementById("child"); const app = new PIXI.Application({ backgroundColor: 0xccffcc, width: 800, height: 800, view: childElement, }); const resizeObserver = new ResizeObserver((entries) => { for (let entry of entries) { const { width, height } = entry.contentRect; const minDimension = Math.min(width, height); // 保持子元素1:1的宽高比 childElement.style.width = `${minDimension}px`; childElement.style.height = `${minDimension}px`; } }); resizeObserver.observe(parentElement); const background = new PIXI.Graphics(); for (let i = 0; i < 8; i++) { for (let j = 0; j < 8; j++) { if ((i + j) % 2 == 0) { background.beginFill(0xccccff); background.drawRect(i * 100, j * 100, 100, 100); background.endFill(); } } } app.stage.addChild(background); const texture = PIXI.Texture.from("https://pixijs.com/assets/bunny.png"); const bunny = new PIXI.Sprite(texture); bunny.anchor.set(0.5); bunny.x = 50; bunny.y = 50; bunny.width = 100; bunny.height = 100; app.stage.addChild(bunny);
CSS
html, body, h3, ul { margin: 0; padding: 0; text-align: center; overflow: hidden; } nav a.active { color: red; } div.horizontalFlexContainer { display: flex; justify-content: space-between; align-items: stretch; } div.verticalFlexContainer { display: flex; flex-direction: column; justify-content: space-between; align-items: stretch; height: 100vh; } /* 父容器仅包含canvas元素,canvas监听父容器尺寸 */ div.parent { border: 4px solid red; flex: 1; /* 居中唯一子元素canvas */ display: flex; align-items: center; justify-content: center; /* 防止canvas子元素破坏布局 */ overflow: hidden; } canvas.child { background-color: yellow; border: 4px green dotted; /* 边框绘制在canvas内部 */ box-sizing: border-box; } div.hint, div.status { background: lightblue; font-style: italic; text-align: center; }
HTML
<script src="//cdn.jsdelivr.net/npm/pixi.js-legacy@7/dist/pixi-legacy.min.js"></script> <div class="horizontalFlexContainer"> <div style="background: lightgrey"> <h3>Select a game!</h3> <nav> <ul> <li>Game 1</li> <li>Game 2</li> <li>Game 3</li> <li>Game 4</li> </ul> </nav> </div> <div style="flex-grow: 1"> <div class="verticalFlexContainer"> <div class="status">Game #1 Score1:Score2</div> <div class="parent" id="parent"> <canvas class="child" id="child"></canvas> </div> <div class="hint">A game hint to do this and that...</div> </div> </div> </div>
原因分析
问题根源在flex布局的默认行为:
- flex项默认带有
min-width: auto属性,这会强制元素宽度不小于其内容的最小宽度。当窗口缩小时,右侧的verticalFlexContainer及其父容器受此限制,无法被压缩到小于canvas初始宽度(800px),导致整体页面宽度溢出视口,出现横向滚动。 - 外层
horizontalFlexContainer未设置宽度为100%,无法占满整个视口宽度,进一步放大了布局问题。
解决方案
通过修改布局属性,打破flex的默认最小宽度限制,允许容器正常收缩:
- 让
horizontalFlexContainer占满视口宽度:
div.horizontalFlexContainer { display: flex; justify-content: space-between; align-items: stretch; width: 100%; /* 添加此行 */ }
- 给包含
verticalFlexContainer的div添加收缩权限和最小宽度限制:
<div style="flex-grow: 1; flex-shrink: 1; min-width: 0">
- 给
verticalFlexContainer添加最小宽度限制:
div.verticalFlexContainer { display: flex; flex-direction: column; justify-content: space-between; align-items: stretch; height: 100vh; min-width: 0; /* 添加此行 */ }
修改完成后,浏览器窗口缩小时右侧容器会正常压缩,ResizeObserver也能继续工作,保持canvas的1:1宽高比。
内容的提问来源于stack exchange,提问作者Alexander Farber
相关产品推荐
相关产品推荐

