Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <div class="container">
  <div class="calculator">
    <div>
      <input id="displayWindow" type="text" value="0" disabled>
    </div>

    <div>
      <input id="formulaWindow" type="text" disabled>
    </div>

    <div> <!-- row 1 -->
<!-- Squishy buttons HTML taken from https://codepen.io/soulwire/pen/bKens -->
      <div class="toggle">
        <input id="power" type="checkbox">
        <span class="button"></span>
        <span id="powerlabel" class="label"><i class="fas fa-power-off"></i></span>
      </div>

      <div class="toggle">
        <input id="ac" type="checkbox">
        <span class="button"></span>
        <span class="label">AC</span>
      </div>

      <div class="toggle">
        <input id="ce" type="checkbox">
        <span class="button"></span>
        <span class="label">CE</span>
      </div>

      <div class="toggle">
        <input id="divide" type="checkbox">
        <span class="button"></span>
        <span class="label">&divide;</span>
      </div>
    </div> <!-- row 1 -->

    <div> <!-- row 2 -->
      <div class="toggle">
        <input id="seven" type="checkbox">
        <span class="button"></span>
        <span class="label">7</span>
      </div>

      <div class="toggle">
        <input id="eight" type="checkbox">
        <span class="button"></span>
        <span class="label">8</span>
      </div>

      <div class="toggle">
        <input id="nine" type="checkbox">
        <span class="button"></span>
        <span class="label">9</span>
      </div>

      <div class="toggle">
        <input id="times" type="checkbox">
        <span class="button"></span>
        <span class="label">&times;</span>
      </div>
    </div> <!-- row 2 -->

    <div> <!-- row 3 -->
      <div class="toggle">
        <input id="four" type="checkbox">
        <span class="button"></span>
        <span class="label">4</span>
      </div>

      <div class="toggle">
        <input id="five" type="checkbox">
        <span class="button"></span>
        <span class="label">5</span>
      </div>

      <div class="toggle">
        <input id="six" type="checkbox">
        <span class="button"></span>
        <span class="label">6</span>
      </div>

      <div class="toggle">
        <input id="minus" type="checkbox">
        <span class="button"></span>
        <span class="label">&minus;</span>
      </div>
    </div> <!-- row 3 -->

    <div> <!-- row 4 -->
      <div class="toggle">
        <input id="one" type="checkbox">
        <span class="button"></span>
        <span class="label">1</span>
      </div>

      <div class="toggle">
        <input id="two" type="checkbox">
        <span class="button"></span>
        <span class="label">2</span>
      </div>

      <div class="toggle">
        <input id="three" type="checkbox">
        <span class="button"></span>
        <span class="label">3</span>
      </div>

      <div class="toggle">
        <input id="plus" type="checkbox">
        <span class="button"></span>
        <span class="label">&plus;</span>
      </div>
    </div> <!-- row 4 -->

    <div> <!-- row 5 -->
      <div id="zerodiv" class="toggle">
        <input id="zero" type="checkbox">
        <span id="zerobutton" class="button"></span>
        <span class="label">0</span>
      </div>

      <div class="toggle">
        <input id="decimal" type="checkbox">
        <span class="button"></span>
        <span class="label">.</span>
      </div>
      
      <div class="toggle">
        <input id="equals" type="checkbox" value="=">
        <span class="button"></span>
        <span class="label">&equals;</span>
      </div>
    </div> <!-- row 5 -->

  </div> <!-- .calculator -->
</div> <!-- .container -->
<script src="https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js"></script>
              
            
!

CSS

              
                /* squishy buttons */

// Squishy buttons CSS taken from https://codepen.io/soulwire/pen/bKens

@import compass

// Squishy buttons inspired by https://goo.gl/bFCyS

@import url(https://fonts.googleapis.com/css?family=Montserrat)

input
  
  text-align: right
  height: 70px
  width: 315px
  padding-right: 8px
  font-size: 3em
  border-radius: 10px
  font-family: 'Montserrat', sans-serif
  
#displayWindow
  
  border-radius: 10px
  border-top: none
  box-shadow: inset 0px 0px 10px rgba(0,0,0,.5), inset 0px -20px 1px rgba(180, 180, 180, .15)
  background: #dfdfdf
  
#formulaWindow
  
  height: 25px
  font-size: 1em
  margin-top: 4px
  margin-bottom: 10px
  border-radius: 10px
  border-top: none
  box-shadow: inset 0px 0px 10px rgba(0,0,0,.5), inset 0px -8px 1px rgba(180, 180, 180, .15)
  background: #dfdfdf

html, body

  font-family: 'Montserrat', sans-serif
  // background from http://lea.verou.me/css3patterns/#carbon-fibre
  background: radial-gradient(black 15%, transparent 16%) 0 0, radial-gradient(black 15%, transparent 16%) 8px 8px, radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 0 1px, radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 8px 9px
  background-color: #1f1f1f
  background-size: 16px 16px
  text-align: center
  height: 100%

.container
  
  text-align: center
  position: absolute
  margin-top: -250px
  width: 100%
  top: 50%

.calculator
  
  padding-top: 25px
  padding-bottom: 20px
  border-radius: 20px
  background: #ccd0d4
  width: 370px
  margin-left: auto
  margin-right: auto
  box-shadow: inset -13px -11px 30px rgba(50,50,50,0.6), inset 5px -7px 15px rgba(55,45,35,0.7)

.toggle

  display: inline-block
  
#zerodiv
  
  width: 160px
  
.toggle

  $size: 80px

  position: relative
  height: $size
  width: $size

  &:before

    $radius: $size * 0.845
    $glow: $size * 0.125

    box-shadow: 0 0 $glow $glow / 2 #fff
    border-radius: $radius
    background: #fff
    position: absolute
    margin-left: ( $radius - $glow ) * -0.5
    margin-top: ( $radius - $glow ) * -0.5
    opacity: 0.2
    content: ''
    height: $radius - $glow
    width: $radius - $glow
    left: 50%
    top: 50%

  .button

    $radius: $size * 0.715

    -webkit-filter: blur(1px)
    -moz-filter: blur(1px)
    filter: blur(1px)

    transition: all 300ms cubic-bezier(0.230, 1.000, 0.320, 1.000)
    -webkit-transition: all 300ms cubic-bezier(0.230, 1.000, 0.320, 1.000)
    box-shadow: 0 15px 25px -4px rgba(0,0,0,0.5), inset 0 -3px 4px -1px rgba(0,0,0,0.2), 0 -7px 15px -1px rgba(255,255,255,0.6), inset 0 3px 4px -1px rgba(255,255,255,0.2), inset 0 0 5px 1px rgba(255,255,255,0.8), inset 0 20px 30px 0 rgba(255,255,255,0.2)
    border-radius: $radius
    position: absolute
    background: #ccd0d4
    margin-left: $radius * -0.5
    margin-top: $radius * -0.5
    display: block
    height: $radius
    width: $radius
    left: 50%
    top: 50%
    
  #zerobutton
    
    margin-left: -70px
    width: 140px

  .label

    transition: color 300ms ease-out
    -webkit-transition: color 300ms ease-out
    text-shadow: 1px 1px 3px #ccd0d4, 0 0 0 rgba(0,0,0,0.8), 1px 1px 4px #fff
    line-height: $size - 1
    text-align: center
    position: absolute
    font-weight: 700
    font-size: 20px
    display: block
    opacity: 0.9
    height: 100%
    width: 100%
    color: rgba(0,0,0,0.4)
    
  #powerlabel
    
    color: rgba(0,128,0,0.3)

  input

    opacity: 0
    background :red
    position: absolute
    cursor: pointer
    z-index: 1
    height: 100%
    width: 100%
    left: 0
    top: 0

    &:active

      ~ .button

        box-shadow: 0 15px 25px -4px rgba(0,0,0,0.4), inset 0 -8px 30px 1px rgba(255,255,255,0.9), 0 -7px 15px -1px rgba(255,255,255,0.6), inset 0 8px 25px 0 rgba(0,0,0,0.4), inset 0 0 10px 1px rgba(255,255,255,0.6)
      
      ~ .label

        font-size: 19px
        color: rgba(0,0,0,0.45)
              
            
!

JS

              
                var formula = "";
var display = "";

var powerOn = true;
var operatorPressed = false;
var equalsPressed = false;
var decimalPressed = false;

var numbers = [
  [zero, "0"],
  [one, "1"],
  [two, "2"],
  [three, "3"],
  [four, "4"],
  [five, "5"],
  [six, "6"],
  [seven, "7"],
  [eight, "8"],
  [nine, "9"]
];

var operators = [
  [divide, "/"],
  [times, "*"],
  [plus, "+"],
  [minus, "-"]
];

power.addEventListener("click", function(){
  
  if (powerOn) {
    
    reset();
    powerOn = false;
    powerlabel.style.color = "rgba(255,0,0,0.3)"   
    disp("", "");
    
  } else {
    
    reset();
    powerOn = true;
    powerlabel.style.color = "rgba(0,128,0,0.3)"

    disp("0", "");
    
  }
  
});

numbers.forEach(function(element){
  
  element[0].addEventListener("click", function(){

    if (powerOn) { 

      if (equalsPressed) {

        formula = "";
        display = "";
        equalsPressed = false;

      }
      // if operator was pressed, reset displayWindow to prepare for new number
      if (operatorPressed) {
        // if first character is not "-", reset displayWindow
        if(formula.charAt(0) !== "-") {

          display = "";

        }     
        // display "-" if last char is "-"
        if (getFromLast(1) === "-") {

            display = "-";

        } 

        operatorPressed = false;

      }

      formula += element[1];
      display += element[1];   
      // eval display if first number is 0
      if (!decimalPressed && element[1] !== "0" && formula.charAt(0) !== "-") {

        display = eval(display);     

      } 
      // eval formula and display if first number is 0
      if (formula.length === 2 && formula.charAt(0) === "0"){

        display = eval(display);
        formula = eval(formula).toString();

      }
      // if first number after operator is zero, eval formula and display to remove zero
      if (isNaN(getFromLast(3)) && getFromLast(3) !== "." && getFromLast(2) === "0") {

        let temp = formula.slice(-2);
        formula = formula.slice(0, -2);
        display = eval(display);
        formula += eval(temp).toString();

      }

      disp(display, formula);

    }
    
  });
  
});

operators.forEach(function(element){
  
  element[0].addEventListener("click", function(){
    
    if (powerOn) {   

      let operatorVal = element[1];
      let lastChar = getFromLast(1);
      // "-" has special functions, so operation is separated
      if (operatorVal === "-") {

        lastChar = subtract(lastChar);

      } else {

        if (!operatorPressed) {
          // add "0" if operator follows decimal
          if (isNaN(lastChar)) {

            formula += "0"; 

          }
          // resets displayWindow when operator is pressed
          if (formula !== "") {

            display = "";
            formula += operatorVal;

          }    
          // allows decimal to be pressed again if previously pressed    
          if (decimalPressed) { 
            decimalPressed = false; 
          } 
          // if equals was pressed, reset equalsPressed to allow continued input
          if (equalsPressed) { 
            equalsPressed = false; 
          }

          operatorPressed = true;

        }

      }

      disp(display, formula);

    } 
  
  });
  
});

decimal.addEventListener("click", function(){  

  if (powerOn) { 
    // prevents double decimal points in a number
    if (!decimalPressed) {
      // if decimal follows an operator or equals, calculator should display "0."
      if (operatorPressed || equalsPressed) {

        operatorPressed = false;
        display = "0.";
        // if equals is pressed, formula value is replaced by "0."
        if (equalsPressed) {

          formula = "0.";
          equalsPressed = false;
        // if equals is not pressed, "0." is added to formula  
        } else { 

          formula += "0.";

        }

      } else {    
        // if last char of formula is operator or first char of formula, display "0."
        if(isNaN(formula.charAt(formula.length - 1)) || formula === "") { 

          display = "0."; 

        } else { 
          // add "." to display if not after an operator or not a first character  
          display += ".";

        }
        // if first character, update formula by adding "0." Otherwise, add only "."
        if (formula === "") {

          formula += "0."; 

        } else { 

          formula += "."; 

        }

      }     

    }

    decimalPressed = true;

    disp(display, formula);
    
  }
  
});

equals.addEventListener("click", function(){
  
    if (powerOn) { 
      //decimal.js is from https://github.com/MikeMcl/decimal.js/
      let temp = new Decimal(eval(formula));

      formula = temp.toPrecision(15);
      //remove zeroes from the end of the number
      //Decimal.toPrecision adds several zeroes at the end of a number
      if (getFromLast(1) == 0) {

        removeZeroes();

      }

      if (formula.length > 10) {

        formula = formula.substring(0, 10); 

        if (getFromLast(1) == 0 && formula.indexOf(".") > -1) {

          removeZeroes();

        }
       
        display = formula;
        disp(display, "Digit limit met")

      } else {

        formula = formula.substring(0, 10);  

        equalsPressed = true;
        decimalPressed = false;

        disp(formula, formula);

      }

  }  

});
// AC resets everything
ac.addEventListener("click", function(){
  
  if (powerOn) { 
  
    reset();

    displayWindow.value = "0";
    formulaWindow.value = "";
    
  }
  
});
// CE removes last entered number or operator
ce.addEventListener("click", function(){
  
  if (powerOn) { 
  
    if (formula !== "") {

      let lastChar = getFromLast(1);  
      // remove if last char is operator
      if (isNaN(lastChar)) {
        // remove entire number if last char is decimal
        if (lastChar === ".") {

          removeNum(lastChar);

        } else {

          formula = formula.slice(0, -1); 

        }

      } else {
        // remove number and continue until last char is operator
        removeNum(lastChar);
        // if first char is "-", remove it
        if (isNaN(formula.charAt(0))) {

           formula = formula.slice(0, -1);

        }

      }

    }

    decimalPressed = false;
    equalsPressed = false;
    // reset displayWindow
    display = "";
    disp(display, formula);
    // ensure operator cannot be pressed if last char is operator    
    lastChar = getFromLast(1);

    if (isNaN(lastChar)) {

      operatorPressed = true; 

    } else { 

      operatorPressed = false; 

    }
  
  }

});

function disp(dispVal, forVal) {
  
  if (dispVal.toString().length > 10) {

    displayWindow.value = "Error"; 
    formulaWindow.value = "GREAT JOB! You broke it.";
    
    reset();
    
  } else if (forVal.length >30) {
    
    displayWindow.value = "Error";
    formulaWindow.value = "You like breaking things, huh?"
    
    reset();
    
  } else {

    displayWindow.value = dispVal;
    formulaWindow.value = forVal;
    
  }
  
}

function getFromLast(i) { 
  
  return formula.charAt(formula.length - i); 
  
}

function removeNum(lastChar) {
  // continue deleting if number or decimal
  while (!isNaN(lastChar) || lastChar === ".") {
    
    if (formula === "") { 
      
      break; 
      
    }
    
    if (formula.length > 1) {
      
      formula = formula.slice(0, -1);
      lastChar = getFromLast(1);
      
    } else {
      
      formula = "";
      lastChar = "";
      
    } 
    
  }
  
}
//continue removing "0" from the back until it hits non-zero num or after "."
function removeZeroes() {
  
  let lastChar = getFromLast(1);

    while (lastChar == 0 || lastChar === ".") {

      formula = formula.slice(0, -1);

      if (lastChar === ".") {

        break;

      }

      lastChar = getFromLast(1);

    }
  
}

function subtract(lastChar) {
  // operator cannot be used if already used
  if (operatorPressed) {
    // if lastChar is a symbol that isn't  "-", 
    if (isNaN(lastChar) && lastChar !== "-") {
      // convert "+" to "-"
      if (lastChar === "+") {
        
        formula = formula.slice(0, -1);
        formula += "-";
        
      } else {  
        //ensure lastChar is not an operator
        display = "-";
        formula += "-";
        
      }
      
    }
    // for after equals but before operator
  } else if (equalsPressed) {
    
    display = "-";
    formula += "-";
    equalsPressed = false;
    
  } else {
    // add "0" after decimal
    if (lastChar === ".") {
      
          formula += "0" + "-";
      
    } else {
      // if not decimal, just add "-"
      display = "-";
      formula += "-";
      decimalPressed = false;
      
    }
    
  }
  
  operatorPressed = true;
  return lastChar;
  
}

function reset() {
  
  display = "";
  formula = "";

  operatorPressed = false;
  equalsPressed = false;
  decimalPressed = false;
  
}
              
            
!
999px

Console