Buenos días y buenas tardes, hoy lo que vas a hacer es dedicarte a crear una calculadora desde cero utilizando exclusivamente HTML, CSS y Javascript.

Te recuerdo que puedes aprender las bases en el curso gratis de desarrollo web, pero bueno... seguramente ya sepas todo eso, así que puedes seguir leyendo.

La idea no es reinventar el mundo de las calculadoras, sino aprender practicando. Porque de nada te sirve estar toda la vida aprendiendo las bases si nunca las usas.

Así que vamos al lío.

¿Cómo lo hago?

Puedes descargar el código aquí.

Puedes ver la explicación en vídeo aquí.

Parte 1. La interfaz.

La interfaz es la parte que ve el usuario que usa un producto y lo que le permite interactuar con el asunto. En este caso es la parte que muestra los botoncitos, la pantalla con el resultado, etc. Y todo eso hay que conseguir hacerlo de una manera medianamente elegante.

Y esta parte realmente es muy fácil.

Tendrás que usar HTML y CSS para crear algo decente, donde el usuario final sepa que lo que está usando es una calculadora y no una tostadora. En este caso crearás algo así:

Pero bueno, eso es relativamente simple porque no deja de ser un contenedor con cositas dentro y ya. De todas formas no te agobies, ahora lo vas a ver.

El HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Calculadora</title>
    <link href="https://fonts.googleapis.com/css2?family=Fraunces&display=swap" rel="stylesheet">
    <link href="index.css" rel="stylesheet" />
    <script src="Display.js" type="text/javascript"></script>
    <script src="Calculadora.js" type="text/javascript"></script>
    <script src="index.js" type="text/javascript" defer></script>
</head>
<body>
    <div class="container">
        <div class="calculadora">
            <div class="display">
                <div id="valor-anterior"></div>
                <div id="valor-actual"></div>
            </div>
            <button class="col-2" onclick="display.borrarTodo()">C</button>
            <button onclick="display.borrar()">&larr;</button>
            <button class="operador" value="dividir">%</button>
            <button class="numero">7</button>
            <button class="numero">8</button>
            <button class="numero">9</button>
            <button class="operador" value="multiplicar">X</button>
            <button class="numero">4</button>
            <button class="numero">5</button>
            <button class="numero">6</button>
            <button class="operador" value="restar">-</button>
            <button class="numero">1</button>
            <button class="numero">2</button>
            <button class="numero">3</button>
            <button class="operador" value="sumar">+</button>
            <button class="col-2 numero">0</button>
            <button class="numero">.</button>
            <button class="operador" value="igual">=</button>
        </div>
    </div>
</body>
</html>

Fíjate que en el head estamos llamando una hoja de estilos CSS.

El CSS que vamos a crear es el siguiente:

* {
    font-family: 'Fraunces', serif;
    color: #fff;
}

body {
    margin: 0;
    background-color: #224870;
}

.container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

.calculadora {
    display: grid;
    grid-template-columns: repeat(4, 75px);
    grid-template-rows: 160px repeat(5, 75px);
    background-color: #00916e;
    padding: 15px;
    border-radius: 32px;
    box-shadow: 15px 10px 0px 5px #00000033;
}

button {
    cursor: pointer;
    margin: 5px;
    padding: 0;
    border-radius: 32px;
    font-size: 1.5em;
    border: none;
    background-color: #00916e;
    box-shadow: 5px 5px 10px -3px #00000040, -5px -5px 15px 3px #00ffc11f;
}

button:active {
    background-color: #006f54;
}

button:focus {
    outline: none;
}

.col-2 {
    grid-column: span 2;
}

.display {
    grid-column: 1 / -1;
    padding: 16px;
    display: flex;
    margin: 10px 10px 20px;
    flex-direction: column;
    align-items: flex-end;
    background-color: #363636;
    border-radius: 32px;
    text-align: right;
    justify-content: space-between;
    word-break: break-all;
    box-shadow: 0px 0px 0px 10px #00000033;
}

#valor-actual {
    font-size: 1.5em;
}

#valor-anterior {
    font-size: 2em;
}

Parte 2. La lógica.

Si no tienes ganas de copiar/pegar lo que puedes hacer es mirarte este impresionante vídeo de Programación Accesible y así aprendes a hacerlo paso a paso. De hecho es lo que yo te recomiendo que hagas. Pero bueno, tú decides:

La lógica es el cerebro del programa, la parte que se encarga de hacer que el asunto cobre vida y funcione como tiene que funcionar.

Esa parte la crearás en este caso utilizando Javascript.

Ya viste que nuestro HTML está llamando varios archivos JS en el head, fíjate bien:

<script src="Display.js" type="text/javascript"></script>
<script src="Calculadora.js" type="text/javascript"></script>
<script src="index.js" type="text/javascript" defer></script>

Lo que pondremos en cada uno de esos archivos es lo siguiente.

Para el Display.js:

class Display {
    constructor(displayValorAnterior, displayValorActual) {
        this.displayValorActual = displayValorActual;
        this.displayValorAnterior = displayValorAnterior;
        this.calculador = new Calculadora();
        this.tipoOperacion = undefined;
        this.valorActual = '';
        this.valorAnterior = '';
        this.signos = {
            sumar: '+',
            dividir: '%',
            multiplicar: 'x',
            restar: '-', 
        }
    }

    borrar() {
        this.valorActual = this.valorActual.toString().slice(0,-1);
        this.imprimirValores();
    }

    borrarTodo() {
        this.valorActual = '';
        this.valorAnterior = '';
        this.tipoOperacion = undefined;
        this.imprimirValores();
    }

    computar(tipo) {
        this.tipoOperacion !== 'igual' && this.calcular();
        this.tipoOperacion = tipo;
        this.valorAnterior = this.valorActual || this.valorAnterior;
        this.valorActual = '';
        this.imprimirValores();
    }

    agregarNumero(numero) {
        if(numero === '.' && this.valorActual.includes('.')) return
        this.valorActual = this.valorActual.toString() + numero.toString();
        this.imprimirValores();
    }

    imprimirValores() {
        this.displayValorActual.textContent = this.valorActual;
        this.displayValorAnterior.textContent = `${this.valorAnterior} ${this.signos[this.tipoOperacion] || ''}`;
    }

    calcular() {
        const valorAnterior = parseFloat(this.valorAnterior);
        const valorActual = parseFloat(this.valorActual);

        if( isNaN(valorActual)  || isNaN(valorAnterior) ) return
        this.valorActual = this.calculador[this.tipoOperacion](valorAnterior, valorActual);
    }
}

Para Calculadora.js:

class Calculadora {
    sumar(num1, num2) {
        return num1 + num2;
    }

    restar(num1, num2) {
        return num1 - num2;
    }

    dividir(num1, num2) {
        return num1 / num2;
    }

    multiplicar(num1, num2) {
        return num1 * num2;
    }
} 

Para index.js:

const displayValorAnterior = document.getElementById('valor-anterior');
const displayValorActual = document.getElementById('valor-actual');
const botonesNumeros = document.querySelectorAll('.numero');
const botonesOperadores = document.querySelectorAll('.operador');

const display = new Display(displayValorAnterior, displayValorActual);

botonesNumeros.forEach(boton => {
    boton.addEventListener('click', () => display.agregarNumero(boton.innerHTML));
});

botonesOperadores.forEach(boton => {
    boton.addEventListener('click', () => display.computar(boton.value))
});

Eso es todo la verdad.

Es un proyecto muy sencillo. Yo lo que haría en tu lugar es añadirle funciones extra, intentar cambiar un poco el estilo. Tú sabes... tienes que soltar las riendas de tu creatividad y dejar volar el caballo que llevas dentro.