<header>
  <div id="title-cont">
    <h2>Calculator</h2>
  </div>
</header>
<main>
  <div id="main-cont">
    <div id="calc-cont">
      <div id="output">
        <h2 id="output-text">0</h2>
      </div>
      <div id="table-cont">
        <table>
          <tr>
            <td id="clear" class="btns" alt="clear">C</td>
            <td class="operator">÷</td>
            <td class="operator">-</td>
            <td id="backspace" alt="backspace" class="btns">
              <img src="https://img.icons8.com/ios-glyphs/90/ffffff/clear-symbol.png" alt="backspace" />
            </td>
          </tr>
          <tr>
            <td class="key">7</td>
            <td class="key">8</td>
            <td class="key">9</td>
            <td class="operator">×</td>
          </tr>
          <tr>
            <td class="key">4</td>
            <td class="key">5</td>
            <td class="key">6</td>
            <td class="operator">+</td>
          </tr>
          <tr>
            <td class="key">1</td>
            <td class="key">2</td>
            <td class="key">3</td>
            <td id="equals" rowspan="2">=</td>
          </tr>
          <tr>
            <td alt="feedback" class="btns">
              <a target="_blank" href="https://github.com/WhiteWolfDot/JS-Calculator/issues/new"><img src="https://img.icons8.com/ios/100/ffffff/hint.png" alt="feedback" />
              </a>
            </td>
            <td class="key">0</td>
            <td class="key">.</td>
          </tr>
        </table>
      </div>
    </div>
  </div>
</main>
<footer>
  <a target="_blank" href="https://github.com/WhiteWolfDot/JS-Calculator/issues/new">
    <h4>Report an issue</h4>
  </a>
  <h5>
    Made with ❤ by
    <a target="_blank" href="https://github.com/WhiteWolfDot">WhiteWolfDot</a>
  </h5>
</footer>
html,
body {
  width: 100%;
  height: 100%;
  background-color: #363636;
  margin: 0;
  overflow: hidden;
  font-size: 7px;
  position: relative;
}

::-webkit-scrollbar {
  height: 0.5rem;
  padding: 0.2rem;
}

::-webkit-scrollbar-track {
  background: #808080;
  border-radius: 3rem;
  padding: 0.2rem;
  box-shadow: inset 0 0 0.5rem rgba(0, 0, 0, 0.4);
}

::-webkit-scrollbar-thumb {
  background: #363636;
  outline: 1px solid #505050;
  border-radius: 3rem;
}

::-webkit-scrollbar-thumb:hover {
  background: #282828;
}

header {
  height: 3%;
  background-color: #282828;
  text-align: center;
  vertical-align: middle;
  padding: 1.5rem;
  box-shadow: 0rem 0.2rem 0.6rem 0 #282828;
}

#title-cont {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

#title-cont h2 {
  width: 38%;
  margin: 0;
  font-size: 2.5rem;
  color: #3d6d79;
  text-shadow: 0.1rem 0.2rem 0.7rem #101010;
}

/*main*/

main {
  width: 100%;
  height: 100%;
  position: relative;
  text-align: center;
}

#main-cont {
  width: 26rem;
  height: auto;
  background-color: #282828;
  padding: 1rem;
  position: absolute;
  top: 38%;
  left: 50%;
  margin-right: -50%;
  transform: translate(-50%, -50%);
  box-shadow: 0rem 0.5rem 0.6rem 0 black;
}

#calc-cont {
  width: 100%;
  position: relative;
  height: 100%;
}

#output {
  width: 100%;
  height: 6rem;
  background-color: #505050;
  box-shadow: 0.1rem 0.1rem 0.6rem 0 black inset;
  margin-bottom: 0.8rem;
}

#output-text {
  font-size: 5rem;
  height: 5.5rem;
  text-align: end;
  margin: 1rem;
  color: #bbbbbb;
  overflow-x: auto;
  overflow-y: hidden;
}

#table-cont {
  position: relative;
  height: auto;
  width: 100%;
}

table,
th,
td {
  border-radius: 1rem;
}

table {
  width: 100%;
  text-align: center;
  height: auto;
  margin: 0;
  font-family: "Supermercado One";
  border-spacing: 1rem;
  column-width: 3rem;
}

.key:hover {
  background-color: #808080;
}

.operator:hover {
  background-color: #2d5d69;
}

.btns {
  background-color: #3d6d79;
  color: white;
  font-size: 3.5rem;
}

.btns:hover {
  background-color: #2d5d69;
}

#equals {
  background-color: black;
  color: white;
}

#equals:hover {
  background-color: #101010;
}

td {
  font-size: 3.5rem;
  color: black;
  background-color: #969696;
  box-shadow: 0rem 0.2rem 0.4rem 0 black;
  padding: 0;
  white-space: nowrap;
}

td img {
  height: auto;
  width: 2rem;
  display: block;
  padding: 0;
  margin: 0 auto;
}

.operator {
  background-color: #3d6d79;
  color: white;
  font-size: 3.5rem;
}

/*footer*/

footer {
  width: 100%;
  height: 2%;
  background-color: #282828;
  position: absolute;
  bottom: 0;
  padding: 20px 0;
  text-align: center;
  box-shadow: 0rem -0.2rem 0.6rem 0 #282828;
}

footer h4 {
  width: 100%;
  font-size: 1.2rem;
  color: #bb9696;
  margin: 10px auto;
  position: absolute;
  bottom: 3rem;
}

footer h5 {
  font-size: 0.8rem;
  width: 100%;
  color: #969696;
  margin: 12px 0 8px 0;
  position: absolute;
  bottom: 0;
}

footer a {
  text-decoration: none;
  font-style: italic;
  color: #bbbbbb;
}

@media screen and (max-height: 350px) {
  html,
  body {
    font-size: 5px;
  }
  header {
    height: 4%;
    padding: 0.5rem;
  }
  #title-cont img {
    width: 2rem;
  }
  #title-cont h2 {
    width: 32%;
  }
  #main-cont {
    top: 40%;
  }
  footer {
    height: 1%;
  }
}

@media screen and (min-height: 450px) {
  html,
  body {
    font-size: 8px;
  }
  header {
    height: 4%;
    padding: 0.5rem;
  }
  #title-cont img {
    width: 1.5rem;
  }
  #main-cont {
    top: 41%;
  }
  footer {
    height: 2%;
  }
  #title-cont h2 {
    width: 35%;
  }
}

@media screen and (min-height: 650px) {
  html,
  body {
    font-size: 10px;
  }
  header {
    height: 5%;
  }
  #title-cont h2 {
    width: 28%;
  }
  footer {
    height: 4%;
  }
  #main-cont {
    width: 28rem;
  }
}

@media screen and (min-height: 850px) {
  html,
  body {
    font-size: 12px;
  }
  footer {
    height: 4%;
  }
}
const output = document.getElementById("output-text");
const stack = ["0"];
const postfix = ["0"];
stack.length = 0;
postfix.length = 0;

var freshStart = true;
var decimalOnce = false;

//to read operators and display it
document.querySelectorAll(".operator").forEach((item) => {
  item.addEventListener("click", (event) => {
    var value = item.innerHTML;
    let lastChar = output.innerHTML[output.innerHTML.length - 1];
    if (isOperator(deFormat(value))) {
      freshStart = false;
      decimalOnce = false;
      if (!isOperator(deFormat(lastChar))) output.innerHTML += value;
      else {
        output.innerHTML = output.innerHTML.substring(
          0,
          output.innerHTML.length - 1
        );
        output.innerHTML += value;
      }
    }
    output.scrollLeft = output.scrollWidth;
  });
});

//to read numbers and display it
document.querySelectorAll(".key").forEach((item) => {
  item.addEventListener("click", (event) => {
    var value = item.innerHTML;
    if (freshStart) {
      output.innerHTML = "";
      freshStart = false;
    }
    if (value == "." && !decimalOnce) {
      if (
        output.innerHTML == "" ||
        isOperator(output.innerHTML[output.innerHTML.length - 1])
      ) {
        output.innerHTML += "0.";
        decimalOnce = true;
      } else if (output.innerHTML[output.innerHTML.length - 1] != ".") {
        output.innerHTML += ".";
        decimalOnce = true;
      }
    } else if (!isNaN(value)) output.innerHTML += value;
    output.scrollLeft = output.scrollWidth;
  });
});

//to convert the text in ouput field to postfix, evaluate and display it
document.getElementById("equals").addEventListener("click", function () {
  while (isNaN(output.innerHTML[output.innerHTML.length - 1])) {
    var string = output.innerHTML;
    string = string.substring(0, string.length - 1);
    output.innerHTML = string;
  }
  var expression = deFormat(output.innerHTML);
  let tempStr = expression;
  let lastIndex = 0;
  let i = 0;
  //conversion to postfix
  for (i = 0; i < expression.length; i++) {
    let x = expression.charAt(i);
    if (isOperator(x)) {
      postfix.push(expression.substring(lastIndex, i));
      lastIndex = i + 1;
      if (stack.length > 0)
        if (isOperator(stack[stack.length - 1]))
          while (precedCheck(stack[stack.length - 1]) >= precedCheck(x))
            postfix.push(stack.pop());
      stack.push(x);
    }
  }
  postfix.push(expression.substring(lastIndex, expression.length));
  while (stack.length > 0) postfix.push(stack.pop());
  //evaluation of postfix expression
  while (postfix.length != 0) {
    let val = postfix[0];
    postfix.shift();
    if (isOperator(val)) {
      let y = parseFloat(stack.pop());
      let x = parseFloat(stack.pop());
      switch (val) {
        case "*":
          stack.push(x * y);
          break;
        case "/":
          stack.push(x / y);
          break;
        case "+":
          stack.push(x + y);
          break;
        case "-":
          stack.push(x - y);
          break;
      }
    } else stack.push(val);
  }
  if (stack) {
    output.innerHTML = stack[stack.length - 1];
  } else output.innerHTML = "ERROR";
  stack.length = 0;
  postfix.length = 0;
  freshStart = true;
  output.scrollLeft = output.scrollWidth;
});

//backspace
document.getElementById("backspace").addEventListener("click", function () {
  var string = output.innerHTML;
  string = string.substring(0, string.length - 1);
  if (output.innerHTML[output.innerHTML.length - 1] == ".") decimalOnce = false;
  if (string.length == 0 || freshStart) {
    output.innerHTML = "0";
    stack.length = 0;
    postfix.length = 0;
    freshStart = true;
  } else output.innerHTML = string;
});

//clear
document.getElementById("clear").addEventListener("click", function () {
  output.innerHTML = "0";
  stack.length = 0;
  freshStart = true;
  postfix.length = 0;
});

//to check whether parameter is a supported operator
function isOperator(value) {
  if (value == "/" || value == "*" || value == "+" || value == "-") return true;
  return false;
}

//function that returns higher value if the precedence is higher
function precedCheck(value) {
  if (value == "*" || value == "/") return 2;
  else if (value == "+" || value == "-") return 1;
  else return -1;
}

//to formate operators to general form
function format(val) {
  val = val.replace(/\*/g, "×");
  val = val.replace(/\//g, "÷");
  return val;
}

//deformation for calculation
function deFormat(val) {
  val = val.replace(/\×/g, "*");
  val = val.replace(/\÷/g, "/");
  return val;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.