<!-- hands off! CSS changes only. -->

<div class="calculator">
  <div class="calculator__display" data-display>0</div>
  <div class="calculator__keyboard">
    <div class="calculator__numbers">
      <button class="button button--number" type="button" data-keycode="67" value="clear">C</button>
      <button class="button button--number" type="button" data-keycode="84" value="toggle">&#8314;&#8725;&#8331;</button>
      <button class="button button--number" type="button" data-keycode="88" value="exponent">%</button>
      <button class="button button--number" type="button" data-keycode="190" value=".">.</button>
      <button class="button button--number" type="button" data-keycode="48" value="0">0</button>
      <button class="button button--number" type="button" data-keycode="49" value="1">1</button>
      <button class="button button--number" type="button" data-keycode="50" value="2">2</button>
      <button class="button button--number" type="button" data-keycode="51" value="3">3</button>
      <button class="button button--number" type="button" data-keycode="52" value="4">4</button>
      <button class="button button--number" type="button" data-keycode="53" value="5">5</button>
      <button class="button button--number" type="button" data-keycode="54" value="6">6</button>
      <button class="button button--number" type="button" data-keycode="55" value="7">7</button>
      <button class="button button--number" type="button" data-keycode="56" value="8">8</button>
      <button class="button button--number" type="button" data-keycode="57" value="9">9</button>
    </div>
    <div class="calculator__operators">
      <button class="button button--operator" type="button" data-keycode="47" value="div">÷</button>
      <button class="button button--operator" type="button" data-keycode="221" value="mult"><span>×</span></button>
      <button class="button button--operator" type="button" data-keycode="189" value="subtract"></button>
      <button class="button button--operator" type="button" data-keycode="187" value="sum">+</button>
      <button class="button button--operator" type="button" data-keycode="13" value="result">=</button>
    </div>
  </div>
</div>
// author: James Sheasby Thomas (@rightsaidjames)

.calculator {
  width: 300px;
  border: 2px solid black;
  padding: 20px 5px 30px 5px;
  background-color: #3F3F3F;
  box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.75);
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  font-family: Helvetica, Arial, sans;
}

.calculator__display {
  background-color: #A0B558;
  padding: 5px;
  margin: 5px 0px 5px 0px;
  flex-basis: 80%;
}

button {
  width: 20%;
  margin: 5px;
  height: auto;
  background-color: white;
  border-radius: 5px;
}

button[value="clear"] {
  background-color: darkred;
  color: white;
  width: 47%;
  order: 4;
}

button[value="toggle"], button[value="exponent"], button[value="."] {
  background-color: grey;
  color: white;
}

div.calculator__numbers {
  display: flex;
  width: 60%;
  float: left;
  order: 0;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
}

button[value="0"] {
  order: 5;
}

div.calculator__operators{
  
}
.button--operator {
  background-color: #212121;
  color: white;
  width: 30%;
  padding: 3x 0px 3px 0px;
}

button[value="result"] {
  background-color: darkgreen;
}





























// change this if you'd like
body {
  display: flex;
  min-height: 100vh;
  align-items: center;
  justify-content: center;
}
View Compiled
// hands off! CSS changes only.



































let calculator = {
  // Initialise defaults
  data: {
    maxChars: 10,
    storedResult: null,
    currentValue: "0",
    currentOperation: null,

    // Map the keys
    mapKeys: {
      48: { type: "input", value: "0" },
      49: { type: "input", value: "1" },
      50: { type: "input", value: "2" },
      51: { type: "input", value: "3" },
      52: { type: "input", value: "4" },
      53: { type: "input", value: "5" },
      54: { type: "input", value: "6" },
      55: { type: "input", value: "7" },
      56: { type: "input", value: "8" },
      57: { type: "input", value: "9" },
      190: { type: "input", value: "." },
      88: { type: "operation", value: "exponent" },
      47: { type: "operation", value: "division" },
      221: { type: "operation", value: "multiply" },
      189: { type: "operation", value: "subtract" },
      187: { type: "operation", value: "sum" },
      67: { type: "clear", value: "clear" },
      13: { type: "result", value: null },
      8: { type: "delete", value: null },
      84: { type: "toggle", value: "toggle" }
    }
  },

  // Receive keyboard input (via data-keycode) & press the corresponding button

  activateButtonWithKeypress(keyCode) {
    const chooseBtn = document.querySelectorAll(
      `[data-keycode="${keyCode}"]`
    )[0];
    if (chooseBtn) {
      chooseBtn.classList.toggle("active");
      setTimeout(() => {
        chooseBtn.classList.toggle("active");
      }, 150);
    }
  },

  // Select all buttons & map to corresponding type

  bindButtons() {
    const buttons = document.querySelectorAll("[data-keycode]");
    const mapKeys = calculator.data.mapKeys;
    Array.from(buttons).forEach((button) => {
      button.addEventListener("click", (event) => {
        this.processUserInput(mapKeys[event.target.dataset.keycode]);
      });
    });
  },

  bindKeyboard() {
    document.addEventListener("keydown", (event) => {
      const mapKeys = calculator.data.mapKeys;
      let keyCode = event.keyCode;

      // binds shift + 7 to 'divide by'
      if (keyCode === 55 && event.shiftKey) {
        keyCode = 47;
      }
      if (mapKeys[keyCode]) {
        this.processUserInput(mapKeys[keyCode]);
        this.activateButtonWithKeypress(keyCode);
      }
    });
  },

  // Blinks display content when numbers are pressed

  blinkDisplay() {
    const blinkDisplay = document.querySelector("[data-display]");
    blinkDisplay.classList.toggle("blink");
    setTimeout(() => {
      blinkDisplay.classList.toggle("blink");
    }, 150);
  },

  // Perform the calculation!

  calculate() {
    // Initialise and convert input to number
    const oldValue = parseFloat(this.data.storedResult, 10);
    const operation = this.data.currentOperation;
    const newValue = parseFloat(this.data.currentValue, 10);
    let resultValue = 0;

    // Performs calculation of numbers determined by operator value
    if (this.data.currentOperation === "multiply") {
      resultValue = oldValue * newValue;
    }
    if (this.data.currentOperation === "division") {
      resultValue = oldValue / newValue;
    }
    if (this.data.currentOperation === "subtract") {
      resultValue = oldValue - newValue;
    }
    if (this.data.currentOperation === "sum") {
      const multiplierFix = 1000000000;
      // resultValue = oldValue + newValue;
      resultValue =
        (oldValue * multiplierFix + newValue * multiplierFix) / multiplierFix;
    }
    if (this.data.currentOperation === "exponent") {
      resultValue = Math.pow(oldValue, newValue);
    }
    this.data.storedResult = null;
    this.data.currentValue = "" + resultValue;
    this.updateDisplay();
  },

  // Resets defaults and clears display for 'C' button
  clearAll() {
    this.data.currentOperation = null;
    this.data.storedResult = null;
    this.data.currentValue = "0";
    this.updateDisplay();
  },

  // Resets current value
  clearCurrentValue() {
    this.data.currentValue = "0";
    this.updateDisplay();
  },

  // Removes last entered number if backspaced
  deleteNumber() {
    const newValue = this.data.currentValue.slice(0, -1);
    if (newValue === "") {
      this.blinkDisplay();
      this.clearCurrentValue();
    } else {
      this.data.currentValue = newValue;
      this.updateDisplay();
    }
  },

  // Receives user input type and launches corresponding function

  processUserInput(userInput) {
    if (userInput.type === "input") {
      this.setNumber(userInput.value);
    }
    if (userInput.type === "operation") {
      this.setOperation(userInput.value);
    }
    if (userInput.type === "delete") {
      this.deleteNumber();
    }
    if (userInput.type === "result") {
      this.showResult();
    }
    if (userInput.type === "clear") {
      this.clearAll();
    }
    if (userInput.type === "toggle") {
      this.toggleNumber();
    }
  },

  // Blinks display as required to prompt user

  setNumber(newNumber) {
    let currentValue = this.data.currentValue;
    if (newNumber === "." && currentValue.includes(".")) {
      this.blinkDisplay();
      return;
    }
    if (currentValue.length === this.data.maxChars) {
      this.blinkDisplay();
      return;
    }
    if (currentValue === "0" && newNumber === ".") {
      currentValue = "0.";
    } else if (currentValue === "0" && newNumber !== ".") {
      this.blinkDisplay();
      currentValue = newNumber;
    } else {
      currentValue += newNumber;
    }
    this.data.currentValue = currentValue;
    this.updateDisplay();
  },

  // Selects operator for calculation

  setOperation(newOperation) {
    if (
      this.data.currentOperation !== null &&
      this.data.storedResult !== null
    ) {
      this.calculate();
    }
    this.data.storedResult = this.data.currentValue;
    this.data.currentValue = "0";
    this.data.currentOperation = newOperation;
  },

  // When "=" is pressed, perform calculation and update the display

  showResult() {
    if (this.data.storedResult !== null) {
      this.calculate();
      this.updateDisplay();

      // if null "=" was pressed first
    } else {
      this.blinkDisplay();
    }
  },

  // When toggle button is pressed, toggle negative '-'
  toggleNumber() {
    this.data.currentValue = parseFloat(this.data.currentValue, 10) * -1 + "";
    this.updateDisplay();
  },

  // Add current value to display class
  updateDisplay() {
    document.querySelector("[data-display]").innerHTML = this.data.currentValue;
  },

  // Function to initialise display and bindings
  start() {
    this.updateDisplay();
    this.bindKeyboard();
    this.bindButtons();
  }
};

// Start the app
calculator.start();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.