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

Discussion

pic
Editor guide
Collapse
kretaceous profile image
Abhijit Hota

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!😄

Collapse
mohammedfarmaan profile image
Mohammed Farmaan Author

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!😁

Collapse
powerc9000 profile image
Clay Murray

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);
    })
}

Collapse
mohammedfarmaan profile image
Mohammed Farmaan Author

Great. Thanks for the explanation!😄

Collapse
powerc9000 profile image
Clay Murray

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

Thread Thread
mohammedfarmaan profile image
Mohammed Farmaan Author

Thank you!😇

Collapse
tadeubarbosa profile image
Tadeu Barbosa

Congrats! It's a good design and project!

Collapse
mohammedfarmaan profile image
Mohammed Farmaan Author

Thank you!😊

Collapse
mathurahravi profile image
Mathurah Ravigulan

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/

Collapse
madza profile image
Madza

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

Collapse
mohammedfarmaan profile image
Mohammed Farmaan Author

Yess it doesn't count!😂

Collapse
jlohani profile image
Jayant Lohani

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.

Collapse
mohammedfarmaan profile image
Mohammed Farmaan Author

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.

Collapse
jlohani profile image
Jayant Lohani

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.

Thread Thread
mohammedfarmaan profile image
Mohammed Farmaan Author

Hahah sure. You can do that too xD.😜

Collapse
akdeberg profile image
Anik Khan

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

Collapse
mohammedfarmaan profile image
Mohammed Farmaan Author

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

Collapse
willemodendaal profile image
Willem Odendaal

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

Collapse
mohammedfarmaan profile image
Mohammed Farmaan Author

Thank you!😄

Collapse
yedveshubham profile image
Shubham_Yedve

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

Collapse
mohammedfarmaan profile image
Mohammed Farmaan Author

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

Collapse
raounek profile image
touibeg mohamed

good job mohammad ...

Collapse
mohammedfarmaan profile image
Mohammed Farmaan Author

Thank you!😇

Collapse
moyohussein_92 profile image
Hussein AbdulQohar

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.