Skip to content
Subscribe to RSS Find me on GitHub Follow me on Twitter

How to Build a Calculator With Javascript

How to Build a Calculator With JavaScript

Building a calculator is a rite of passage for new programmers. It’s a perfect project for absolute beginners because it combines simple HTML structure, basic CSS styling, and just enough JavaScript logic to feel rewarding without being overwhelming. By the end of this tutorial, you’ll have a working calculator that can add, subtract, multiply, and divide, plus you’ll understand exactly how each piece fits together.

We’ll create a calculator that runs entirely in your browser—no server needed, no complex setup. You’ll learn how to capture button clicks, build a mathematical expression as a string, evaluate it safely, and handle common errors like dividing by zero. Let’s dive in and build something useful while learning fundamental JavaScript concepts along the way.

What You’ll Need

Before we start, make sure you have:

Step-by-Step Guide

Step 1: Create the HTML Structure

First, let’s build the skeleton of our calculator. We’ll create a display area to show numbers and a grid of buttons for input. The key insight here is using data-key attributes on our buttons. These custom attributes let us store what each button represents (a number or an operator) separately from what it displays.

Create a new file called calculator.html and add this code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript Calculator</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="calculator">
        <input type="text" id="display" readonly />
        <div id="keys">
            <button data-key="7">7</button>
            <button data-key="8">8</button>
            <button data-key="9">9</button>
            <button data-key="/">÷</button>
            
            <button data-key="4">4</button>
            <button data-key="5">5</button>
            <button data-key="6">6</button>
            <button data-key="*">×</button>
            
            <button data-key="1">1</button>
            <button data-key="2">2</button>
            <button data-key="3">3</button>
            <button data-key="-">−</button>
            
            <button data-key="0">0</button>
            <button data-key=".">.</button>
            <button data-key="=">=</button>
            <button data-key="+">+</button>
            
            <button data-key="C" class="clear">Clear</button>
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>

What this code does:

Step 2: Add Basic CSS Styling

While not strictly required, styling makes your calculator usable and pleasant to look at. Create a style.css file in the same folder:

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.calculator {
    background: #2c3e50;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}

#display {
    width: 100%;
    height: 60px;
    font-size: 2em;
    text-align: right;
    padding: 10px;
    margin-bottom: 15px;
    border: none;
    border-radius: 5px;
    background: #34495e;
    color: white;
    box-sizing: border-box;
}

#keys {
    display: grid;
    grid-template-columns: repeat(4, 60px);
    gap: 10px;
}

button {
    height: 60px;
    font-size: 1.2em;
    border: none;
    border-radius: 5px;
    background: #3498db;
    color: white;
    cursor: pointer;
    transition: background 0.2s;
}

button:hover {
    background: #2980b9;
}

button.clear {
    grid-column: span 4;
    background: #e74c3c;
}

button.clear:hover {
    background: #c0392b;
}

What this code does:

Step 3: Listen for Button Clicks with JavaScript

Now for the magic! Create a script.js file. We’ll use event delegation, a powerful pattern where we listen for clicks on the entire button container rather than each individual button. This is more efficient and easier to maintain.

// Get references to our display and keys container
const display = document.querySelector('#display');
const keys = document.querySelector('#keys');

// Listen for clicks on the entire keys container
keys.addEventListener('click', (event) => {
    // event.target is the actual button that was clicked
    const key = event.target.getAttribute('data-key');
    
    // If clicked something without data-key (like the gap between buttons), exit
    if (!key) return;
    
    // If the equals button was clicked, evaluate the expression
    if (key === '=') {
        evaluate();
        return;
    }
    
    // If clear button was clicked, reset the display
    if (key === 'C') {
        display.value = '';
        return;
    }
    
    // Otherwise, add the key to the display
    display.value += key;
});

What this code does:

Step 4: Evaluate the Expression Safely

The final piece is the evaluate() function. Never use eval() in production code—it’s dangerous because it can execute arbitrary code. Instead, we use the Function constructor, which is safer for simple math.

function evaluate() {
    try {
        // Get the current expression from the display
        const expression = display.value;
        
        // Don't evaluate if display is empty
        if (!expression) return;
        
        // Check for division by zero
        if (expression.includes('/0')) {
            display.value = 'Error: Divide by zero';
            return;
        }
        
        // Create a function that returns the evaluated expression
        const result = Function(`'use strict'; return (${expression})`)();
        
        // Show the result, handling very large/small numbers
        display.value = Number.isFinite(result) ? result : 'Error';
        
    } catch (error) {
        // If anything goes wrong, show an error message
        display.value = 'Error';
        console.error('Calculation error:', error);
    }
}

What this code does:

Common Mistakes to Avoid

  1. Using eval() instead of Function(): The eval() function can execute any JavaScript code, making it a security risk. Malicious input could steal data or crash your page. Function() creates a sandboxed environment that’s much safer for calculations.

  2. Forgetting to validate input: Beginners often trust user input completely. Always check for division by zero, empty expressions, and invalid characters before evaluating.

  3. Not handling the case where nothing is clicked: The if (!key) return; guard clause is crucial. Without it, clicking the space between buttons would cause errors when trying to get data-key from non-button elements.

  4. Typos in selectors: A single wrong character in document.querySelector('#display') means JavaScript can’t find your element. The # is essential for IDs, and selectors are case-sensitive.

  5. Forgetting readonly on the display: If users can type directly into the display, they might enter invalid characters that break your calculator. Keep it read-only for consistency.

  6. Missing the C button logic: Many tutorials forget the clear functionality, forcing users to refresh the page. Always include a way to reset the calculator.

Troubleshooting Tips

Problem: Nothing happens when I click buttons

Problem: The display shows “undefined” or “[object Object]”

Problem: Calculations give wrong results

Problem: Division by zero shows “Infinity” instead of an error

Problem: Decimal numbers don’t work correctly

Problem: Keyboard doesn’t work

Practice Exercises to Level Up

  1. Add Keyboard Support: Extend your calculator to respond to keyboard input. Listen for keydown events and map number keys and operators to your existing functions. Don’t forget Enter for equals and Escape for clear!

  2. Prevent Invalid Input: Improve the calculator so users can’t enter two operators in a row (like 5++3) or multiple decimal points in one number. You’ll need to add validation logic before appending each key.

  3. Add Memory Functions: Implement MC (Memory Clear), MR (Memory Recall), M+ (Memory Add), and M- (Memory Subtract) buttons. Store the memory value in a variable and update the display accordingly.

  4. Create a Scientific Mode: Add buttons for square root, power, and percentage. You’ll need to enhance the evaluate() function to handle these operations safely.

  5. Build a History Feature: Store the last 10 calculations in an array and display them below the calculator. This teaches you about arrays, DOM manipulation, and persisting data.

Next Steps on Your Journey

Now that you have a working calculator, you have a solid foundation in DOM manipulation, event handling, and basic validation. Here are some paths forward:

Summary

You just built a fully functional calculator from scratch! You learned how to:

This project teaches you more than just calculator logic—it introduces patterns you’ll use in countless future projects. The event delegation pattern works for any interactive UI, the validation approach applies to all user input, and the safety-first mindset is essential for writing secure code.

Keep experimenting with the practice exercises, and don’t be afraid to break your calculator and fix it again. That’s how you learn. Happy coding!