How to Build a Compound Interest Calculator?
1. Setting Up the HTML Structure
The HTML structure includes input fields for the principal amount, interest rate, time, and frequency of compounding, along with a button to calculate the interest.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Compound Interest Calculator</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css">
<link rel="stylesheet" href="styles.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--background-color: #f8f9fa;
--card-background: #ffffff;
--text-color: #212529;
--border-color: #a5dee0;
--hover-color: #e9ecef;
}
[data-theme="dark"] {
--primary-color: #0d6efd;
--secondary-color: #6c757d;
--background-color: #212529;
--card-background: #343a40;
--text-color: #f8f9fa;
--border-color: #495057;
--hover-color: #495057;
}
body {
background-color: var(--background-color);
color: var(--text-color);
transition: all 0.3s ease;
}
.card {
background-color: var(--card-background);
border-color: var(--border-color);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
}
.form-control, .form-select {
background-color: var(--card-background);
border-color: var(--border-color);
color: var(--text-color);
}
.form-control:focus, .form-select:focus {
background-color: var(--card-background);
border-color: var(--primary-color);
color: var(--text-color);
}
.btn-primary {
background-color: var(--primary-color);
border-color: var(--primary-color);
}
.btn-primary:hover {
filter: brightness(110%);
}
.theme-container {
position: fixed;
top: 20px;
right: 20px;
z-index: 1000;
}
.theme-switch {
position: relative;
width: 60px;
height: 30px;
}
.theme-switch input {
opacity: 0;
width: 0;
height: 0;
}
.switch {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .4s;
border-radius: 30px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 5px;
}
.switch:before {
content: "";
position: absolute;
height: 22px;
width: 22px;
left: 4px;
bottom: 4px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .switch:before {
transform: translateX(30px);
}
.light-icon, .dark-icon {
color: #fff;
font-size: 14px;
}
.results-container {
padding: 15px;
border-radius: 8px;
background-color: var(--card-background);
}
.result-item {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
padding: 10px;
border-bottom: 1px solid var(--border-color);
}
.result-item:last-child {
border-bottom: none;
}
.table {
color: var(--text-color);
}
.table-hover tbody tr:hover {
background-color: var(--hover-color);
}
@media (max-width: 768px) {
.container {
padding: 10px;
}
.card {
margin-bottom: 20px;
}
}
</style>
</head>
<body>
<div class="theme-container">
<div class="theme-switch">
<input type="checkbox" id="darkModeToggle">
<label for="darkModeToggle" class="switch">
<i class="bi bi-sun-fill light-icon"></i>
<i class="bi bi-moon-fill dark-icon"></i>
</label>
</div>
</div>
<div class="container mt-5">
<h1 class="text-center mb-4">Compound Interest Calculator</h1>
<div class="row">
<div class="col-md-6">
<div class="card calculator-card">
<div class="card-body">
<form id="calculatorForm">
<div class="mb-3">
<label for="currency" class="form-label">Currency</label>
<select class="form-select" id="currency">
<option value="USD">USD ($)</option>
<option value="EUR">EUR (โฌ)</option>
<option value="GBP">GBP (ยฃ)</option>
<option value="INR">INR (โน)</option>
</select>
</div>
<div class="mb-3">
<label for="principal" class="form-label">Principal Amount</label>
<input type="number" class="form-control" id="principal" required>
</div>
<div class="mb-3">
<label for="rate" class="form-label">Annual Interest Rate (%)</label>
<input type="number" class="form-control" id="rate" step="0.01" required>
</div>
<div class="mb-3">
<label for="time" class="form-label">Time Period (Years)</label>
<input type="number" class="form-control" id="time" required>
</div>
<div class="mb-3">
<label for="compounds" class="form-label">Compounding Frequency</label>
<select class="form-select" id="compounds">
<option value="1">Annually (1/year)</option>
<option value="2">Semi-annually (2/year)</option>
<option value="4">Quarterly (4/year)</option>
<option value="12">Monthly (12/year)</option>
<option value="365">Daily (365/year)</option>
</select>
</div>
<div class="d-grid gap-2">
<button type="submit" class="btn btn-primary">Calculate</button>
<button type="reset" class="btn btn-secondary">Reset</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card results-card">
<div class="card-body">
<h3>Results</h3>
<div id="results" class="results-container">
<div class="result-item">
<span>Total Amount:</span>
<span id="totalAmount">-</span>
</div>
<div class="result-item">
<span>Interest Earned:</span>
<span id="interestEarned">-</span>
</div>
</div>
<canvas id="growthChart" class="mt-3"></canvas>
<div class="mt-3">
<button id="downloadReport" class="btn btn-success">
<i class="bi bi-download"></i> Download Report
</button>
</div>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-body">
<h3>Yearly Breakdown</h3>
<div class="table-responsive">
<table class="table table-hover" id="yearlyBreakdown">
<thead>
<tr>
<th>Year</th>
<th>Principal</th>
<th>Interest</th>
<th>Total Amount</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="script.js"></script>
<script>
// Dark mode functionality
const darkModeToggle = document.getElementById('darkModeToggle');
const htmlElement = document.documentElement;
darkModeToggle.addEventListener('change', () => {
if (darkModeToggle.checked) {
htmlElement.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark');
} else {
htmlElement.setAttribute('data-theme', 'light');
localStorage.setItem('theme', 'light');
}
});
// Load saved theme preference
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
htmlElement.setAttribute('data-theme', savedTheme);
darkModeToggle.checked = savedTheme === 'dark';
}
// Calculator functionality
const calculatorForm = document.getElementById('calculatorForm');
const currencySelect = document.getElementById('currency');
let growthChart = null;
calculatorForm.addEventListener('submit', (e) => {
e.preventDefault();
calculateResults();
});
function calculateResults() {
const principal = parseFloat(document.getElementById('principal').value);
const rate = parseFloat(document.getElementById('rate').value) / 100;
const time = parseFloat(document.getElementById('time').value);
const compounds = parseFloat(document.getElementById('compounds').value);
const currency = currencySelect.value;
// Calculate total amount using compound interest formula
const amount = principal * Math.pow(1 + (rate / compounds), compounds * time);
const interest = amount - principal;
// Format currency
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currency
});
// Display results
document.getElementById('totalAmount').textContent = formatter.format(amount);
document.getElementById('interestEarned').textContent = formatter.format(interest);
// Generate yearly breakdown
generateYearlyBreakdown(principal, rate, time, compounds, currency);
// Update chart
updateChart(principal, rate, time, compounds);
}
function generateYearlyBreakdown(principal, rate, time, compounds, currency) {
const tbody = document.querySelector('#yearlyBreakdown tbody');
tbody.innerHTML = '';
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currency
});
for (let year = 1; year <= time; year++) {
const amount = principal * Math.pow(1 + (rate / compounds), compounds * year);
const yearlyInterest = amount - principal;
const row = document.createElement('tr');
row.innerHTML = `
<td>${year}</td>
<td>${formatter.format(principal)}</td>
<td>${formatter.format(yearlyInterest)}</td>
<td>${formatter.format(amount)}</td>
`;
tbody.appendChild(row);
}
}
function updateChart(principal, rate, time, compounds) {
const ctx = document.getElementById('growthChart').getContext('2d');
// Generate data points
const labels = [];
const principalData = [];
const totalData = [];
for (let year = 0; year <= time; year++) {
labels.push(`Year ${year}`);
principalData.push(principal);
const amount = principal * Math.pow(1 + (rate / compounds), compounds * year);
totalData.push(amount);
}
// Destroy existing chart if it exists
if (growthChart) {
growthChart.destroy();
}
// Create new chart
growthChart = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Principal Amount',
data: principalData,
borderColor: '#6c757d',
backgroundColor: 'rgba(108, 117, 125, 0.1)',
fill: true
},
{
label: 'Total Amount',
data: totalData,
borderColor: '#0d6efd',
backgroundColor: 'rgba(13, 110, 253, 0.1)',
fill: true
}]
},
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Investment Growth Over Time'
},
tooltip: {
mode: 'index',
intersect: false
}
},
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currencySelect.value,
minimumFractionDigits: 0,
maximumFractionDigits: 0
}).format(value);
}
}
}
}
}
});
}
// Download report functionality
document.getElementById('downloadReport').addEventListener('click', () => {
const principal = parseFloat(document.getElementById('principal').value);
const rate = parseFloat(document.getElementById('rate').value);
const time = parseFloat(document.getElementById('time').value);
const compounds = parseFloat(document.getElementById('compounds').value);
const currency = currencySelect.value;
const amount = principal * Math.pow(1 + (rate / 100 / compounds), compounds * time);
const interest = amount - principal;
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currency
});
const report = `Compound Interest Calculator Report
Generated on: ${new Date().toLocaleDateString()}
Investment Details:
------------------
Principal Amount: ${formatter.format(principal)}
Annual Interest Rate: ${rate}%
Time Period: ${time} years
Compounding Frequency: ${compounds} times per year
Results:
--------
Total Amount: ${formatter.format(amount)}
Interest Earned: ${formatter.format(interest)}
`;
const blob = new Blob([report], { type: 'text/plain' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'compound-interest-report.txt';
a.click();
window.URL.revokeObjectURL(url);
});
// Add hover effect to input fields
const inputFields = document.querySelectorAll('.form-control, .form-select');
inputFields.forEach(field => {
field.addEventListener('mouseover', () => {
field.style.borderColor = getComputedStyle(document.documentElement).getPropertyValue('--primary-color');
});
field.addEventListener('mouseout', () => {
if (document.activeElement !== field) {
field.style.borderColor = getComputedStyle(document.documentElement).getPropertyValue('--border-color');
}
});
});
</script>
</body>
</html>
Best Compound Interest Calculator
- Compound Interest Calculator HTML CSS JS
- Finance Calculator Using JavaScript
- Investment Growth Calculator Online
- Create a Compound Interest Calculator in JavaScript
- How to Calculate Compound Interest with Code