Freedom Sale
Independence Day Special — Unlock the AI Path 70% off our most popular AI course · Limited time offer
--Days
--Hrs
--Min
--Sec
Claim Your Discount
✦ Beginner ⏱ 30 min

📐 Build a Unit Converter Web App

🎯 What You'll Build

A multi-category unit converter with instant live conversion for length, weight, temperature, and speed — with a swap button to reverse direction.

📋 What You'll Need

1

Define unit conversion rules

Store each category as an object mapping unit names to their conversion factor relative to a base unit.

// All values relative to the base unit (first in each category)
const CATEGORIES = {
  Length: {
    base: 'meters',
    units: {
      meters: 1, kilometers: 0.001, centimeters: 100, millimeters: 1000,
      miles: 0.000621371, yards: 1.09361, feet: 3.28084, inches: 39.3701,
    },
  },
  Weight: {
    base: 'kilograms',
    units: {
      kilograms: 1, grams: 1000, milligrams: 1e6,
      pounds: 2.20462, ounces: 35.274, tonnes: 0.001,
    },
  },
  Temperature: { special: true },  // handled separately
  Speed: {
    base: 'km/h',
    units: { 'km/h': 1, 'm/s': 0.277778, mph: 0.621371, knots: 0.539957 },
  },
};

function convert(value, fromUnit, toUnit, category) {
  if (category === 'Temperature') return convertTemp(value, fromUnit, toUnit);
  const cat   = CATEGORIES[category];
  const inBase = value / cat.units[fromUnit];
  return inBase * cat.units[toUnit];
}

function convertTemp(v, from, to) {
  let celsius;
  if      (from === 'Celsius')    celsius = v;
  else if (from === 'Fahrenheit') celsius = (v - 32) * 5/9;
  else                            celsius = v - 273.15;
  if      (to === 'Celsius')      return celsius;
  else if (to === 'Fahrenheit')   return celsius * 9/5 + 32;
  else                            return celsius + 273.15;
}

console.log(convert(100, 'kilometers', 'miles', 'Length').toFixed(3));  // 62.137
console.log(convert(100, 'Celsius', 'Fahrenheit', 'Temperature'));       // 212
2

Build the HTML with category tabs

Dynamic dropdowns that repopulate when you switch category.

<!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>
  <style>
    * { margin:0; padding:0; box-sizing:border-box; }
    body { font-family:'Segoe UI',sans-serif; background:#0f172a; color:#f8fafc; min-height:100vh; display:flex; align-items:center; justify-content:center; padding:20px; }
    .card { background:#1e293b; border-radius:20px; padding:36px; max-width:460px; width:100%; }
    h1 { font-size:1.4rem; text-align:center; margin-bottom:24px; }
    .tabs { display:flex; gap:6px; flex-wrap:wrap; margin-bottom:28px; }
    .tab { flex:1; min-width:80px; padding:8px 4px; border:none; background:#334155; color:#94a3b8; border-radius:8px; cursor:pointer; font-size:0.8rem; font-weight:600; transition:all 0.2s; }
    .tab.active { background:#3b82f6; color:#fff; }
    .row { display:flex; align-items:center; gap:12px; margin-bottom:16px; }
    .col { flex:1; display:flex; flex-direction:column; gap:6px; }
    label { font-size:0.75rem; color:#94a3b8; font-weight:600; text-transform:uppercase; letter-spacing:0.05em; }
    input, select { width:100%; padding:11px 14px; background:#0f172a; border:1px solid #334155; color:#f8fafc; border-radius:10px; font-size:0.95rem; }
    input:focus, select:focus { outline:none; border-color:#3b82f6; }
    .swap-btn { background:#334155; border:none; color:#94a3b8; font-size:1.2rem; padding:10px; border-radius:10px; cursor:pointer; flex-shrink:0; transition:all 0.2s; margin-top:16px; }
    .swap-btn:hover { background:#3b82f6; color:#fff; }
  </style>
</head>
<body>

<?php require_once __DIR__ . '/../promo_banner.php'; ?>

<div class="card">
  <h1>📐 Unit Converter</h1>
  <div class="tabs" id="tabs"></div>
  <div class="row">
    <div class="col"><label>From</label><input type="number" id="fromVal" value="1" oninput="doConvert(false)"><select id="fromUnit" onchange="doConvert(false)"></select></div>
    <button class="swap-btn" onclick="swap()">&#8644;</button>
    <div class="col"><label>To</label><input type="number" id="toVal" oninput="doConvert(true)"><select id="toUnit" onchange="doConvert(false)"></select></div>
  </div>
</div>
<script src="app.js"></script>
</body>
</html>
3

Wire up the JavaScript

Build tabs, populate selects, and run the conversion on every keypress.

// app.js  (paste conversion logic from Step 1 first)
const TEMP_UNITS = ['Celsius', 'Fahrenheit', 'Kelvin'];
let currentCategory = 'Length';

function buildTabs() {
  const tabs = document.getElementById('tabs');
  Object.keys(CATEGORIES).forEach(cat => {
    const btn = document.createElement('button');
    btn.className = 'tab' + (cat === currentCategory ? ' active' : '');
    btn.textContent = cat;
    btn.onclick = () => { currentCategory = cat; buildTabs(); buildSelects(); doConvert(false); };
    tabs.appendChild(btn);
  });
}

function buildSelects() {
  const units = currentCategory === 'Temperature' ? TEMP_UNITS : Object.keys(CATEGORIES[currentCategory].units);
  ['fromUnit','toUnit'].forEach((id, i) => {
    const sel = document.getElementById(id);
    sel.innerHTML = units.map((u,j) => `<option value="${u}" ${j === i ? 'selected' : ''}>${u}</option>`).join('');
  });
}

function doConvert(reversed) {
  const fromVal  = parseFloat(document.getElementById('fromVal').value);
  const fromUnit = document.getElementById('fromUnit').value;
  const toUnit   = document.getElementById('toUnit').value;
  if (isNaN(fromVal)) return;
  const result = convert(fromVal, fromUnit, toUnit, currentCategory);
  document.getElementById(reversed ? 'fromVal' : 'toVal').value = parseFloat(result.toFixed(8));
}

function swap() {
  const fU = document.getElementById('fromUnit').value;
  const tU = document.getElementById('toUnit').value;
  document.getElementById('fromUnit').value = tU;
  document.getElementById('toUnit').value   = fU;
  doConvert(false);
}

buildTabs(); buildSelects(); doConvert(false);
💡 Tip: Temperature uses special-case conversion formulas rather than a simple factor because Celsius and Fahrenheit do not have the same zero point. All other unit conversions are just multiplication by a constant.

🎉 You Did It!

You built a four-category converter that handles both linear units and temperature. Add more categories by extending the CATEGORIES object — each new category automatically gets a tab and populated dropdowns.

Found something wrong?

Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.