loading...
Cover image for Simple Calculator with Dark Mode.

Simple Calculator with Dark Mode.

mohammedfarmaan profile image Mohammed Farmaan Updated on ・4 min read

Here's a simple calculator built using HTML, CSS and obviously, JavaScript.

This calculator also has dark mode which looks really good. And here's how you can do that:

Here's the markup:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Calculator</title>
  <meta name="description" content="" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link rel="stylesheet" href="light.css" id="theme" />
  <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300&display=swap" rel="stylesheet" />
</head>
<body>
  <center>
    <div class="container">
      <h1>Calculator</h1>
      <div class="first-row">
        <input type="text" name="result" class="result" id="result" value="" placeholder="Result" readonly />
        <input type="button" value="C" onclick="clearScreen()" class="clear" />
      </div>
      <div class="second-row">
        <input type="button" value="1" onclick="liveScreen(1)" id="one" />
        <input type="button" value="2" onclick="liveScreen(2)" id="two" />
        <input type="button" value="3" id="three" onclick="liveScreen(3)" />
        <input type="button" value="+" onclick="liveScreen('+')" />
      </div>
      <div class="third-row">
        <input type="button" value="4" id="four" onclick="liveScreen(4)" />
        <input type="button" value="5" id="five" onclick="liveScreen(5)" />
        <input type="button" value="6" id="six" onclick="liveScreen(6)" />
        <input type="button" value="-" onclick="liveScreen('-')" />
      </div>
      <div class="fourth-row">
        <input type="button" value="7" id="seven" onclick="liveScreen(7)" />
        <input type="button" value="8" id="eight" onclick="liveScreen(8)" />
        <input type="button" value="9" id="nine" onclick="liveScreen(9)" />
        <input type="button" value="x" onclick="liveScreen('*')" />
      </div>
      <div class="fifth-row">
        <input type="button" value="/" onclick="liveScreen('/')" />
 <input type="button" value="0" id="zero" onclick="liveScreen(0)" />
        <input type="button" value="." class="dot" onclick="liveScreen('.')" />
        <input type="button" value="=" onclick="result.value = eval(result.value)" />
      </div>
      <div class="bottom-buttons">
        <button>
          <i class="fab fa-github"></i>
          <a href="https://github.com/Mohammad-Farmaan/JavaScript-Calculator">GitHub</a>
        </button>
        <button onclick="switchTheme()" id="dark-mode">
          Dark Mode 🌙
        </button>
      </div>
    </div>
  </center>
  <script src="https://kit.fontawesome.com/f28b055962.js" crossorigin="anonymous"></script>
  <script src="script.js" async defer></script>
</body>
</html>

Here's the CSS for Light Mode:

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  font-family: "Open Sans", sans-serif;
  font-weight: bold;
}
body {
  background-color: rgb(28, 231, 221);
  transition: 0.8s;
  -webkit-transition: 0.8s;
  -moz-transition: 0.8s;
  -ms-transition: 0.8s;
  -o-transition: 0.8s;
}
h1 {
  margin-top: 25vh;
  text-align: center;
  margin-bottom: 1.5%;
  color: #fff;
}
.container {
  width: 370px;
}
.result {
  width: 59.1%;
}
input {
  padding: 25px;
  color: rgb(17, 16, 16);
  font-size: 1em;
  cursor: pointer;
  width: 70px;
  background-color: #fff;
  border: none;
  outline: none;
  border-radius: 4px;
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  -ms-border-radius: 4px;
  -o-border-radius: 4px;
}

.first-row,
.second-row,
.third-row,
.fourth-row,
.fifth-row {
  margin-bottom: 3px;
}
input[type="text"] {
  background-color: rgb(255, 255, 255);
}
input[type="button"]:hover {
  background-color: rgb(37, 35, 59);
  color: #fff;
}
.clear {
  color: #fff;
  background-color: rgb(255, 42, 42);
}
button {
  border: none;
  background-color: rgb(41, 38, 38);
  padding: 10px;
  color: white;
  margin: 2px;
  cursor: pointer;
  outline: none;
  border-radius: 4px;
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  -ms-border-radius: 4px;
  -o-border-radius: 4px;
}

button a {
  text-decoration: none;
  color: #fff;
}
.bottom-buttons {
  float: left;
  margin-left: 10%;
  margin-top: 0.7%;
}

@media (max-width: 640px) {
  h1 {
    margin-top: 15vh;
  }
}

Here's the CSS for Dark Mode:

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  font-family: "Open Sans", sans-serif;
  font-weight: bold;
}

body {
  background-color: rgb(20, 19, 19);
  transition: 0.8s;
  -webkit-transition: 0.8s;
  -moz-transition: 0.8s;
  -ms-transition: 0.8s;
  -o-transition: 0.8s;
}
h1 {
  margin-top: 25vh;
  text-align: center;
  margin-bottom: 1.5%;
  color: #fff;
}
.container {
  width: 370px;
}
.result {
  width: 59.1%;
}
input {
  padding: 25px;
  color: rgb(255, 255, 255);
  font-size: 1em;
  cursor: pointer;
  width: 70px;
  background-color: rgb(47, 51, 50);
  border: none;
  outline: none;
  border-radius: 4px;
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  -ms-border-radius: 4px;
  -o-border-radius: 4px;
}

.first-row,
.second-row,
.third-row,
.fourth-row,
.fifth-row {
  margin-bottom: 3px;
}
input[type="text"] {
  background-color: rgb(47, 51, 50);
}
input[type="button"]:hover {
  background-color: rgb(160, 160, 160);
  color: #fff;
}
.clear {
  color: #fff;
  background-color: rgb(255, 42, 42);
}
button {
  border: none;
  background-color: rgb(39, 36, 36);
  padding: 10px;
  color: white;
  margin: 2px;
  cursor: pointer;
  outline: none;
  border-radius: 4px;
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  -ms-border-radius: 4px;
  -o-border-radius: 4px;
}

button a {
  text-decoration: none;
  color: #fff;
}
.bottom-buttons {
  float: left;
  margin-left: 10%;
  margin-top: 0.7%;
}

@media (max-width: 640px) {
  h1 {
    margin-top: 15vh;
  }
}

And finally, here's the JavaScript:

// Clears the screen on click of C button.
function clearScreen() {
  document.getElementById("result").value = "";
}
// Displays the entered value on screen.
function liveScreen(value) {
  document.getElementById("result").value += value;
}
// Swaps the style sheet in order to  achieve dark mode.
function switchTheme() {
  let darkMode = document.getElementById("dark-mode");
  let theme = document.getElementById("theme");
  if (theme.getAttribute("href") == "light.css") {
    theme.href = "dark.css";
    darkMode.innerHTML = "Light Mode 🌙";
  } else {
    theme.href = "light.css";
    darkMode.innerHTML = "Dark Mode 🌙";
  }
}

That's it. Now we have a simple calculator with dark mode. Thanks for reading. Hope you like it!

Link to live demo:
https://mohammed-farmaan.github.io/JavaScript-Calculator

Here's the link to repo:

GitHub logo Mohammed-Farmaan / JavaScript-Calculator

A simple calculator built using HTML, CSS and JavaScript which also has support for dark mode.

JavaScript Calculator

A Calculator App with dark mode. Built using HTML, CSS and JavaScript. Feel free to check out the code and don't forget to star the repo.

cal

Posted on by:

Discussion

pic
Editor guide
 

Great web-app with great UI! I surely learned something about dark-mode implementation.

Although, may I suggest you to add the readonly attribute to the text input for result, since you're using the notorious eval() function? I'm aware that it's a 'simple' calculator but I'm just suggesting.

Great project, though!😄

 

Yeah sure. I was more focussed on the UI so I didn't put that little extra effort to look into that. Thanks for the suggestion tho. Glad you learned something!😁

 

Here you go so you don't have to use eval.

// Turns a string equation into a value eg '2*2 + 4' will return '8'
function calcString(input) {
    const values = input.split("");
    const out = [];
    const ops = [];
    const allOps = ["*", "/", "+", "-", ")", "("];

    let num = "";
    for(let index = 0; index < values.length; index++){
    const v = values[index];
        if(v === " ") {
          continue;
        }
      if(!allOps.includes(v)){
        while(!allOps.includes(values[index]) && values[index] !== " " && index < values.length){
          num += values[index];
                 index ++;
        }
        index--;
      out.push(num);
      num = "";
        continue;
      }          

            if (v === ")"){
                let top = ops.pop();

                while(top !== "(" && ops.length) {
                    out.push(top);
                    top = ops.pop();

                }
                if(top !== "("){
                    return "Mismatched parens"
                }
              continue;
            }
            if(ops.length && v !== "(") {
                let top = ops[ops.length - 1];
                let topP = getPrecedence(top);
                const currP = getPrecedence(v);

              while(currP >= topP && top !== "(" && ops.length) {

                out.push(top)
                ops.pop();
                top = ops[ops.length - 1];
                topP = getPrecedence(top);

              }

            } 
            ops.push(v);


    }
    while(ops.length) {
            out.push(ops.pop());
    }
    const stack = [];
    out.forEach((o)=>{
      if(!allOps.includes(o)){
        stack.push(parseFloat(o, 10));
      } else {
        const r = stack.pop();
        const l = stack.pop();
        switch(o) {
          case "+":
            stack.push(l+r);
            break;
          case "-":
            stack.push(l-r);
            break;
          case "*":
            stack.push(l*r);
            break;
          case "/":
            stack.push(l/r);
            break;
        }
      }
    })

  return ""+stack[0]

}
function getPrecedence(value) {
    const precedence = [["("], ["*", "/"], ["+", "-"]];
    return precedence.findIndex((p)=> {
        return p.includes(value);
    })
}

 

Great. Thanks for the explanation!😄

 

Totally forgot to mention! Looks really great the design is super nice.

Thank you!😇

 

Congrats! It's a good design and project!

 

Thank you!😊

 

It would be cool if you could add something with local storage so it saves the dark mode/light mode toggle the user has, so it doesn't automatically change light mode when the screen is reloaded! I came across this blog, thought it could be helpful 😊 joshwcomeau.com/gatsby/dark-mode/

 

Year 2020: If there is not dark mode, it doesn't count xdd

 

Yess it doesn't count!😂

 

This looks amazing. Great work.
I made a calculator a while ago but its design was not good and had some flaws. Will try to create another one like yours which supports dark mode.

 

Thank you!😄 Yeah sure. Feel free to check how I implemented things and don't forget to add your own design to it. Good luck.

 

All I have to do is change the GitHub link at the end.😏
Just kidding.😂😂 Will just look at the implementation and make my own.

Hahah sure. You can do that too xD.😜

 

The UI looks astonishing 😍
And as per the code, I have the same suggestion as @Abhijit.
Thanks a lot for sharing. #Kudos

 

Thank you!😄 Yeah I've considered that suggestion.

 

I like that this is just plain Javascript. Good job :)

 

Thank you!😄

 

Impressive Ui/design I loved it. Especially the transition between the light and the dark theme.

 

Thank you. I'm glad you liked it!😄

 

good job mohammad ...

 

Thank you!😇

 

Thumbs up for the design. Did you notice that evaluating 0.2 multiplied by 6 or 0.2 multiplied by 3 is giving a funny answer, or this just happens to be one of the disadvantages of the eval function.