Calculator
A cute, retro-themed calculator with full keyboard support. No frameworks, just vanilla JavaScript and good ol’ HTML and CSS.
Highlights
Perform basic maths (+ − × ÷)
Clear number on display with CE (Cancel Entry), or clear entire calculation with C (Clear)
Keyboard-friendly ⌨️
Built with
HTML and CSS
Vanilla JavaScript
Mobile-first workflow
Why I built this
This project is part of the Foundations Course in The Odin Project, one of the many online courses I took in my self-learning journey.
The goal is to apply everything we’ve learned about HTML, CSS, and JavaScript into a functional app. Hence no frameworks were used, only vanilla JS 🍦
Designing the calculator
I wanted my calculator to look unique, so I started by creating a mockup. To keep it simple I used Google Slides for my first iteration, but it turned out to be too blocky for my taste…
After getting some feedback from my girlfriend, I worked on a second iteration. I got inspired by the retro colors and unusual keypad layout of the Texas Instruments TI-150, so I tried to combine that with the simplicity of mini pocket calculators to achieve a better design.
I also switched to Figma, so I got to learn a bit about making reusable components like buttons and the calculator display.
Implementing the markup and logic
Since I got stuck for a while on the design phase, I “cheated” a little bit and skimmed Kevin Powell’s video on building a calculator - but only the HTML/CSS part! I got an overview of how to structure the markup, as well as the accessibility issues to consider while working on this project, such as:
- tab order for keyboard users
- whether to set the
cursor: pointer
on button hover
For the logic, I did some research on the internal workings of the calculator, which ultimately inspired my JavaScript implementation. I used a register
object to hold the state of the app, which gets updated as the user presses different buttons.
let register = {
a: 0,
b: 0,
operator: null,
answer: 0,
flag: null, // controls whether display will be cleared
}
This data structure also makes it easy to emulate the standard behavior of calculators where operations are evaluated one at a time. For example, if I press 4 + 5
and then press +
instead of =
, the operation is evaluated, displaying 9
. I can chain operations, so if I press 11 + 32 / 2 =
I get 26
.
One of my biggest takeaways for this project is learning how numbers are represented in JavaScript, and how to address this quirk.
Because JavaScript stores numbers as double-precision floating point numbers, operations with decimal numbers give inaccurate results:
0.1 + 0.2 // returns 0.30000000000000004
For this small project, I opted for a simple solution by using toPrecision()
method to minimize this effect. But for larger projects, I might consider importing a library such as big.js to solve arithmetic issues properly.