Dark CSS

How to Build Currency Converter in JavaScript

Facebook
Twitter
WhatsApp

📌 In this tutorial

We’ll build a simple Currency Converter App using HTML, CSS, and JavaScript.
You’ll learn how to:

  • Create a clean UI with input fields and dropdowns.

  • Show country flags based on selected currencies.

  • Fetch live exchange rates using an API.

  • Display the converted currency amount instantly.

Perfect for beginners who want to practice working with APIs and dynamic DOM updates!

Watch complete tutorial: www.youtube.com/@darkcss77

Currency Converter App

HTML Code:

...

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Currency Coverter App | JavaScript</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>

    <!-- Main container for the currency converter -->
    <div class="container">

        <!-- Title of the app -->
        <h2>Corrency Converter</h2>

        <!-- Currency converter form -->
        <form action="">

            <!-- Input section for entering the amount -->
            <div class="amount">
                <p>Enter Amount</p>
                <input type="text" value="100"> <!-- Default amount is 100 -->
            </div>

            <!-- Dropdowns for selecting currencies -->
            <div class="drop-down">

                <!-- From currency selection -->
                <div class="from">
                    <p>From</p>
                    <div class="select-country">
                        <!-- Flag image of the default 'from' country -->
                        <img src="https://flagsapi.com/US/flat/64.png" alt="">
                        <!-- Select menu for 'from' currency (to be filled by JavaScript) -->
                        <select name="from">
                        </select>
                    </div>
                </div>

                <!-- To currency selection -->
                <div class="to">
                    <p>To</p>
                    <div class="select-country">
                        <!-- Flag image of the default 'to' country -->
                        <img src="https://flagsapi.com/IN/flat/64.png" alt="">
                        <!-- Select menu for 'to' currency (to be filled by JavaScript) -->
                        <select name="to">
                        </select>
                    </div>
                </div>
            </div>

            <!-- Message box to show the converted amount -->
            <div class="msg_box">
                <!-- Output will be inserted here using JavaScript -->
            </div>

            <!-- Convert button -->
            <button>Convert</button>
        </form>
    </div>

    <!-- JavaScript file for populating country codes -->
    <script src="country_code.js"></script>

    <!-- Main JavaScript file for app functionality -->
    <script src="script.js"></script>
</body>

</html>

...

Explanation:

The main layout is wrapped inside a div with the class container, which holds a heading (<h2>) titled “Currency Converter”, followed by a <form> element. Inside the form, there is an input section where users can enter the amount they want to convert, labeled as “Enter Amount”.

Then, there are two dropdown sections — “From” and “To” — each with a flag image and an empty <select> element that will later be filled dynamically with currency options using JavaScript. A div with the class msg_box is included to display the conversion result, and finally, there’s a “Convert” button that triggers the currency conversion.

At the end of the body, two JavaScript files (country_code.js and script.js) are included to add interactivity and handle API logic.

CSS Code:

....


/* Importing Google Font - Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');

/* Resetting default margin and padding for all elements */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Poppins', sans-serif;
}

/* Styling the body with a centered layout and gradient background */
body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    /* Full height of viewport */
    background: linear-gradient(135deg, #667eea 0%, #0040b7 100%);
    padding: 20px;
}

/* Main container box for the converter */
.container {
    background: rgba(255, 255, 255, 0.95);
    /* Semi-transparent white */
    backdrop-filter: blur(10px);
    /* Blur background for glass effect */
    border-radius: 20px;
    box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
    min-width: 450px;
    padding: 30px;
    transition: all .3s ease;
}

/* Slight hover animation on the container */
.container:hover {
    transform: translateY(-5px);
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.25);
}

/* Styling the heading */
h2 {
    color: #333;
    font-size: 1.2rem;
    text-transform: uppercase;
    font-weight: 600;
    text-align: center;
    margin-bottom: 25px;
    position: relative;
    letter-spacing: 1px;
}

/* Decorative line below the heading */
h2::before {
    content: '';
    position: absolute;
    bottom: -15px;
    left: 50%;
    transform: translateX(-50%);
    width: 100px;
    height: 4px;
    background: linear-gradient(135deg, #667eea 0%, #0040b7 100%);
    border-radius: 2px;
}

/* Spacing for the form section */
form {
    margin-top: 40px;
}

/* Styling the amount input section */
.amount {
    margin-bottom: 25px;
}

.amount p {
    color: #555;
    font-size: 14px;
    font-weight: 500;
    margin-bottom: 8px;
}

.amount input {
    width: 100%;
    height: 50px;
    border: none;
    background: #f5f5f5;
    padding: 0 20px;
    font-size: 18px;
    font-weight: 500;
    border-radius: 12px;
    color: #333;
    outline: none;
    border: 2px solid transparent;
    box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.115);
    transition: all .3s ease;
}

/* Highlight input on focus */
.amount input:focus {
    border-color: #667eea;
    background: #fff;
}

/* Container for currency dropdowns */
.drop-down {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 25px;
}

/* Styling for both 'from' and 'to' dropdown sections */
.from,
.to {
    width: 48%;
}

.from p,
.to p {
    color: #555;
    font-size: .9rem;
    font-weight: 500;
    margin-bottom: 8px;
}

/* Dropdown styling with flag and select */
.select-country {
    display: flex;
    align-items: center;
    background: #f5f5f5;
    border-radius: 12px;
    padding: 10px 15px;
    border: 2px solid rgb(217, 217, 217);
    transition: all .3s ease;
}

/* Hover effect for dropdown */
.select-country:hover {
    background: #fff;
    box-shadow: 0 5px 15px rgba(102, 126, 234, .1);
}

/* Focus effect inside dropdown */
.select-country:focus-within {
    border-color: #667eea;
    background: #fff;
}

/* Styling the select element */
.select-country select {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    font-size: 1rem;
    color: #333;
    font-weight: 500;
    cursor: pointer;
}

/* Styling for country flag images */
.select-country img {
    width: 30px;
    height: 30px;
    object-fit: cover;
    margin-right: 10px;
}

/* Message display box for showing conversion result */
.msg_box {
    color: #333;
    padding: 15px;
    border-radius: 12px;
    margin-bottom: 15px;
    text-align: center;
    font-size: 1rem;
    font-weight: 500;
}

/* Convert button styling */
button {
    border: 0;
    outline: none;
    background: linear-gradient(135deg, #667eea 0%, #0040b7 100%);
    color: #fff;
    font-size: 1rem;
    font-weight: 600;
    width: 100%;
    height: 50px;
    letter-spacing: 1px;
    text-transform: uppercase;
    border-radius: 12px;
    cursor: pointer;
    box-shadow: 0px 5px 15px rgba(102, 126, 234, .4);
    transition: all .3s ease;
}

/* Button hover effect */
button:hover {
    transform: translateY(-3px);
    box-shadow: 0 8px 20px rgba(102, 126, 234, .6);
}

/* Button click effect */
button:active {
    transform: translateY(0);
}


....

Explanation:

This CSS file styles the Currency Converter App to make it visually appealing and responsive. It starts by importing the Poppins font from Google Fonts and applies basic resets like removing default margins and padding, and setting box-sizing to border-box for consistent sizing.

The body is centered using Flexbox and given a smooth blue gradient background. The main .container is styled with a white, slightly transparent background, rounded corners, and a subtle shadow for a modern card-like appearance. On hover, it lifts slightly to add interactivity. Headings are styled to be uppercase and centered, with an underline effect using a gradient bar.

Form inputs and dropdowns are styled with padding, rounded edges, and a focus effect that changes the border color to match the theme. Country flags and currency selectors are aligned horizontally inside .select-country.

The convert button is styled with a gradient background, hover animations, and a shadow for a bold look. The result message is shown inside .msg_box with centered text and clear formatting for easy reading.

JavaScript Code:

...

// Base URL for the Exchange Rate API (replace API key if needed)
const URL = "https://v6.exchangerate-api.com/v6/${Enter Your API Key}/pair";

// Selecting elements from the DOM
let dropDown = document.querySelectorAll(".drop-down select");
let amount = document.querySelector(".amount input");
let btn = document.querySelector("button");
let fromCurr = document.querySelector(".from select");
let toCurr = document.querySelector(".to select");
let exchangedCurr = document.querySelector(".msg_box");

// Loop through both 'from' and 'to' dropdowns to populate currency options
for (let select of dropDown) {
  for (currCode in countryList) {
    // Create a new option tag for each currency
    let newOption = document.createElement("option");
    newOption.innerText = currCode;
    newOption.value = currCode;

    // Set default selected options (USD for 'from', INR for 'to')
    if (select.name === "from" && currCode === "USD") {
      newOption.selected = "selected";
    } else if (select.name === "to" && currCode === "INR") {
      newOption.selected = "selected";
    }

    // Append option to dropdown
    select.append(newOption);
  }

  // Add event listener to update flag when dropdown value changes
  select.addEventListener("change", (e) => {
    updateFlag(e.target);
  });

  // Function to update the flag icon based on selected currency
  const updateFlag = (element) => {
    let currCode = element.value; // selected currency code
    let countryCode = countryList[currCode]; // get country code from countryList

    // Set the flag image source dynamically
    let newSrc = `https://flagsapi.com/${countryCode}/flat/64.png`;
    let img = element.parentElement.querySelector("img");
    img.src = newSrc;
  };
}

// Event listener for the "Convert" button
btn.addEventListener("click", async (event) => {
  event.preventDefault();

  let amountValue = amount.value;
  if (amountValue === "" || amountValue < 1) {
    amountValue = 1;
    amount.value = "1";
  }

  exchangedCurr.innerHTML = "Fetching rate...";

  try {
    const Ex_URL = `${URL}/${fromCurr.value}/${toCurr.value}`;
    let response = await fetch(Ex_URL);
    let data = await response.json();

    exchangedCurr.innerHTML = `
      <div class="result-text">
          ${amount.value} ${data.base_code} = 
          ${Math.round(data.conversion_rate * amount.value)} ${data.target_code}
      </div>
    `;
  } catch (error) {
    exchangedCurr.innerHTML = "Something went wrong. Please try again.";
  }
});


....

Explanation:

This JavaScript code powers the functionality of the Currency Converter App. It begins by defining the base API URL for fetching exchange rates.

It then selects key DOM elements like dropdowns, input fields, the convert button, and the result display box. Using a for...in loop, it dynamically populates both “From” and “To” currency <select> dropdowns with options from a countryList object.

It also sets default currencies to USD and INR. When a user selects a currency, the corresponding country flag is updated using the updateFlag function.

When the “Convert” button is clicked, the app prevents the default form submission, validates the amount, fetches the current exchange rate using fetch() and async/await, and then calculates and displays the converted amount inside the .msg_box element.

Overall, the script makes the app dynamic and interactive, enabling real-time currency conversion using live API data.

List of Country code with their currencies:

...

const countryList = {
  AED: "AE",
  AFN: "AF",
  XCD: "AG",
  ALL: "AL",
  AMD: "AM",
  ANG: "AN",
  AOA: "AO",
  AQD: "AQ",
  ARS: "AR",
  AUD: "AU",
  AZN: "AZ",
  BAM: "BA",
  BBD: "BB",
  BDT: "BD",
  XOF: "BE",
  BGN: "BG",
  BHD: "BH",
  BIF: "BI",
  BMD: "BM",
  BND: "BN",
  BOB: "BO",
  BRL: "BR",
  BSD: "BS",
  NOK: "BV",
  BWP: "BW",
  BYR: "BY",
  BZD: "BZ",
  CAD: "CA",
  CDF: "CD",
  XAF: "CF",
  CHF: "CH",
  CLP: "CL",
  CNY: "CN",
  COP: "CO",
  CRC: "CR",
  CUP: "CU",
  CVE: "CV",
  CYP: "CY",
  CZK: "CZ",
  DJF: "DJ",
  DKK: "DK",
  DOP: "DO",
  DZD: "DZ",
  ECS: "EC",
  EEK: "EE",
  EGP: "EG",
  ETB: "ET",
  EUR: "FR",
  FJD: "FJ",
  FKP: "FK",
  GBP: "GB",
  GEL: "GE",
  GGP: "GG",
  GHS: "GH",
  GIP: "GI",
  GMD: "GM",
  GNF: "GN",
  GTQ: "GT",
  GYD: "GY",
  HKD: "HK",
  HNL: "HN",
  HRK: "HR",
  HTG: "HT",
  HUF: "HU",
  IDR: "ID",
  ILS: "IL",
  INR: "IN",
  IQD: "IQ",
  IRR: "IR",
  ISK: "IS",
  JMD: "JM",
  JOD: "JO",
  JPY: "JP",
  KES: "KE",
  KGS: "KG",
  KHR: "KH",
  KMF: "KM",
  KPW: "KP",
  KRW: "KR",
  KWD: "KW",
  KYD: "KY",
  KZT: "KZ",
  LAK: "LA",
  LBP: "LB",
  LKR: "LK",
  LRD: "LR",
  LSL: "LS",
  LTL: "LT",
  LVL: "LV",
  LYD: "LY",
  MAD: "MA",
  MDL: "MD",
  MGA: "MG",
  MKD: "MK",
  MMK: "MM",
  MNT: "MN",
  MOP: "MO",
  MRO: "MR",
  MTL: "MT",
  MUR: "MU",
  MVR: "MV",
  MWK: "MW",
  MXN: "MX",
  MYR: "MY",
  MZN: "MZ",
  NAD: "NA",
  XPF: "NC",
  NGN: "NG",
  NIO: "NI",
  NPR: "NP",
  NZD: "NZ",
  OMR: "OM",
  PAB: "PA",
  PEN: "PE",
  PGK: "PG",
  PHP: "PH",
  PKR: "PK",
  PLN: "PL",
  PYG: "PY",
  QAR: "QA",
  RON: "RO",
  RSD: "RS",
  RUB: "RU",
  RWF: "RW",
  SAR: "SA",
  SBD: "SB",
  SCR: "SC",
  SDG: "SD",
  SEK: "SE",
  SGD: "SG",
  SKK: "SK",
  SLL: "SL",
  SOS: "SO",
  SRD: "SR",
  STD: "ST",
  SVC: "SV",
  SYP: "SY",
  SZL: "SZ",
  THB: "TH",
  TJS: "TJ",
  TMT: "TM",
  TND: "TN",
  TOP: "TO",
  TRY: "TR",
  TTD: "TT",
  TWD: "TW",
  TZS: "TZ",
  UAH: "UA",
  UGX: "UG",
  USD: "US",
  UYU: "UY",
  UZS: "UZ",
  VEF: "VE",
  VND: "VN",
  VUV: "VU",
  YER: "YE",
  ZAR: "ZA",
  ZMK: "ZM",
  ZWD: "ZW",
};

Source Code:

Download “Currency-App.7z” Currency-App.7z – Downloaded 42 times – 3.70 KB

Conclusions:

In this project, we successfully built a responsive and interactive Currency Converter Web App using HTML, CSS, and JavaScript. We structured the layout with HTML, styled it attractively with modern CSS design elements, and added real-time functionality using JavaScript and an exchange rate API. Users can enter an amount, select their desired currencies, and instantly see the converted value along with dynamic flag updates.