In today’s tech-driven world, unit conversion is a common task for developers, students, and professionals alike. Whether you're converting lengths, weights, temperatures, or volumes, having a reliable tool can save time and effort. In this blog, we’ll walk through the process of building a Unit Converter with History Log using HTML, CSS, and JavaScript. This app not only converts units but also saves your recent conversions for quick reference.
You can check out the live app here: Unit Converter with History Log.
Let’s dive into the details!
Table of Contents
- Introduction to the App
- HTML Structure
- Styling with CSS
- JavaScript Logic
- Adding the History Log Feature
- Conclusion
1. Introduction to the App
The Unit Converter with History Log is a simple yet powerful web application that allows users to:
- Convert units across different categories like length, weight, temperature, and volume.
- Save and view the last 10 conversions in a history log.
- Clear the history log with a single click.
The app is designed to be user-friendly, responsive, and visually appealing. It uses local storage to save the conversion history, ensuring that the data persists even after the page is refreshed.
2. HTML Structure
The HTML file (index.html
) forms the backbone of the app. It defines the structure and layout of the unit converter. Here’s a breakdown of the key components:
Key Elements:
- Mode Selector: A dropdown to switch between different unit categories (length, weight, temperature, volume).
- Input and Result Fields: Two input fields for the user to enter a value and view the converted result.
- Unit Selectors: Dropdowns to select the "from" and "to" units.
- History Log: A section to display the recent conversions.
- Clear History Button: A button to clear the history log.
Here’s the HTML code:
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Unit Converter</title>
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css2?family=Segoe+UI:wght@400;600&display=swap" rel="stylesheet">
</head>
<body>
<div class="calculator">
<div class="header">
<select id="modeSelect">
<option value="length">Length</option>
<option value="weight">Weight and Mass</option>
<option value="temperature">Temperature</option>
<option value="volume">Volume</option>
</select>
</div>
<div class="display">
<input type="number" id="inputValue" placeholder="0">
<select id="fromUnit"></select>
<div class="result-container">
<input type="number" id="resultValue" readonly>
<select id="toUnit"></select>
</div>
</div>
<div class="history">
<div class="history-header">History</div>
<div class="history-list" id="historyList"></div>
<button id="clearHistory" class="clear-btn">Clear history</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
3. Styling with CSS
The CSS file (styles.css
) is responsible for the app’s visual design. It ensures the app looks clean and modern, with a focus on usability.
Key Features:
- Responsive Layout: The app is centered on the page and works well on both desktop and mobile devices.
- Dropdown Styling: Custom styling for the dropdown menus to make them visually appealing.
- History Log Design: A scrollable history section with a clean, minimalistic design.
Here’s the CSS code:
/* styles.css */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', sans-serif;
}
body {
background: #f3f3f3;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.calculator {
width: 360px;
background: white;
border: 1px solid #e0e0e0;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.header {
padding: 10px;
background: #fafafa;
border-bottom: 1px solid #e0e0e0;
}
#modeSelect {
width: 100%;
padding: 8px;
border: none;
font-size: 16px;
background: transparent;
cursor: pointer;
}
.display {
padding: 20px;
}
#inputValue, #resultValue {
width: 100%;
padding: 10px;
border: 1px solid #e0e0e0;
border-radius: 4px;
font-size: 24px;
margin-bottom: 10px;
background: white;
}
#resultValue {
background: #f9f9f9;
}
select {
width: 100%;
padding: 10px;
border: 1px solid #e0e0e0;
border-radius: 4px;
font-size: 16px;
background: white;
cursor: pointer;
appearance: none;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24"><path fill="gray" d="M7 10l5 5 5-5z"/></svg>');
background-repeat: no-repeat;
background-position: right 10px center;
}
.history {
padding: 15px;
border-top: 1px solid #e0e0e0;
}
.history-header {
font-size: 14px;
color: #666;
margin-bottom: 10px;
}
.history-list {
max-height: 200px;
overflow-y: auto;
margin-bottom: 10px;
}
.history-item {
padding: 8px;
font-size: 14px;
border-bottom: 1px solid #f0f0f0;
color: #333;
}
.history-item span {
color: #666;
font-size: 12px;
}
.clear-btn {
width: 100%;
padding: 8px;
border: none;
border-radius: 4px;
background: #f0f0f0;
color: #333;
font-size: 14px;
cursor: pointer;
transition: background 0.2s;
}
.clear-btn:hover {
background: #e0e0e0;
}
4. JavaScript Logic
The JavaScript file (script.js
) handles the app’s functionality. It includes:
- Unit Conversion Logic: Converts units based on the selected category and units.
- History Log Management: Saves and displays the last 10 conversions.
- Event Listeners: Updates the app dynamically based on user input.
Here’s the JavaScript code:
// script.js
document.addEventListener('DOMContentLoaded', () => {
const units = {
length: {
'Meter': 1,
'Kilometer': 1000,
'Centimeter': 0.01,
'Millimeter': 0.001,
'Mile': 1609.34,
'Yard': 0.9144,
'Foot': 0.3048,
'Inch': 0.0254
},
'weight': {
'Kilogram': 1,
'Gram': 0.001,
'Milligram': 0.000001,
'Pound': 0.453592,
'Ounce': 0.0283495
},
temperature: {
'Celsius': 'c',
'Fahrenheit': 'f',
'Kelvin': 'k'
},
volume: {
'Liter': 1,
'Milliliter': 0.001,
'Gallon (US)': 3.78541,
'Quart (US)': 0.946353,
'Pint (US)': 0.473176,
'Cup (US)': 0.24
}
};
const modeSelect = document.getElementById('modeSelect');
const fromUnitSelect = document.getElementById('fromUnit');
const toUnitSelect = document.getElementById('toUnit');
const inputValue = document.getElementById('inputValue');
const resultValue = document.getElementById('resultValue');
const historyList = document.getElementById('historyList');
const clearHistoryBtn = document.getElementById('clearHistory');
let history = JSON.parse(localStorage.getItem('conversionHistory')) || [];
function populateUnits(category) {
const unitOptions = units[category];
fromUnitSelect.innerHTML = '';
toUnitSelect.innerHTML = '';
for (let unit in unitOptions) {
const option1 = document.createElement('option');
const option2 = document.createElement('option');
option1.value = unit;
option2.value = unit;
option1.textContent = unit;
option2.textContent = unit;
fromUnitSelect.appendChild(option1);
toUnitSelect.appendChild(option2);
}
// Set default selections like Windows Calculator
fromUnitSelect.selectedIndex = 0;
toUnitSelect.selectedIndex = 1;
}
function convertTemperature(value, fromUnit, toUnit) {
let celsius;
switch(fromUnit) {
case 'Celsius': celsius = value; break;
case 'Fahrenheit': celsius = (value - 32) * 5/9; break;
case 'Kelvin': celsius = value - 273.15; break;
}
switch(toUnit) {
case 'Celsius': return celsius;
case 'Fahrenheit': return (celsius * 9/5) + 32;
case 'Kelvin': return celsius + 273.15;
}
}
function convert() {
const category = modeSelect.value;
const fromUnit = fromUnitSelect.value;
const toUnit = toUnitSelect.value;
const value = parseFloat(inputValue.value) || 0;
let result;
if (category === 'temperature') {
result = convertTemperature(value, fromUnit, toUnit);
} else {
const fromFactor = units[category][fromUnit];
const toFactor = units[category][toUnit];
result = (value * fromFactor) / toFactor;
}
resultValue.value = result.toFixed(6).replace(/\.?0+$/, '');
if (value !== 0) {
const conversion = {
date: new Date().toLocaleTimeString(),
value: value,
fromUnit: fromUnit,
toUnit: toUnit,
result: result.toFixed(6).replace(/\.?0+$/, ''),
category: category
};
history.unshift(conversion);
if (history.length > 10) history.pop();
localStorage.setItem('conversionHistory', JSON.stringify(history));
updateHistory();
}
}
function updateHistory() {
historyList.innerHTML = '';
history.forEach(item => {
const div = document.createElement('div');
div.className = 'history-item';
div.innerHTML = `${item.value} ${item.fromUnit} = ${item.result} ${item.toUnit}<br><span>${item.date}</span>`;
historyList.appendChild(div);
});
}
function clearHistory() {
history = [];
localStorage.removeItem('conversionHistory');
updateHistory();
}
modeSelect.addEventListener('change', () => {
populateUnits(modeSelect.value);
convert();
});
fromUnitSelect.addEventListener('change', convert);
toUnitSelect.addEventListener('change', convert);
inputValue.addEventListener('input', convert);
clearHistoryBtn.addEventListener('click', clearHistory);
// Initial setup
populateUnits(modeSelect.value);
updateHistory();
});
5. Adding the History Log Feature
The history log is a standout feature of this app. It uses local storage to save conversions, ensuring the data persists even after the page is refreshed. Here’s how it works:
- Saving Conversions: Every time a conversion is performed, the details (value, units, result, and timestamp) are saved to local storage.
- Displaying History: The history log displays the last 10 conversions in reverse chronological order.
- Clearing History: Users can clear the history log with a single click.
6. Conclusion
Building a Unit Converter with History Log is a great way to practice your HTML, CSS, and JavaScript skills. This app is not only functional but also showcases the power of local storage and dynamic DOM manipulation.
Feel free to explore the live app here and use the code provided to build your own version. Happy coding!
Top comments (0)