skip to Main Content

I am trying to create a simple board game UI using css grid. I assumed this would be the perfect tool for the purpose however I am not able to achieve the desired results, namely:

1 – The tiles will auto size so that they fill the parent
2 – The tiles will maintain a 1:1 aspect ratio
3 – The page content should NOT expand outside of the visible browser window.

Unfortunately every solution I’ve tried so far either causes overflow, or the page extending horizontally when the height of each tile gets too big (or vertically when the width of each tile gets too big).

:root
        {
            --col_and_row_count: 10;
        }

        .main 
        {
            display: grid;
            grid-template-rows: 60px 1fr 60px; 
            gap: 1em;
            height: 100vh;
        }

        .wrapper 
        {
            display: grid;
            grid-template-columns: 200px 1fr;
        }

        .board 
        {
            display: flex;
            align-items: center;
        }

        .tiles 
        {
            margin: auto;
            display: grid;
            grid-template-columns: repeat(var(--col_and_row_count), 1fr);
            gap: 12px;
            aspect-ratio: 1; 
        }

        .tiles > div 
        {
            background: green;
               
        }
 <div class="main">

        <div>
            Some heading text goes here
        </div>

        <div class="wrapper">

            <div>
                The side bar goes here
            </div>


            <div class="board">

                <div class="tiles">
                    <div data-tile-index="0"></div>
                    <div data-tile-index="1"></div>
                    <div data-tile-index="2"></div>
                    <div data-tile-index="3"></div>
                    <div data-tile-index="4"></div>
                    <div data-tile-index="5"></div>
                    <div data-tile-index="6"></div>
                    <div data-tile-index="7"></div>
                    <div data-tile-index="8"></div>
                    <div data-tile-index="9"></div>
                    <div data-tile-index="10"></div>
                    <div data-tile-index="11"></div>
                    <div data-tile-index="12"></div>
                    <div data-tile-index="13"></div>
                    <div data-tile-index="14"></div>
                    <div data-tile-index="15"></div>
                    <div data-tile-index="16"></div>
                    <div data-tile-index="17"></div>
                    <div data-tile-index="18"></div>
                    <div data-tile-index="19"></div>
                    <div data-tile-index="20"></div>
                    <div data-tile-index="21"></div>
                    <div data-tile-index="22"></div>
                    <div data-tile-index="23"></div>
                    <div data-tile-index="24"></div>
                    <div data-tile-index="25"></div>
                    <div data-tile-index="26"></div>
                    <div data-tile-index="27"></div>
                    <div data-tile-index="28"></div>
                    <div data-tile-index="29"></div>
                    <div data-tile-index="30"></div>
                    <div data-tile-index="31"></div>
                    <div data-tile-index="32"></div>
                    <div data-tile-index="33"></div>
                    <div data-tile-index="34"></div>
                    <div data-tile-index="35"></div>
                    <div data-tile-index="36"></div>
                    <div data-tile-index="37"></div>
                    <div data-tile-index="38"></div>
                    <div data-tile-index="39"></div>
                    <div data-tile-index="40"></div>
                    <div data-tile-index="41"></div>
                    <div data-tile-index="42"></div>
                    <div data-tile-index="43"></div>
                    <div data-tile-index="44"></div>
                    <div data-tile-index="45"></div>
                    <div data-tile-index="46"></div>
                    <div data-tile-index="47"></div>
                    <div data-tile-index="48"></div>
                    <div data-tile-index="49"></div>
                    <div data-tile-index="50"></div>
                    <div data-tile-index="51"></div>
                    <div data-tile-index="52"></div>
                    <div data-tile-index="53"></div>
                    <div data-tile-index="54"></div>
                    <div data-tile-index="55"></div>
                    <div data-tile-index="56"></div>
                    <div data-tile-index="57"></div>
                    <div data-tile-index="58"></div>
                    <div data-tile-index="59"></div>
                    <div data-tile-index="60"></div>
                    <div data-tile-index="61"></div>
                    <div data-tile-index="62"></div>
                    <div data-tile-index="63"></div>
                    <div data-tile-index="64"></div>
                    <div data-tile-index="65"></div>
                    <div data-tile-index="66"></div>
                    <div data-tile-index="67"></div>
                    <div data-tile-index="68"></div>
                    <div data-tile-index="69"></div>
                    <div data-tile-index="70"></div>
                    <div data-tile-index="71"></div>
                    <div data-tile-index="72"></div>
                    <div data-tile-index="73"></div>
                    <div data-tile-index="74"></div>
                    <div data-tile-index="75"></div>
                    <div data-tile-index="76"></div>
                    <div data-tile-index="77"></div>
                    <div data-tile-index="78"></div>
                    <div data-tile-index="79"></div>
                    <div data-tile-index="80"></div>
                    <div data-tile-index="81"></div>
                    <div data-tile-index="82"></div>
                    <div data-tile-index="83"></div>
                    <div data-tile-index="84"></div>
                    <div data-tile-index="85"></div>
                    <div data-tile-index="86"></div>
                    <div data-tile-index="87"></div>
                    <div data-tile-index="88"></div>
                    <div data-tile-index="89"></div>
                    <div data-tile-index="90"></div>
                    <div data-tile-index="91"></div>
                    <div data-tile-index="92"></div>
                    <div data-tile-index="93"></div>
                    <div data-tile-index="94"></div>
                    <div data-tile-index="95"></div>
                    <div data-tile-index="96"></div>
                    <div data-tile-index="97"></div>
                    <div data-tile-index="98"></div>
                    <div data-tile-index="99"></div>
                </div>



            </div>

        </div>



        <div>
            This is the footer
        </div>




    </div>

2

Answers


  1. You should use auto instead of 1fr in repeat function to avoid overflow.

    grid-template-columns: repeat(var(--col_and_row_count), 1fr); ❌

    to

    grid-template-columns: repeat(var(--col_and_row_count), auto); ✅

    Check out this

    :root
    {
        --col_and_row_count: 10;
    }
    
    .main 
    {
        display: grid;
        grid-template-rows: 60px 1fr 60px; 
        gap: 1em;
        height: 100vh;
    }
    
    .wrapper 
    {
        display: grid;
        grid-template-columns: 200px 1fr;
    }
    
    .board 
    {
        display: flex;
        align-items: center;
    }
    
    .tiles 
    {
          display: grid;
          grid-template-columns: repeat(var(--col_and_row_count), auto);
          width: 100%;
          height: 100%;
          grid-gap: 5px;
          grid-template-rows: auto;
          grid-auto-flow: row;
          align-items: stretch
    }
    
    .tiles > div 
    {
        background: green;
        aspect-ratio: 1;
    }
    <div class="main">
    
        <div>
            Some heading text goes here
        </div>
    
        <div class="wrapper">
    
            <div>
                The side bar goes here
            </div>
    
            <div class="board">
    
                <div class="tiles">
                    <div data-tile-index="0"></div>
                    <div data-tile-index="1"></div>
                    <div data-tile-index="2"></div>
                    <div data-tile-index="3"></div>
                    <div data-tile-index="4"></div>
                    <div data-tile-index="5"></div>
                    <div data-tile-index="6"></div>
                    <div data-tile-index="7"></div>
                    <div data-tile-index="8"></div>
                    <div data-tile-index="9"></div>
                    <div data-tile-index="10"></div>
                    <div data-tile-index="11"></div>
                    <div data-tile-index="12"></div>
                    <div data-tile-index="13"></div>
                    <div data-tile-index="14"></div>
                    <div data-tile-index="15"></div>
                    <div data-tile-index="16"></div>
                    <div data-tile-index="17"></div>
                    <div data-tile-index="18"></div>
                    <div data-tile-index="19"></div>
                    <div data-tile-index="20"></div>
                    <div data-tile-index="21"></div>
                    <div data-tile-index="22"></div>
                    <div data-tile-index="23"></div>
                    <div data-tile-index="24"></div>
                    <div data-tile-index="25"></div>
                    <div data-tile-index="26"></div>
                    <div data-tile-index="27"></div>
                    <div data-tile-index="28"></div>
                    <div data-tile-index="29"></div>
                    <div data-tile-index="30"></div>
                    <div data-tile-index="31"></div>
                    <div data-tile-index="32"></div>
                    <div data-tile-index="33"></div>
                    <div data-tile-index="34"></div>
                    <div data-tile-index="35"></div>
                    <div data-tile-index="36"></div>
                    <div data-tile-index="37"></div>
                    <div data-tile-index="38"></div>
                    <div data-tile-index="39"></div>
                    <div data-tile-index="40"></div>
                    <div data-tile-index="41"></div>
                    <div data-tile-index="42"></div>
                    <div data-tile-index="43"></div>
                    <div data-tile-index="44"></div>
                    <div data-tile-index="45"></div>
                    <div data-tile-index="46"></div>
                    <div data-tile-index="47"></div>
                    <div data-tile-index="48"></div>
                    <div data-tile-index="49"></div>
                    <div data-tile-index="50"></div>
                    <div data-tile-index="51"></div>
                    <div data-tile-index="52"></div>
                    <div data-tile-index="53"></div>
                    <div data-tile-index="54"></div>
                    <div data-tile-index="55"></div>
                    <div data-tile-index="56"></div>
                    <div data-tile-index="57"></div>
                    <div data-tile-index="58"></div>
                    <div data-tile-index="59"></div>
                    <div data-tile-index="60"></div>
                    <div data-tile-index="61"></div>
                    <div data-tile-index="62"></div>
                    <div data-tile-index="63"></div>
                    <div data-tile-index="64"></div>
                    <div data-tile-index="65"></div>
                    <div data-tile-index="66"></div>
                    <div data-tile-index="67"></div>
                    <div data-tile-index="68"></div>
                    <div data-tile-index="69"></div>
                    <div data-tile-index="70"></div>
                    <div data-tile-index="71"></div>
                    <div data-tile-index="72"></div>
                    <div data-tile-index="73"></div>
                    <div data-tile-index="74"></div>
                    <div data-tile-index="75"></div>
                    <div data-tile-index="76"></div>
                    <div data-tile-index="77"></div>
                    <div data-tile-index="78"></div>
                    <div data-tile-index="79"></div>
                    <div data-tile-index="80"></div>
                    <div data-tile-index="81"></div>
                    <div data-tile-index="82"></div>
                    <div data-tile-index="83"></div>
                    <div data-tile-index="84"></div>
                    <div data-tile-index="85"></div>
                    <div data-tile-index="86"></div>
                    <div data-tile-index="87"></div>
                    <div data-tile-index="88"></div>
                    <div data-tile-index="89"></div>
                    <div data-tile-index="90"></div>
                    <div data-tile-index="91"></div>
                    <div data-tile-index="92"></div>
                    <div data-tile-index="93"></div>
                    <div data-tile-index="94"></div>
                    <div data-tile-index="95"></div>
                    <div data-tile-index="96"></div>
                    <div data-tile-index="97"></div>
                    <div data-tile-index="98"></div>
                    <div data-tile-index="99"></div>
                </div>
    
            </div>
    
        </div>
    
        <div>
            This is the footer
        </div>
    
    </div>
    Login or Signup to reply.
  2. I would advise you to draw the game on the <canvas> element.
    But, if you still want to have html grid cells, then you can also use the <canvas> element to preserve the aspect ratio. For example, like this:

    :root {
      --col_and_row_count: 10;
      --header-height: auto;
      --footer-height: auto;
      --game-gap: 4px;
    }
    
    .main {
      display: grid;
      grid-template-rows: var(--header-height) 1fr var(--footer-height); 
      gap: var(--game-gap);
      position: fixed;
      inset: 0;
      padding: 4px;
    }
    
    .wrapper {
      display: grid;
      grid-template-columns: 200px 1fr;
      overflow: hidden;
    }
    
    .board {
      overflow: hidden;
      display: flex;
      flex-direction: column;
    }
    
    .tiles-wrapp {
      position: relative;
      overflow: hidden;
      max-height: 100%;
      margin: 0 auto auto 0;
      aspect-ratio: 1;
    }
    
    .board canvas {
      max-width: 100%;
      max-height: 100%;
    }
    
    .tiles {
      position: absolute;
      inset: 0;
      display: grid;
      grid-template-columns: repeat(var(--col_and_row_count), 1fr);
      gap: 2px;
      aspect-ratio: 1; 
    }
    
    .tiles > div {
      background: green;
    }
    <div class="main">
      <div>Some heading text goes here</div>
      <div class="wrapper">
        <div>The side bar goes here</div>
        <div class="board">
          <div class="tiles-wrapp">
            <canvas width="100000" height="100000"></canvas>
            <div class="tiles">
              <div data-tile-index="0"></div>
              <div data-tile-index="1"></div>
              <div data-tile-index="2"></div>
              <div data-tile-index="3"></div>
              <div data-tile-index="4"></div>
              <div data-tile-index="5"></div>
              <div data-tile-index="6"></div>
              <div data-tile-index="7"></div>
              <div data-tile-index="8"></div>
              <div data-tile-index="9"></div>
              <div data-tile-index="10"></div>
              <div data-tile-index="11"></div>
              <div data-tile-index="12"></div>
              <div data-tile-index="13"></div>
              <div data-tile-index="14"></div>
              <div data-tile-index="15"></div>
              <div data-tile-index="16"></div>
              <div data-tile-index="17"></div>
              <div data-tile-index="18"></div>
              <div data-tile-index="19"></div>
              <div data-tile-index="20"></div>
              <div data-tile-index="21"></div>
              <div data-tile-index="22"></div>
              <div data-tile-index="23"></div>
              <div data-tile-index="24"></div>
              <div data-tile-index="25"></div>
              <div data-tile-index="26"></div>
              <div data-tile-index="27"></div>
              <div data-tile-index="28"></div>
              <div data-tile-index="29"></div>
              <div data-tile-index="30"></div>
              <div data-tile-index="31"></div>
              <div data-tile-index="32"></div>
              <div data-tile-index="33"></div>
              <div data-tile-index="34"></div>
              <div data-tile-index="35"></div>
              <div data-tile-index="36"></div>
              <div data-tile-index="37"></div>
              <div data-tile-index="38"></div>
              <div data-tile-index="39"></div>
              <div data-tile-index="40"></div>
              <div data-tile-index="41"></div>
              <div data-tile-index="42"></div>
              <div data-tile-index="43"></div>
              <div data-tile-index="44"></div>
              <div data-tile-index="45"></div>
              <div data-tile-index="46"></div>
              <div data-tile-index="47"></div>
              <div data-tile-index="48"></div>
              <div data-tile-index="49"></div>
              <div data-tile-index="50"></div>
              <div data-tile-index="51"></div>
              <div data-tile-index="52"></div>
              <div data-tile-index="53"></div>
              <div data-tile-index="54"></div>
              <div data-tile-index="55"></div>
              <div data-tile-index="56"></div>
              <div data-tile-index="57"></div>
              <div data-tile-index="58"></div>
              <div data-tile-index="59"></div>
              <div data-tile-index="60"></div>
              <div data-tile-index="61"></div>
              <div data-tile-index="62"></div>
              <div data-tile-index="63"></div>
              <div data-tile-index="64"></div>
              <div data-tile-index="65"></div>
              <div data-tile-index="66"></div>
              <div data-tile-index="67"></div>
              <div data-tile-index="68"></div>
              <div data-tile-index="69"></div>
              <div data-tile-index="70"></div>
              <div data-tile-index="71"></div>
              <div data-tile-index="72"></div>
              <div data-tile-index="73"></div>
              <div data-tile-index="74"></div>
              <div data-tile-index="75"></div>
              <div data-tile-index="76"></div>
              <div data-tile-index="77"></div>
              <div data-tile-index="78"></div>
              <div data-tile-index="79"></div>
              <div data-tile-index="80"></div>
              <div data-tile-index="81"></div>
              <div data-tile-index="82"></div>
              <div data-tile-index="83"></div>
              <div data-tile-index="84"></div>
              <div data-tile-index="85"></div>
              <div data-tile-index="86"></div>
              <div data-tile-index="87"></div>
              <div data-tile-index="88"></div>
              <div data-tile-index="89"></div>
              <div data-tile-index="90"></div>
              <div data-tile-index="91"></div>
              <div data-tile-index="92"></div>
              <div data-tile-index="93"></div>
              <div data-tile-index="94"></div>
              <div data-tile-index="95"></div>
              <div data-tile-index="96"></div>
              <div data-tile-index="97"></div>
              <div data-tile-index="98"></div>
              <div data-tile-index="99"></div>
            </div>
          </div>
        </div>
      </div>
      <div>This is the footer</div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search