cssflexboxaspect-ratiopixi.jsresize-observer

Why doesn't the flex child shrink in this simple test case webpage?


I had a webpage which was working perfectly and resized the child canvas element (the checkerboard with a bunny), while keeping its 1:1 aspect ratio with a help of ResizeObserver, when the browser window width decreased:

animated screenshot 1

Then I have added a "horizontalFlexContainer" div element around all the elements of that page, so that I could add a grey menu with 4 entries on the left side.

Unfortunately, this has resulted in the issue that the "verticalFlexContainer" refuses to shrink, when the browser width decreases:

animated screenshot 2

Here is my problematic keep-aspect-ratio.html using the main.css

Does anybody please have a recommendation, what is suddenly causing the "resistance" to shrink?

  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);

      // maintain the 1:1 aspect ratio of the child element
      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);
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;
}

/* the parent contains: just the canvas element, which observes the parent dimensions */
div.parent {
  border: 4px solid red;
  flex: 1;
  /* center the only child element: the canvas */
  display: flex;
  align-items: center;
  justify-content: center;
  /* prevent the canvas child disrupting the layout */
  overflow: hidden;
}

canvas.child {
  background-color: yellow;
  border: 4px green dotted;
  /* draw the border inside of the canvas element */
  box-sizing: border-box;
}

div.hint,
div.status {
  background: lightblue;
  font-style: italic;
  text-align: center;
}
<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>


Solution

  • #child { max-width: 100% }:

    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);
    
          // maintain the 1:1 aspect ratio of the child element
          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);
    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;
    }
    
    /* the parent contains: just the canvas element, which observes the parent dimensions */
    div.parent {
      border: 4px solid red;
      flex: 1;
      /* center the only child element: the canvas */
      display: flex;
      align-items: center;
      justify-content: center;
      /* prevent the canvas child disrupting the layout */
      overflow: hidden;
    }
    
    canvas.child {
      background-color: yellow;
      border: 4px green dotted;
      /* draw the border inside of the canvas element */
      box-sizing: border-box;
      max-width: 100%;
    }
    
    div.hint,
    div.status {
      background: lightblue;
      font-style: italic;
      text-align: center;
    }
    <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>