Search code examples
csscss-grid

CSS Grid: centering and overlapping difficulties


I'm trying to create a simple calculator using only HTML and CSS for the layout and, eventually, pure JavaScript for the functions.

I want the site/page to be responsive which is why I am using CSS Grid and no absolute units; % and fr instead of px...

The calculator itself should be a grid of centred squares with the text in the buttons centred both horizontally and vertically and all of the buttons should fit within the "calculator".

<html>
   <body>
      <div class="calc">
        <button id="bp">+&nbsp;/&nbsp;-</button>
        <button id="bc">C</button>
        <button id="bb">X</button>
         <button id="b7">7</button>
         <button id="b8">8</button>
         <button id="b9">9</button>
         <button id="b4">4</button>
         <button id="b5">5</button>
         <button id="b6">6</button>
         <button id="b1">1</button>
         <button id="b2">2</button>
         <button id="b3">3</button>
         <button id="bd">.</button>
         <button id="b0">0</button>
         <button id="be">=</button>
      </div>
   </body>
</html>

div.calc {
   max-width: 80%;
   margin: 1% auto;

   border: 2px solid #111111;
   border-radius: 5px;
   padding: 1%;

    display: grid;
   grid-template-columns: repeat(3, 1fr);
   grid-template-rows: repeat(5, 1fr);
   grid-gap: 2%;

    justify-items: center;
    align-items: center; 
}

div.calc > button {
   background-color: lightgrey;
   color: darkblue;

   border: 2px solid #111111;
   border-radius: 5px;

   font-size: 2em;
   cursor: pointer;

   vertical-align: center;
   text-align: center;

   width: 100%;
   height: 0;
   padding: 50%;
}

button#bp,
button#bd {
    background-color: blue;
    color: yellow;
}

button#bc {
    background-color: red;
    color: white;
}

button#bb {
    background-color: yellow;
    color: blue;
}

button#be {
    background-color: green;
    color: yellow;
}

Codepen

The calculator div does not appear to be high enough to hold the buttons and the bottom row of the grid therefore overlaps and bleeds outside of the calculator.

I tried playing around with the height of the calc div (height: 100% ...) but the last row always goes over...

I can't seem to get the text inside the button to centre properly; especially horizontally. The '+ / -' button is a good example. I've set the text-align as center and both the justify-items and align-items are center. I know those last two refer to the button items themselves within the grid. But I can't see where else to get the text to centre properly.

I'm hoping this is something outright simple and I've just been staring at the same code, over and over again, for oh too many hours.

If you would rather not correct my code and prefer to point me to any online examples or explanations which would help I will gladly do my homework.

Thanks!


Solution

  • The issue is the grid-gap:2%. It's working for horizontally because we can resolve the 2% based on the width but for the height it won't work since there is no height defined. Basically, the browser is first calculation the height without the gap, then the gap is addedd.

    You should consider px or another unit like vw/vh for this one. I have also changed the way you are centring the button. (Centering in CSS Grid)

    div.calc {
      max-width: 80%;
      margin: 1% auto;
      border: 2px solid #111111;
      border-radius: 5px;
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-template-rows: repeat(5, 1fr);
      
      grid-gap: 1vw;
      padding: 1vw; /*make the padding the same*/
    }
    
    div.calc>button {
      background-color: lightgrey;
      color: darkblue;
      border: 2px solid #111111;
      border-radius: 5px;
      font-size: 2em;
      cursor: pointer;
      /*to center*/
      display: flex;
      align-items: center;
      justify-content: center;
      /**/
    }
    /*keep the ratio*/
    div.calc>button:before {
      content: "";
      display: inline-block;
      padding-top: 100%;
    }
    /**/
    button#bp,
    button#bd {
      background-color: blue;
      color: yellow;
    }
    
    button#bc {
      background-color: red;
      color: white;
    }
    
    button#bb {
      background-color: yellow;
      color: blue;
    }
    
    button#be {
      background-color: green;
      color: yellow;
    }
    <div class="calc">
        <button id="bp">+&nbsp;/&nbsp;-</button>
        <button id="bc">C</button>
        <button id="bb">X</button>
        <button id="b7">7</button>
        <button id="b8">8</button>
        <button id="b9">9</button>
        <button id="b4">4</button>
        <button id="b5">5</button>
        <button id="b6">6</button>
        <button id="b1">1</button>
        <button id="b2">2</button>
        <button id="b3">3</button>
        <button id="bd">.</button>
        <button id="b0">0</button>
        <button id="be">=</button>
      </div>