Search code examples
htmlcsscss-grid

How can I get grid items to fit/share the screen size dynamically?


I am currently building a game and want to create a split screen from the current version I have (which runs on a canvas) and stumbled into .

How I can get the grid to autosize elements inside it to equally match the size of the current viewport / page?

  • uf there is only one, then it should be the size of the page
  • if there are two, then it should be half the width and be side by side
  • third should start the second row and be half height and full width
  • four should be 1/4 all around.

then the trend continues for the rest.

If you are familiar with split screen games you might know the layout I am talking about.

The code below works perfectly with 4 screens; I do not know how this would be achieved with 1-2-3...-5-6-7, etc.

.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr;
  padding-left: 0;
  padding-right: 0;
  margin-left: auto;
  margin-right: auto;
}

.wrapper canvas {
  width: 100%;
}
<div id="wrapper" class="wrapper">
  <canvas id="canvas" width="3840" height="2160"></canvas>
</div>

The question has been answered using a flexbox instead, however, it would be nice to see the grid perform this task as well.


Solution

  • You can do it easily with Flexbox:

    body {display: flex; flex-wrap: wrap}
    
    .flex {
      display: flex; /* displays flex-items (children) inline */
      flex-wrap: wrap; /* enables them to wrap (default: nowrap) */
      /* 16:9 ratio */
      width: 160px;
      height: 90px;
      margin: 5px;
    }
    
    .flex > div {
      flex-grow: 1; /* enabled (default: 0); can grow/expand beyond 50% of the parent's width */
      flex-basis: 50%; /* initial width set to 50% because none of the items will be less than that, no matter how many of them */
      border: 1px solid; /* just to see the result better */
      box-sizing: border-box; /* recommended because of the border; otherwise you'd need to use the CSS calc() function: "flex-basis: calc(50% - 2px);" -2px because of the left and right border, which is 1px each; same applies for margins, if you're going to use them, then you also need to use the calc(), e.g.: calc(x% - twice the defined margin) */
      background: #eff0f1;
    }
    <div class="flex">
      <div>1</div>
    </div>
    
    <div class="flex">
      <div>1</div>
      <div>2</div>
    </div>
    
    <div class="flex">
      <div>1</div>
      <div>2</div>
      <div>3</div>
    </div>
    
    <div class="flex">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
    </div>
    
    <div class="flex">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>5</div>
    </div>
    
    <div class="flex">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>5</div>
      <div>6</div>
    </div>