<h1>
  CSS Calculator
</h1>
<h2>
  How this Calculator Works
</h2>
<p>
  The goal of this calculator is to utilize the Custom Properties (CSS Variables) and <code>calc()</code> CSS function to run the calculation inputs. Since CSS is a one-way, reactive styling language, it isn’t aware of changes made to interactive HTML elements, in particular changes to input values. Neither can CSS capture and manipulate data. This is an area where Javascript does well, capturing an manipulating DOM elements. <a href="https://codepen.io/zastrow/pen/RwwqmBL">See the code</a> of this page to see how the calculator works.
</p>

<form>
  <input class="number-1" type="number" placeholder="0"/>
  <input class="number-2" type="number" placeholder="0"/>
  <ul>
    <li>
      <input type="radio" value="add" name="operator" id="add" checked />
      <label for="add"><span>&plus;</span></label>
    </li>
    <li>
      <input type="radio" value="subtract" name="operator" id="subtract" />
      <label for="subtract"><span>&minus;</span></label>
    </li>
    <li>
      <input type="radio" value="multiply" name="operator" id="multiply" />
      <label for="multiply"><span>&times;</span></label>
    </li>
    <li>
      <input type="radio" value="divide" name="operator" id="divide" />
      <label for="divide"><span>&divide;</span></label>
    </li>
  </ul>
</form>
<div class="result" style="--maths:var(--add);right: calc(var(--maths) * 1px)"></div>
// Calculator Engine
html {
  --val1: 0;
  --val2: 0;
  --add: calc(var(--val1) + var(--val2));
  --subtract: calc(var(--val1) - var(--val2));
  --multiply: calc(var(--val1) * var(--val2));
  --divide: calc(var(--val1) / var(--val2));
}

$bp: 40rem;

// Visual Style
body {
  font-family: sytem-ui, sans-serif;
  line-height: 1.5;
  margin: 1.5rem auto;
  width: calc(100% - 2rem);
  max-width: 60rem;
  
  @media (min-width: $bp) {
    margin: 3rem auto;
    width: calc(100% - 6rem);
  }
}

form {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  display: flex;
  flex-direction: column;
  border-top: 1px solid #ddd;
  
  @media (min-width: $bp) {
    flex-direction: row;
    margin-top: 3rem;
    padding-top: 3rem;
  }
}

input {
  appearance: none;
  border: none;
  font-family: inherit;
  font-size: inherit;
  background-color: transparent;
}

[type="number"] {
  text-align: right;
  border-bottom: 1px solid #333;
  flex: 1 1 auto;
  width: 100%;
  padding: 0;
  font-size: 2rem;
  color: #333;
}

[type="number"]::-webkit-outer-spin-button,
[type="number"]::-webkit-inner-spin-button {
  appearance: none;
}

[type="number"]::placeholder {
  color: #333;
}

[type="number"]:focus {
  outline: none;
  border-color: dodgerblue;
  box-shadow: 0 1px dodgerblue;
}

[type="radio"] {
  display: none;
}

label {
  font-size: 2rem;
  border: 1px #ddd solid;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 3rem;
  width: 3rem;
  border-radius: 0.5rem;
  color: #333;
  font-weight: 100;
}

[type="radio"]:checked + label {
  background-color: dodgerblue;
  color: white;
  border-color: darken(dodgerblue, 10%);
}

.number-1 {
  order: 1;
}

.number-2 {
  order: 3;
}

ul {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  margin: 2rem auto;
  padding: 0;
  order: 2;

  @media (min-width: $bp) {
    margin: auto 2rem;
    flex-wrap: nowrap;
  }
}

li + li {
  margin-left: 1rem;
}

li span {
  display: block;
  margin-top: -0.25rem;
}

.result {
  margin-top: 3rem;
  font-size: 4rem;
  font-weight: 200;
  text-align: center;
  order: 4;
  flex-basis: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch; 
}
const inputs = document.querySelectorAll('[type="number"]');
const ops = document.querySelectorAll('[name="operator"] + label');
const result = document.querySelector('.result');
const body = document.querySelector('html');

let maths;
let operator;
let prop1;
let prop2;
let resultStyles;
let resultContainer;

let timeout;
const delay = 100;

const calculate = () => {
  prop1 = document.querySelector('.number-1').value;
  prop2 = document.querySelector('.number-2').value;
  operator = document.querySelector('[name="operator"]:checked').value;
  
  if (prop1 === '') { prop1 = 0;}
  if (prop2 === '') { prop2 = 0;}
    
  body.style.setProperty('--val1', prop1 );
  body.style.setProperty('--val2', prop2 );
  result.style.setProperty('--maths', `var(--${operator})` );
  
  resultStyles = window.getComputedStyle(result);
  resultContainer = resultStyles.getPropertyValue('right');
  resultValue = resultContainer.toString().replace('px','');
  
  if (resultValue === 'auto') {
    resultValue = '∞';
  }

  result.innerText = resultValue;
};

calculate();

[...ops].forEach((op) => {
  op.addEventListener('click', () => {
    clearTimeout(timeout);
    timeout = setTimeout(calculate, delay);
    timeout;
  });
});

[...inputs].forEach((input) => {
  input.addEventListener('keydown', (e) => {
    const key = e.keyCode ? e.keyCode : e.which;
    if (!( [8, 9, 13, 27, 46, 110, 190].indexOf(key) !== -1 ||
      (key == 65 && ( e.ctrlKey || e.metaKey  ) ) || 
      (key >= 35 && key <= 40) ||
      (key >= 48 && key <= 57 && !(e.shiftKey || e.altKey)) ||
      (key >= 96 && key <= 105)
    )) e.preventDefault();
    
    clearTimeout(timeout);
    timeout = setTimeout(calculate, delay);
    timeout;
  });
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.