Tip Calculator App in HTML, CSS, and JavaScript

Tip Calculator App in HTML, CSS, and JavaScript

Hey everybody I hope you are all fine, today we are going to create a Tip Calculator App in HTML CSS and JavaScript. It’s a great project to build logic and improve your skills in HTML CSS and JavaScript. This project is for beginners who are working in HTML CSS and JavaScript.

So, I’m going to use HTML and CSS to Design the project and we will use media query to make it responsive for any device. Once we designed the complete application, then we will use JavaScript to add the functionalities that help to display the dynamic content, when the user clicks on a particular button.

In this tutorial, we will guide you through the process of building a practical and user-friendly tip calculator app using the trio of web development languages: HTML, CSS, and JavaScript. Whether you are a beginner or have some experience with web development, this step-by-step guide will help you create a handy tool that simplifies the task of calculating tips at restaurants or any other service-based transactions.

Tip Calculator App in HTML CSS and JavaScript

So, Let’s look at the video tutorial that helps you to create your project namely Tip Calculator App in HTML CSS and JavaScript. Inside the tutorial you can learn each step with practically, I hope the video is helpful and beneficial for you, you can watch the video till to end.

I hope you’ve watched the complete video tutorial, you’ve learned something new from this tutorial. Let’s look at the source code of the project below.

You May Also Like:

Before coding, let’s break down the primary functionality we aim to achieve with our tip calculator app. The app should allow users to input the bill amount and select a tip percentage. Subsequently, it should calculate the tip amount and display both the tip and the total bill, including the tip. This user-friendly tool will streamline the process of determining tips, making it convenient for everyone.

HTML Structure:

The HTML (Hypertext Markup Language) is the foundation of our web page. It provides the structure for our tip calculator app, defining the elements users will interact with. We’ll start by creating input fields for the bill amount and tip percentage, a button to initiate the calculation, and placeholders to display the results. This organized structure sets the stage for our app’s functionality.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- displays site properly based on user's device -->
<title>Tip calculator App | OnlineITtuts</title>
    <link rel="stylesheet" href="style.css" />
    <script defer src="app.js"></script>
  </head>
  <body>
    <header>
      <img src="./images/logo.svg" alt="" />
    </header>
    <main>
      <div class="container">
        <div class="topSection">
          <div class="label">
            <label for="input">Bill</label>
          </div>
          <div class="input_wrapper">
            <input type="number" placeholder="0.0" id="input" />
            <img src="./images/icon-dollar.svg" alt="" />
          </div>
          <div class="label">
            <label for="customTip">Select Tip %</label>
          </div>
          <div class="btnContainer">
            <button class="btn">5%</button>
            <button class="btn">10%</button>
            <button class="btn active">15%</button>
            <button class="btn">25%</button>
            <button class="btn">50%</button>
            <input type="number" placeholder="Custom" id="customTip" />
          </div>
          <div class="label">
            <label for="people">Number of People</label>
            <p id="error"></p>
          </div>
          <div class="peopleWrapper">
            <input type="number" placeholder="1" id="people" />
            <img src="./images/icon-person.svg" alt="" />
          </div>
        </div>
        <div class="bottomSection">
          <div class="amount">
            <div class="desc">
              <p>
                Tip Amount <br />
                <span>/ person</span>
              </p>
              <div class="tipValue">$5</div>
            </div>
            <div class="desc">
              <p>
                Total <br />
                <span>/ person</span>
              </p>
              <div class="tipValue">$200</div>
            </div>
          </div>
          <button class="reset">Reset</button>
        </div>
      </div>
    </main>
  </body>
</html>

CSS Styling:

Once we have our HTML structure in place, it’s time to add some visual appeal with CSS (Cascading Style Sheets). CSS will handle the styling, making our app not only functional but also visually pleasing. We’ll choose a color scheme, fonts, and layouts that contribute to a clean and intuitive design. A well-styled interface enhances the overall user experience.

@import url("https://fonts.googleapis.com/css2?family=Manrope:wght@400;600;700;800&family=Space+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap");

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
body {
  background-color: hsl(185, 41%, 84%);
  font-family: "space Mono", sans-serif;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  flex-direction: column;
}
header {
  display: flex;
  justify-content: center;
  margin-block: 50px;
}
.container {
  border-radius: 20px;
  background-color: #fff;
}
.topSection {
  padding: 30px;
}
.label {
  font-size: 14px;
  color: hsl(186, 14%, 43%);
  font-weight: 700px;
  margin-bottom: 20px;
}
.input_wrapper {
  position: relative;
}
.input_wrapper > input {
  margin-block: 0 40px;
  padding: 10px;
  font-size: 16px;
  width: 350px;
  border: none;
  border-radius: 5px;
  background-color: hsl(189, 41%, 97%);
  text-align: right;
  cursor: pointer;
  color: hsl(183, 100%, 15%);
  font-size: 18px;
  font-family: inherit;
  font-weight: 700;
}
input[type="number"] {
  -moz-appearance: textfield;
}
.input_wrapper > input:focus {
  outline: none;
}
.input_wrapper > img {
  position: absolute;
  top: 15px;
  left: 15px;
}
.btnContainer {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 1fr);
  grid-gap: 15px;
  margin-bottom: 40px;
}
.btnContainer > button {
  padding: 10px;
  border: none;
  border-radius: 5px;
  background-color: hsl(183, 100%, 15%);
  color: #fff;
  font-size: 20px;
  cursor: pointer;
  font-family: "space Mono", sans-serif;
}
.btnContainer > button.active {
  background-color: hsl(185, 41%, 84%);
  color: hsl(183, 100%, 15%);
}
button:active {
  transform: scale(0.98);
}
.btnContainer > input {
  border: none;
  padding: 10px;
  background-color: hsl(189, 41%, 97%);
  border-radius: 5px;
  font-family: "space Mono", sans-serif;
  font-size: 14px;
}
.peopleWrapper {
  position: relative;
}
.peopleWrapper > input {
  margin-block: 10px 40px;
  padding: 10px;
  font-size: 16px;
  width: 350px;
  border: none;
  border-radius: 5px;
  background-color: hsl(189, 41%, 97%);
  text-align: right;
  cursor: pointer;
  color: hsl(183, 100%, 15%);
  font-size: 18px;
  font-family: inherit;
  font-weight: 700;
}
.peopleWrapper > input:focus {
  outline: none;
}
.peopleWrapper > input:focus {
  outline: none;
}
.peopleWrapper > img {
  position: absolute;
  top: 20px;
  left: 20px;
}
.bottomSection {
  background-color: hsl(183, 100%, 15%);
  border: none;
  border-radius: 20px;
  padding-block: 50px 20px;
  padding-inline: 20px;
}
.desc {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 55px;
}
.desc > p {
  font-size: 20px;
  font-family: inherit;
  color: #fff;
}
.desc > p > span {
  opacity: 0.5;
}
.desc > div {
  font-size: 30px;
  font-family: inherit;
  color: hsl(172, 67%, 45%);
  font-weight: 700;
}
.reset {
  padding: 15px;
  border: none;
  border-radius: 5px;
  background-color: hsl(184, 14%, 56%);
  font-size: 16px;
  color: hsl(183, 100%, 15%);
  font-weight: 700;
  width: 380px;
  cursor: pointer;
  display: block;
  /* margin-top: 15rem; */
}
@media (min-width: 1200px) {
  .container {
    display: flex;
    width: 920px;
    height: 490px;
    margin: 0 auto;
  }
  .topSection {
    width: 50%;
  }
  .bottomSection {
    width: 50%;
    margin-block: 35px;
    margin-right: 35px;
    padding-block: 50px 20px;
    padding-inline: 20px;
    position: relative;
  }
  .desc {
    padding-inline: 40px;
  }
  .reset {
    position: absolute;
    bottom: 40px;
    left: 40px;
    width: 355px;
    margin: 0 auto;
  }
  .input_wrapper > input {
    width: 379px;
  }
  .peopleWrapper > input {
    position: relative;
    width: 379px;
    bottom: 20px;
  }
  .peopleWrapper > img {
    position: absolute;
    top: 7px;
  }
  .btnContainer {
    grid-template-columns: repeat(3, 1fr);
    margin-bottom: 2.5rem;
  }
  .btn {
    width: 115px;
  }
  .btnContainer > input {
    width: 100%;
  }
}
@media (min-width: 375px) and (max-width: 1199px) {
  .reset {
    width: 100%;
  }
}

JavaScript Functionality:

Now, let’s bring our tip calculator app to life by incorporating JavaScript. JavaScript is a dynamic scripting language that allows us to add functionality and interactivity to our web page. We’ll create event listeners to capture user inputs, perform the necessary calculations, and dynamically update the displayed results. JavaScript’s versatility ensures a responsive user experience.

"use strict";

const inputEl = document.querySelector("#input");
const btnEl = document.querySelectorAll(".btn");
const customTip = document.querySelector("#customTip");
const errorEl = document.querySelector("#error");
const peopleEl = document.querySelector("#people");
const totalVal = document.querySelectorAll(".tipValue");
const resetEl = document.querySelector(".reset");
let billVal = 0;
let peopleVal = 1;
let tipVal = 0.15;
inputEl.addEventListener("input", validateBill);
peopleEl.addEventListener("input", setPeopleValue);
resetEl.addEventListener("click", handleReset);
customTip.addEventListener("input", tipCustomVal);
// btn Events
btnEl.forEach((btn) => {
  btn.addEventListener("click", handleClick);
});
function handleClick(e) {
  btnEl.forEach((btn) => {
    btn.classList.remove("active");
    if (e.target.innerHTML === btn.innerHTML) {
      btn.classList.add("active");
      tipVal = parseFloat(btn.innerHTML) / 100;
    }
  });
  customTip.value = "";
  calculate();
}
// validate the bill
function validateBill() {
  if (inputEl.value.includes(",")) {
    inputEl.value.replace(",", ".");
  }
  billVal = parseFloat(inputEl.value);
  calculate();
}
// tip custom value
function tipCustomVal() {
  tipVal = parseFloat(customTip.value / 100);
  btnEl.forEach((btn) => {
    btn.classList.remove("active");
  });
  if (customTip.value !== 0) {
    calculate();
  }
}
// set people Value
function setPeopleValue() {
  peopleVal = parseFloat(peopleEl.value);
  if (peopleVal <= 0) {
    errorEl.innerHTML = "number must be greater than zero";
    setTimeout(() => {
      errorEl.innerHTML = "";
    }, 2000);
  }
  calculate();
}
// calculate
function calculate() {
  if (peopleVal >= 1) {
    let tip = (billVal * tipVal) / peopleVal;
    let totalAmount = (billVal * (tipVal + 1)) / peopleVal;
    totalVal[0].innerHTML = "$" + tip.toFixed(2);
    totalVal[1].innerHTML = "$" + totalAmount.toFixed(2);
  }
}
// reset
function handleReset() {
  inputEl.value = 0.0;
  validateBill();
  btnEl[2].click();
  peopleEl.value = 1;
  setPeopleValue();
}

Step-by-Step Development:

  1. HTML Structure:
  • Create a new HTML file and define the basic structure.

  • Add input fields for the bill amount and tip percentage.

  • Include a button to trigger the calculation.

  • Set up placeholders to display the tip amount and total bill.

  1. CSS Styling:
  • Open a new CSS file to style your HTML elements.

  • Choose a color scheme that is easy on the eyes.

  • Define fonts and sizes for text elements.

  • Apply layouts and spacing for a well-organized design.

  1. JavaScript Functionality:
  • Link your JavaScript file to your HTML document.

  • Use JavaScript to capture user inputs from the bill and tip percentage fields.

  • Implement a function to calculate the tip amount based on the input values.

  • Update the displayed results dynamically as the user interacts with the app.

  1. Handling Edge Cases and Validation:
  • Implement validation checks to ensure users enter valid data.

  • Consider edge cases, such as zero bill amount or extreme tip percentages.

  • Display meaningful error messages to guide users in case of invalid inputs.

  1. Testing and Debugging:
  • Thoroughly test your app under various scenarios.

  • Debug any issues or glitches that arise during testing.

  • Ensure the app performs reliably and provides accurate results.

Conclusion:

By following this step-by-step tutorial, you have successfully created a user-friendly tip calculator app using HTML, CSS, and JavaScript. This project not only enhances your web development skills but also provides a practical tool that can be used by a wide range of users. Feel free to customize the de