0

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!

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Derek Erb
  • 131
  • 2
  • 10

2 Answers2

3

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>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Wow that was fast! That elegantly solved my problem while keeping everything responsive. Now I just need to do some more reading to fully grasp what you did there both with vw in the gap and padding as well as the use of flex inside of a grid and the ::before ratio code... Thanks! – Derek Erb Apr 18 '19 at 08:33
  • @DerekErb basically vw is a lenght that doesn't depend on the width or the height of the element so there won't be any issue as the browser can resolved it *easily*. For the flexbox use, it's one method among many (follow the first link to see all of them) and for the ratio here is a good link to better understand : https://stackoverflow.com/a/54928586/8620333 – Temani Afif Apr 18 '19 at 08:47
1

Alternative solution with flexbox method with three column button box. I hope this will be helpful for you.

* {
    box-sizing: border-box;
    position: relative;
}

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;  */
    display: flex;
    flex-wrap: wrap;
    width: 100%;
    margin: 0 auto;
}

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;
    height: 0;
    padding: 12%;
    flex-grow: 1;
    width: 31%;
    height: 31%;
    margin: 5px;
}

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>
Saravana
  • 3,389
  • 4
  • 21
  • 37