You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加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的默认最小宽度限制,允许容器正常收缩:

  1. 让horizontalFlexContainer占满视口宽度:
div.horizontalFlexContainer {
  display: flex;
  justify-content: space-between;
  align-items: stretch;
  width: 100%; /* 添加此行 */
}
  1. 给包含verticalFlexContainer的div添加收缩权限和最小宽度限制:
<div style="flex-grow: 1; flex-shrink: 1; min-width: 0">
  1. 给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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 21:47:12