skip to Main Content

I have a game website where there is a header, a chessboard, and footer. I need to fit all three within the view port. The chessboard should shrink to make this happen.

The shrinking is what I’m having a problem with. I have been able to get width responsiveness, but not to a restrictive height.

The chessboard should remain square and take up unused space or shrink to prevent overflow.

I am doing something along the lines of the following, but the chessboard ends up overflowing the height of the parent.

.parent {
  height: 100vh;
  background-color: grey;
  display: flex;
  flex-direction: column;
}

.header {
  height: 10px;
  background-color: blue;
}

.child {
  background-color: red;
  flex: 1 1 auto;
}

.chessboard {
  width: 100%;
  max-height: 100%;
  aspect-ratio: 1/1;
  background-color: purple;
  margin: auto;
}

.footer {
  height: 10px;
  background-color: green;
}
<div class="parent">
  <div class="header">
  </div>
  <div class="child">
    <div class="chessboard">
    </div>
  </div>
  <div class="footer">
  </div>
</div>

Any help is appreciated.

3

Answers


  1. You have aspect-ratio that say to the chessboard to have the same height as width, so if your width is 3000px your height will be the same. You have options

    1. remove the aspect ratio
    2. with my example, remove the child wrapper element
    3. set a max-height to the chessboard
    *,
    *::before,
    *::after {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    .parent {
      height: 100vh;
      background-color: grey;
      display: flex;
      flex-direction: column;
    }
    
    .header {
      flex-shrink: 0;
      height: 10px;
      background-color: blue;
    }
    
    .child {
      flex-grow: 1;
      background-color: lightcoral;
    }
    
    .chessboard {
      height: 100%;
      max-height: 100%;
      background-color: purple;
      margin: auto;
    }
    
    .footer {
      flex-shrink: 0;
      height: 10px;
      background-color: green;
    }
    <div class="parent">
      <header class="header">
      </header>
    
      <div class="child">
        <div class="chessboard">
          main
        </div>
      </div>
    
      <footer class="footer">
      </footer>
    </div>
    Login or Signup to reply.
  2. I would just use a grid with the board in the middle.
    I gave the "child" a different color just to show it was there. Notice how the board stays inside of that but the markup forces us to add an aspect ratio to it also.

    EDIT: to let the padding to the heavy lifting here. A lot of credit to this idea here: https://css-tricks.com/aspect-ratios-grid-items/#aa-scenario-1-just-the-element-inside-needs-to-have-an-aspect-ratio

    body {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-size: 16px;
    }
    
    .parent {
      background-color: grey;
    }
    
    .grid {
      display: grid;
      grid-template-columns: 5% 1fr 5%;
      /* calc middle row based on other two */
      grid-template-rows: 0.625em calc(100vh - 1.35em) 0.625em;
    }
    
    .grid>* {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr;
      place-items: start;
    }
    
    .grid>[style^='--aspect-ratio']::before {
      content: "";
      display: inline-block;
      width: 1px;
      height: 0;
      padding-bottom: calc(100% / (var(--aspect-ratio)));
    }
    
    .header,
    .footer {
      grid-column: span 3;
    }
    
    .header {
      grid-row: 1;
      background-color: #0000FF;
    }
    
    .footer {
      grid-row: 3;
      background-color: #008000;
    }
    
    .child {
      grid-column: 2;
      grid-row: 2;
      background-color: #E6E6FA;
      display: grid;
      place-items: center;
      /* just to show the board stays inside it */
      padding-top: 0.25em;
    }
    
    .chessboard {
      aspect-ratio: 1 / 1;
      background-color: #800080;
      height: 100%
    }
    <div class="parent grid">
      <div class="header"></div>
      <div class="child" style="--aspect-ratio: 1/1;">
        <div class="chessboard"></div>
      </div>
      <div class="footer"></div>
    </div>
    Login or Signup to reply.
  3. The final answer depends on some clarifications on your part. I asked you in a comment to the question. But I will give a universal answer.

    I will briefly explain what is done in the example below.
    I created a .chessboard-wrapper that has a <canvas> in it. <canvas> scales as you need and has aspect-ratio: 1;.
    The .chessboard itself has position: absolute; and will take the dimensions of the father.

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    .parent {
      height: 100vh;
      background-color: grey;
      display: flex;
      flex-direction: column;
    }
    
    .header {
      height: 10px;
      background-color: blue;
      flex: none;
    }
    
    .child {
      background-color: red;
      flex: auto;
      min-height: 0;
      display: flex;
      flex-direction: column;
    }
    
    .chessboard-wrapper {
      position: relative;
      min-height: 0;
      margin: auto;
      aspect-ratio: 1;
    }
    
    .chessboard-wrapper > canvas {
      max-width: 100%;
      max-height: 100%;
    }
    
    .chessboard {
      position: absolute;
      inset: 0;
      background-color: purple;
    }
    
    .footer {
      height: 10px;
      background-color: green;
      flex: none;
    }
    <div class="parent">
      <div class="header"></div>
      <div class="child">
        <div class="chessboard-wrapper">
          <canvas width="1000000" height="1000000"></canvas>
          <div class="chessboard"></div>
        </div>
      </div>
      <div class="footer"></div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search