Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

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

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

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="calc-container">
  <div class="calc-body">
    <section class="top-section">
      <h2 class="current" id="current-output">0</h2>
    </section>
    <section class="buttons">
    <div class="button-column">
      <button class="user-button" data-btn-type="edit" id="btn-ac">AC</button>
      <button class="user-button" data-btn-type="number" id="btn-7">7</button>
      <button class="user-button" data-btn-type="number" id="btn-4">4</button>
      <button class="user-button" data-btn-type="number" id="btn-1">1</button>
      <button class="user-button" data-btn-type="number" id="btn-0">0</button>
    </div>
    <div class="button-column">
      <button class="user-button" data-btn-type="edit" id="btn-ce">CE</button>
      <button class="user-button" data-btn-type="number" id="btn-8">8</button>
      <button class="user-button" data-btn-type="number" id="btn-5">5</button>
      <button class="user-button" data-btn-type="number" id="btn-2">2</button>
      <button class="user-button" data-btn-type="number" id="btn-dec">.</button>    
    </div>
    <div class="button-column">
      <button class="user-button" data-btn-type="edit" id="btn-back">&larr;</button>
      <button class="user-button" data-btn-type="number" id="btn-9">9</button>
      <button class="user-button" data-btn-type="number" id="btn-6">6</button>
      <button class="user-button" data-btn-type="number" id="btn-3">3</button>
    </div>
    <div class="button-column">
      <button class="user-button" data-btn-type="calc" id="btn-div">/</button>
      <button class="user-button" data-btn-type="calc" id="btn-mult">*</button>
      <button class="user-button" data-btn-type="calc" id="btn-sub">-</button>
      <button class="user-button" data-btn-type="calc" id="btn-add">+</button>
      <button class="user-button" data-btn-type="calc" id="btn-eq">=</button>   
    </div>
  </section>
  </div>
</div>
              
            
!

CSS

              
                $calc-width: 320px;
* {
  box-sizing: border-box;
  position: relative;
}
body {
  font-family: "Ubuntu Mono";
  background-image: url('https://images.unsplash.com/photo-1501959181532-7d2a3c064642?dpr=1&auto=format&fit=crop&w=1500&h=975&q=80&cs=tinysrgb&crop=');
  background-size: 1920px auto;
  background-position: center;
  background-repeat: no-repeat;
  max-width: 1500px;
  margin: 0 auto;
}
.calc-container {
  height: 100vh;
  margin: 0 auto;
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: center;
}
.calc-body {
  text-align: center;
  width: $calc-width;
  background-color: rgba(0,0,0,0.3);
  color: white;
  padding-bottom: 1em;
  border-radius: 15px;
  overflow: hidden;
  &::before, &::after {
    content: ' ';
    width: 100%;
    min-height: 100%;
    display: block;
    position: absolute;
    top: 0;
  }
  &::before {
    background-image: url('https://images.unsplash.com/photo-1501959181532-7d2a3c064642?dpr=1&auto=format&fit=crop&w=1500&h=975&q=80&cs=tinysrgb&crop=');
    filter: blur(10px);
    background-size: 1920px auto;
    background-repeat: no-repeat;
    background-position: center;
    z-index: -1;
  }
  &::after {
    z-index: -1;
    background-color: rgba(0,0,0,0.4);
  }
}
.current {
  width: 100%;
  margin: 0.5em auto;
  text-align: right;
  padding: 0.2em 1em;
  font-size: 1.5em;
  background-color: rgba(255,255,255,0.1);
}
.buttons {
  width: $calc-width;
  display: flex;
  justify-content: center;
  margin: 0 auto;
}
.button-column {
  min-width: 72px;
  display: flex;
  flex-direction: column;
}
button {
  color: white;
  font-family: "Ubuntu Mono";
  background-color: rgba(255,255,255,0.3);
  border: thin solid rgba(255,255,255,0);
  transition: 0.15s ease-in-out all;
  font-size: 1.4em;
  &:focus {
    outline: none;
  }
  &:hover {
    cursor: pointer;
    background-color: rgba(255,255,255,0.5);
    border: thin solid rgba(255,255,255,0.7);
    transition: 0.15s ease-in-out all;
  }
}
#btn-eq {
  width: 192%;
  left: -100%;
}
.user-button {
  padding: 15px;
  margin: 3px;
}
              
            
!

JS

              
                // grab all the user input buttons
let buttons = document.getElementsByClassName('user-button');
// main output field
let output = document.getElementById('current-output');
// keeps track of whether the current number has a decimal, and won't allow two decimals
let dec = false;
// holds the result of all arithmetic operations up to this point
let currentTotal = undefined;
// holds the most recent arithmetic operations
let currentArith = undefined;
// determines whether to replace the output string or edit it; either 'replace' or 'edit'
let calcState = 'replace';

window.addEventListener('click', function(e){
  if (buttons[e.target.id]) {
    // then we have the button!
    switch (e.target.getAttribute('data-btn-type')) {
      // handle all potential number entries, including decimals
      case 'number':
        numberEntry(e.target);
        break;
      // handle all potential edits: all clear, clear entry, and backspace
      case 'edit':
        editEntry(e.target);
        break;
      // handle calculations
      case 'calc':
        calculateEntry(e.target);
        break;
    }
  }
});

// number entry accepts a target button element (e.target) and alters the main
// output field based on the target's contents and the calc state
function numberEntry(t) {
  let text = calcState == 'edit' ? output.textContent : '';
  // handle decimals
  if (t.id === 'btn-dec') {
    if (dec) {
      return;
    }
    else {
      if (text === '' || calcState === 'replace') {
        // if the current output string is blank, set it to '0'
        text = '0';
      }
      // keep track of the decimal's position in the output number string
      dec = text.length;
      text += t.textContent;
      output.textContent = text;
      calcState = 'edit';
      return;
    }
  }
  // handle number inputs; if the output text field is showing 0, replace that value
  if (text === '0' && !dec) {
    text = '';
  }
  text += t.textContent;
  output.textContent = text;
  calcState = 'edit';
}

// alter the current main output with backspace, clearing the current entry, or
// clearing all calculations. accepts a target button element (e.target)
function editEntry(t) {
  let text = calcState == 'edit' ? output.textContent : '0';
  // handle backspaces
  if (t.id === 'btn-back') {
    // if backspacing the last number, set the output field to '0'
    if (text.length === 1) {
      text = '0';
      output.textContent = text;
      calcState = 'replace';
      return;
    }
    // otherwise, remove the last character
    else {
      text = text.slice(0, text.length - 1);
      // if the output string's length is now lower than the decimal's last position,
      // update the decimal value to false
      if (text.length - 1 < dec) {
        dec = false;
      }
      output.textContent = text;
      return;
    }
  }
  // clear entry and all clear both zero out the output field and reset the decimal value
  if (t.id === 'btn-ce' || t.id === 'btn-ac') {
    text = '0';
    dec = false;
    calcState = 'replace';
  }
  // all clear also erases the arithmetic and number history
  if (t.id === 'btn-ac') {
    currentTotal = undefined;
    currentArith = undefined;
  }
  output.textContent = text;
  return;
}

// add the current output field plus the chosen operation to the equation
// also sums the equation, and updates the output field. accepts a button target (e.target)
function calculateEntry(t) {
  // handle equals
  if (t.id == 'btn-eq') {
    if (currentTotal === undefined && calcState === 'replace') {
      console.log('nope!');
      return;
    }
    console.log('getting total from equals');
    output.textContent = getTotal(currentTotal, currentArith, output.textContent);
    currentTotal = undefined;
    calcState = 'replace';
    dec = false;
    return;
  }
  // handle user selecting operation before any values are entered (initial/all clear states)
  if (currentTotal === undefined && calcState === 'replace' && output.textContent === '0') {
    console.log('cannot perform ' + t.textContent + ' operation: initial calculator state');
    return;
  }
  
  // handle valid calcState and valid user input, but no currentTotal
  if (currentTotal === undefined) {
    currentTotal = output.textContent;
    currentArith = t.textContent;
    dec = false;
    calcState = 'replace';
    console.log('line 132: ', currentTotal, currentArith);
    return;
  }
  
  // handle user entering multiple operations after one another
  if (calcState === 'replace' && (
    t.id === 'btn-div' ||
    t.id === 'btn-mult' ||
    t.id === 'btn-sub' ||
    t.id === 'btn-add' 
  )) {
    currentArith = t.textContent;
    dec = false;
    calcState = 'replace';
    console.log('line 152: ', currentTotal, currentArith);
    return;
  }
  
  if (currentTotal !== undefined && calcState === 'edit' && currentArith !== undefined) {
    currentTotal = getTotal(currentTotal, currentArith, output.textContent);
    output.textContent = currentTotal;
    currentArith = t.textContent;
    dec = 'false';
    calcState = 'replace';
    console.log('line 161: ', currentTotal, currentArith);
    return;
  }
}

function getTotal(a, operator, b){
  let total;
  if (a === undefined || operator === undefined || b === undefined) {
    total = a || b;
  }
  else {
    total = eval(a + operator + b);
  }
  return total;
}
              
            
!
999px

Console