DEV Community

Mohamud Dahir Abdi
Mohamud Dahir Abdi

Posted on

Build a Sleek Calculator with Dark Mode - Interactive Guide

Let's create a modern calculator that's both beautiful and functional, with all the code explained in an engaging way. By the end, you'll have a calculator that works on all devices and even supports keyboard input!

🎨 The Design Vision

We're building a calculator with:

  • A dark theme (with easy light mode potential)
  • Full calculation history
  • Keyboard support (type directly!)
  • Responsive design (works on phones too)
  • Smooth animations

Calculator Preview


πŸ› οΈ Let's Build It!

1. The HTML Foundation

Our calculator needs:

  • A display area (for current input and history)
  • Number buttons (0-9)
  • Operator buttons (+, -, *, /)
  • Special functions (AC, DEL, %)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Neon Calculator</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="calculator"> <!-- Display Area --> <div class="display"> <div class="history"></div> <input type="text" id="output" readonly> </div> <!-- Buttons Grid --> <div class="buttons"> <button data-value="AC" class="ac">AC</button> <button data-value="DEL" class="del">DEL</button> <button data-value="%" class="operator">%</button> <button data-value="/" class="operator">Γ·</button> <button data-value="7" class="number">7</button> <button data-value="8" class="number">8</button> <button data-value="9" class="number">9</button> <button data-value="*" class="operator">Γ—</button> <button data-value="4" class="number">4</button> <button data-value="5" class="number">5</button> <button data-value="6" class="number">6</button> <button data-value="-" class="operator">βˆ’</button> <button data-value="1" class="number">1</button> <button data-value="2" class="number">2</button> <button data-value="3" class="number">3</button> <button data-value="+" class="operator">+</button> <button data-value="0" class="number zero">0</button> <button data-value="." class="number">.</button> <button data-value="=" class="equals">=</button> </div> </div> <script src="script.js"></script> </body> </html> 
Enter fullscreen mode Exit fullscreen mode

Key Points:

  • data-value attributes store what each button does
  • Special classes like operator and number help with styling
  • The zero button is wider (we'll style it that way)

2. Stylish CSS Makeover

Let's give our calculator some personality with:

  • A sleek dark theme
  • Glowing operator buttons
  • Smooth button presses
:root { --bg-color: #1e1e2e; --display-bg: #2a2a3a; --button-bg: #3a3a4a; --operator-color: #ff9500; --equals-color: #ff2d75; --ac-del-color: #a5a5a5; --text-color: #ffffff; } body { background: var(--bg-color); display: flex; justify-content: center; align-items: center; min-height: 100vh; font-family: 'Segoe UI', sans-serif; transition: all 0.3s ease; } .calculator { width: 320px; background: var(--bg-color); border-radius: 20px; padding: 20px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); } .display { background: var(--display-bg); border-radius: 10px; padding: 20px; margin-bottom: 20px; text-align: right; } .history { color: rgba(255, 255, 255, 0.5); height: 20px; font-size: 14px; } #output { width: 100%; border: none; background: transparent; color: var(--text-color); font-size: 36px; text-align: right; outline: none; } .buttons { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; } button { height: 60px; border: none; border-radius: 10px; font-size: 24px; cursor: pointer; transition: all 0.1s; color: var(--text-color); background: var(--button-bg); } button:active { transform: scale(0.95); } .number { background: var(--button-bg); } .operator { background: var(--operator-color); } .equals { background: var(--equals-color); } .ac, .del { background: var(--ac-del-color); } .zero { grid-column: span 2; } /* Glow effect on hover */ .operator:hover, .equals:hover { filter: brightness(1.2); box-shadow: 0 0 10px currentColor; } 
Enter fullscreen mode Exit fullscreen mode

Design Highlights:

  • CSS variables make theme changes easy
  • Grid layout for perfect button alignment
  • Interactive button effects (press and glow)
  • The zero button spans two columns

3. JavaScript Magic

Now for the brains! Our calculator needs to:

  • Handle button clicks
  • Manage calculations
  • Support keyboard input
  • Show history
const output = document.getElementById('output'); const buttons = document.querySelectorAll('button'); const historyDisplay = document.querySelector('.history'); let currentInput = '0'; let calculationHistory = ''; // Initialize display output.value = currentInput; // Update the calculator display function updateDisplay() { output.value = currentInput; // Adjust font size for long numbers output.style.fontSize = currentInput.length > 12 ? '24px' : '36px'; } // Check if input is valid function isValidInput(value) { // Prevent multiple decimals if (value === '.' && currentInput.includes('.') && !'+-*/'.includes(currentInput.slice(-1))) { return false; } // Prevent consecutive operators if ('+-*/'.includes(value) && '+-*/'.includes(currentInput.slice(-1))) { return false; } return true; } // Perform the calculation function calculate() { try { // Replace Γ— and Γ· with * and / let expression = currentInput.replace(/Γ—/g, '*').replace(/Γ·/g, '/'); // Use Function constructor instead of eval const result = new Function(`return ${expression}`)(); // Format the result return Number.isInteger(result) ? result.toString() : result.toFixed(4); } catch { return 'Error'; } } // Handle button clicks buttons.forEach(button => { button.addEventListener('click', () => { const value = button.dataset.value; if (value === 'AC') { // Clear everything currentInput = '0'; calculationHistory = ''; historyDisplay.textContent = ''; } else if (value === 'DEL') { // Backspace functionality currentInput = currentInput.length > 1 ? currentInput.slice(0, -1) : '0'; } else if (value === '=') { // Calculate and show history calculationHistory = currentInput; historyDisplay.textContent = calculationHistory + ' ='; currentInput = calculate(); } else { // Add numbers or operators if (!isValidInput(value)) return; if (currentInput === '0' && !'+-*/'.includes(value)) { currentInput = value; } else { currentInput += value; } } updateDisplay(); }); }); // Keyboard support document.addEventListener('keydown', (e) => { const keyMap = { 'Enter': '=', 'Backspace': 'DEL', 'Escape': 'AC', '*': '*', '+': '+', '-': '-', '/': '/', '%': '%', '.': '.' }; if (keyMap[e.key]) { document.querySelector(`button[data-value="${keyMap[e.key]}"]`).click(); } else if (!isNaN(e.key) || e.key === '0') { document.querySelector(`button[data-value="${e.key}"]`).click(); } }); 
Enter fullscreen mode Exit fullscreen mode

Key Features:

  • Safe calculations using Function instead of eval
  • Input validation prevents errors
  • Keyboard support for quick typing
  • History tracking shows your previous calculation
  • Error handling for invalid expressions

πŸš€ Taking It Further

Want to enhance your calculator? Try these ideas:

  1. Add Light/Dark Mode Toggle
const themeToggle = document.createElement('button'); themeToggle.textContent = 'πŸŒ™'; document.body.prepend(themeToggle); themeToggle.addEventListener('click', () => { document.body.classList.toggle('light-mode'); }); 
Enter fullscreen mode Exit fullscreen mode

Add to CSS:

.light-mode { --bg-color: #f0f2f5; --display-bg: #ffffff; --button-bg: #e0e0e0; --text-color: #000000; } 
Enter fullscreen mode Exit fullscreen mode
  1. Add Scientific Functions
<button data-value="Math.sqrt(">√</button> <button data-value="Math.pow(,2)">x²</button> 
Enter fullscreen mode Exit fullscreen mode
  1. Add Memory Functions
let memory = 0; function memoryAdd() { memory += parseFloat(currentInput); } 
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ Why This Calculator Rocks

  • No eval() - Safer calculations using Function constructor
  • Great UX - Visual feedback on button presses
  • Responsive - Works on any device
  • Accessible - Works with keyboard and screen readers
  • Easy to Extend - Add more features easily

Now you've got a calculator that looks great and works even better! What feature will you add next? Maybe voice control or calculation graphs? The possibilities are endless!

Top comments (0)