thumbnail

Bill Splitter Using HTML , CSS and JavaScript

Introduction :

This bill splitting website aims to simplify the process of dividing a bill among a group of people. It allows users to input the total bill amount, select a tip percentage, and specify the number of people sharing the bill. Based on these inputs, the website calculates the tip amount, total amount to be paid, and each person’s share of the bill. Additionally, it provides functionality to reset the inputs and start over.

This bill splitting website serves as a practical solution for individuals or groups facing the common challenge of dividing expenses evenly among multiple parties. With its intuitive interface and robust functionality, it simplifies the intricate process of splitting bills, making it an indispensable tool for social gatherings, business meetings, or any situation involving shared expenses.

Imagine a scenario where friends dine out together, each ordering their favorite dishes and drinks. As the meal concludes, the inevitable question arises: “How do we split the bill?” This seemingly simple query can quickly become a logistical nightmare, especially when considering varying meal costs, differing tipping preferences, and the number of individuals involved. Here, this website steps in, transforming the tedious task of bill division into a streamlined and hassle-free experience.

Structural Foundation:

At its core, the website relies on a solid structural foundation provided by HTML (Hypertext Markup Language). HTML elements such as containers, labels, and input fields are meticulously organized to create an intuitive user interface. Each element serves a distinct purpose, contributing to the overall functionality and aesthetic appeal of the website.

Enhancement:

Enhancing the user experience is the CSS (Cascading Style Sheets) styling, which adds visual flair and cohesiveness to the website. Through carefully crafted style rules, elements are adorned with captivating colors, elegant fonts, and responsive design, ensuring a visually appealing presentation across various devices and screen sizes.

Interactive Dynamics:

However, it is the dynamic interactivity facilitated by JavaScript that truly sets this website apart. JavaScript functions orchestrate user interactions, validate input data, perform real-time calculations, and update the display accordingly. Whether selecting tip percentages, inputting custom tips, specifying the number of people, or generating the final bill, JavaScript seamlessly orchestrates every step of the process with precision and efficiency.

Functional Core:

The heart of the website lies in its JavaScript logic, where a series of meticulously crafted functions govern every aspect of bill splitting. From input validation to result calculation, each function plays a vital role in ensuring accuracy and reliability. Whether it’s enabling/disabling buttons based on input validity, calculating tip amounts, or resetting the interface to its initial state, these functions work in harmony to deliver a seamless user experience.

Practical Utility:

Beyond its technical intricacies, this website embodies practical utility, offering a tangible solution to a ubiquitous problem. Whether it’s a casual dinner with friends, a business lunch, or a group outing, the website empowers users to effortlessly divide expenses, fostering harmony and convenience in shared financial transactions.

In essence, this bill splitting website transcends mere digital functionality, embodying the ethos of simplicity, efficiency, and practicality. By seamlessly integrating HTML, CSS, and JavaScript, it transforms the complex chore of bill division into a seamless and enjoyable experience, epitomizing the power of technology to simplify everyday tasks and enhance social interactions.

Explanation :

The website consists of three main sections: HTML for structure and content, CSS for styling, and JavaScript for interactivity and functionality.

HTML Structure:

The HTML structure defines the layout of the website, including input fields, buttons, and result displays. It uses semantic tags like <div>, <label>, and <input> for structuring the content logically. The layout is divided into two main sections: left section for input fields and right section for displaying calculated results.

CSS Styling:

The CSS styling provides visual enhancements to the website, including colors, fonts, spacing, and responsiveness for different screen sizes. It styles various elements such as containers, input fields, buttons, and result displays to create an aesthetically pleasing and user-friendly interface.

JavaScript Logic:

The JavaScript logic handles user interactions and performs calculations based on input values. It consists of several functions to validate input, calculate tip and total amounts, update display, and handle reset functionality.

  • validateInput(): Checks if all required input fields have valid values and enables/disables the “Generate Bill” button accordingly.
  • validateBill(): Validates the bill amount input field and enables/disables tip buttons, custom tip input, and number of people input accordingly.
  • selectTip(e): Handles the selection of tip percentage buttons and calculates the tip amount accordingly. It also enables/disables the custom tip input field.
  • tipCustomValue(): Handles the input of custom tip percentage and calculates the tip amount accordingly.
  • setPeopleValue(): Handles the input of the number of people sharing the bill.
  • calculate(): Calculates the tip amount, total amount to be paid, and each person’s share of the bill based on input values.
  • handleReset(): Resets all input fields, disables unnecessary elements, and clears calculated results when the reset button is clicked.

Purpose of Functions:

  • Validation Functions (validateInput(), validateBill()): Ensure that all required input fields have valid values before allowing the user to generate the bill.
  • Tip Selection Functions (selectTip(e), tipCustomValue()): Handle the selection of tip percentage either through predefined buttons or custom input.
  • Input Handling Functions (setPeopleValue()): Handle the input of the number of people sharing the bill.
  • Calculation Function (calculate()): Calculate tip amount, total amount, and each person’s share of the bill based on input values.
  • Reset Function (handleReset()): Reset all input fields and clear calculated results to start over.

These functions collectively provide the core functionality of the bill splitting website, ensuring a seamless and efficient user experience.

SOURCE CODE :

HTML (index.html)

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

<head>
  <meta charset="UTF-8" />
  <link rel="icon" type="image/svg+xml" href="../../logo.svg" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <script src="./script.js" type="module"></script> <link rel="stylesheet" href="style.css" />
  <title>Bill Splitter</title>
</head>

<body>
  <div class="container">
    <div class="bill-container">
      <div class="inside_left">
        <div class="input-container">
          <label for="amount">Bill</label>
          <div class="amount-container">
            <span>&#8377;</span>
            <input type="number" class="amount" name="amount" id="amount" autofocus />
          </div>
        </div>
        <div class="tip-container">
          <label>Select Tip</label>
          <div class="btn-tip">
            <button class="btn" disabled>5&#37;</button>
            <button class="btn" disabled>10&#37;</button>
            <button class="btn" disabled>15&#37;</button>
            <button class="btn" disabled>25&#37;</button>
            <button class="btn" disabled>50&#37;</button>
            <button class="btn" disabled>75&#37;</button>
          </div>
          <div class="customTip">
            <input type="number" id="customTip" placeholder="Custom Tip" disabled />
          </div>
        </div>
        <div class="people-container">
          <label>Number Of People</label>
          <input type="number" id="person" placeholder="No of people" disabled />
        </div>
        <button id="generate-bill" class="generate" disabled>Generate Bill</button>
      </div>
      <div class="inside_right">
        <div class="total-amount">
          <div class="tip-amount">
            <h4>Tip amount</h4>
            <span class="tipValue"></span>
          </div>
          <div class="total">
            <h4>Total</h4>
            <span class="totalValue"></span>
          </div>
          <div class="total">
            <h4>Each Person Bill</h4>
            <span class="bill"></span>
          </div>
        </div>
        <button id="reset" disabled>Reset</button>
      </div>
    </div>
  </div> <script data-no-optimize="1">!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).LazyLoad=e()}(this,function(){"use strict";function e(){return(e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,a=arguments[e];for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(t[n]=a[n])}return t}).apply(this,arguments)}function i(t){return e({},it,t)}function o(t,e){var n,a="LazyLoad::Initialized",i=new t(e);try{n=new CustomEvent(a,{detail:{instance:i}})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(a,!1,!1,{instance:i})}window.dispatchEvent(n)}function l(t,e){return t.getAttribute(gt+e)}function c(t){return l(t,bt)}function s(t,e){return function(t,e,n){e=gt+e;null!==n?t.setAttribute(e,n):t.removeAttribute(e)}(t,bt,e)}function r(t){return s(t,null),0}function u(t){return null===c(t)}function d(t){return c(t)===vt}function f(t,e,n,a){t&&(void 0===a?void 0===n?t(e):t(e,n):t(e,n,a))}function _(t,e){nt?t.classList.add(e):t.className+=(t.className?" ":"")+e}function v(t,e){nt?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s+)"+e+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")}function g(t){return t.llTempImage}function b(t,e){!e||(e=e._observer)&&e.unobserve(t)}function p(t,e){t&&(t.loadingCount+=e)}function h(t,e){t&&(t.toLoadCount=e)}function n(t){for(var e,n=[],a=0;e=t.children[a];a+=1)"SOURCE"===e.tagName&&n.push(e);return n}function m(t,e){(t=t.parentNode)&&"PICTURE"===t.tagName&&n(t).forEach(e)}function a(t,e){n(t).forEach(e)}function E(t){return!!t[st]}function I(t){return t[st]}function y(t){return delete t[st]}function A(e,t){var n;E(e)||(n={},t.forEach(function(t){n[t]=e.getAttribute(t)}),e[st]=n)}function k(a,t){var i;E(a)&&(i=I(a),t.forEach(function(t){var e,n;e=a,(t=i[n=t])?e.setAttribute(n,t):e.removeAttribute(n)}))}function L(t,e,n){_(t,e.class_loading),s(t,ut),n&&(p(n,1),f(e.callback_loading,t,n))}function w(t,e,n){n&&t.setAttribute(e,n)}function x(t,e){w(t,ct,l(t,e.data_sizes)),w(t,rt,l(t,e.data_srcset)),w(t,ot,l(t,e.data_src))}function O(t,e,n){var a=l(t,e.data_bg_multi),i=l(t,e.data_bg_multi_hidpi);(a=at&&i?i:a)&&(t.style.backgroundImage=a,n=n,_(t=t,(e=e).class_applied),s(t,ft),n&&(e.unobserve_completed&&b(t,e),f(e.callback_applied,t,n)))}function N(t,e){!e||0<e.loadingCount||0<e.toLoadCount||f(t.callback_finish,e)}function C(t,e,n){t.addEventListener(e,n),t.llEvLisnrs[e]=n}function M(t){return!!t.llEvLisnrs}function z(t){if(M(t)){var e,n,a=t.llEvLisnrs;for(e in a){var i=a[e];n=e,i=i,t.removeEventListener(n,i)}delete t.llEvLisnrs}}function R(t,e,n){var a;delete t.llTempImage,p(n,-1),(a=n)&&--a.toLoadCount,v(t,e.class_loading),e.unobserve_completed&&b(t,n)}function T(o,r,c){var l=g(o)||o;M(l)||function(t,e,n){M(t)||(t.llEvLisnrs={});var a="VIDEO"===t.tagName?"loadeddata":"load";C(t,a,e),C(t,"error",n)}(l,function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_loaded),s(e,dt),f(n.callback_loaded,e,a),i||N(n,a),z(l)},function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_error),s(e,_t),f(n.callback_error,e,a),i||N(n,a),z(l)})}function G(t,e,n){var a,i,o,r,c;t.llTempImage=document.createElement("IMG"),T(t,e,n),E(c=t)||(c[st]={backgroundImage:c.style.backgroundImage}),o=n,r=l(a=t,(i=e).data_bg),c=l(a,i.data_bg_hidpi),(r=at&&c?c:r)&&(a.style.backgroundImage='url("'.concat(r,'")'),g(a).setAttribute(ot,r),L(a,i,o)),O(t,e,n)}function D(t,e,n){var a;T(t,e,n),a=e,e=n,(t=It[(n=t).tagName])&&(t(n,a),L(n,a,e))}function V(t,e,n){var a;a=t,(-1<yt.indexOf(a.tagName)?D:G)(t,e,n)}function F(t,e,n){var a;t.setAttribute("loading","lazy"),T(t,e,n),a=e,(e=It[(n=t).tagName])&&e(n,a),s(t,vt)}function j(t){t.removeAttribute(ot),t.removeAttribute(rt),t.removeAttribute(ct)}function P(t){m(t,function(t){k(t,Et)}),k(t,Et)}function S(t){var e;(e=At[t.tagName])?e(t):E(e=t)&&(t=I(e),e.style.backgroundImage=t.backgroundImage)}function U(t,e){var n;S(t),n=e,u(e=t)||d(e)||(v(e,n.class_entered),v(e,n.class_exited),v(e,n.class_applied),v(e,n.class_loading),v(e,n.class_loaded),v(e,n.class_error)),r(t),y(t)}function $(t,e,n,a){var i;n.cancel_on_exit&&(c(t)!==ut||"IMG"===t.tagName&&(z(t),m(i=t,function(t){j(t)}),j(i),P(t),v(t,n.class_loading),p(a,-1),r(t),f(n.callback_cancel,t,e,a)))}function q(t,e,n,a){var i,o,r=(o=t,0<=pt.indexOf(c(o)));s(t,"entered"),_(t,n.class_entered),v(t,n.class_exited),i=t,o=a,n.unobserve_entered&&b(i,o),f(n.callback_enter,t,e,a),r||V(t,n,a)}function H(t){return t.use_native&&"loading"in HTMLImageElement.prototype}function B(t,i,o){t.forEach(function(t){return(a=t).isIntersecting||0<a.intersectionRatio?q(t.target,t,i,o):(e=t.target,n=t,a=i,t=o,void(u(e)||(_(e,a.class_exited),$(e,n,a,t),f(a.callback_exit,e,n,t))));var e,n,a})}function J(e,n){var t;et&&!H(e)&&(n._observer=new IntersectionObserver(function(t){B(t,e,n)},{root:(t=e).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))}function K(t){return Array.prototype.slice.call(t)}function Q(t){return t.container.querySelectorAll(t.elements_selector)}function W(t){return c(t)===_t}function X(t,e){return e=t||Q(e),K(e).filter(u)}function Y(e,t){var n;(n=Q(e),K(n).filter(W)).forEach(function(t){v(t,e.class_error),r(t)}),t.update()}function t(t,e){var n,a,t=i(t);this._settings=t,this.loadingCount=0,J(t,this),n=t,a=this,Z&&window.addEventListener("online",function(){Y(n,a)}),this.update(e)}var Z="undefined"!=typeof window,tt=Z&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),et=Z&&"IntersectionObserver"in window,nt=Z&&"classList"in document.createElement("p"),at=Z&&1<window.devicePixelRatio,it={elements_selector:".lazy",container:tt||Z?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_poster:"poster",class_applied:"applied",class_loading:"litespeed-loading",class_loaded:"litespeed-loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1},ot="src",rt="srcset",ct="sizes",lt="poster",st="llOriginalAttrs",ut="loading",dt="loaded",ft="applied",_t="error",vt="native",gt="data-",bt="ll-status",pt=[ut,dt,ft,_t],ht=[ot],mt=[ot,lt],Et=[ot,rt,ct],It={IMG:function(t,e){m(t,function(t){A(t,Et),x(t,e)}),A(t,Et),x(t,e)},IFRAME:function(t,e){A(t,ht),w(t,ot,l(t,e.data_src))},VIDEO:function(t,e){a(t,function(t){A(t,ht),w(t,ot,l(t,e.data_src))}),A(t,mt),w(t,lt,l(t,e.data_poster)),w(t,ot,l(t,e.data_src)),t.load()}},yt=["IMG","IFRAME","VIDEO"],At={IMG:P,IFRAME:function(t){k(t,ht)},VIDEO:function(t){a(t,function(t){k(t,ht)}),k(t,mt),t.load()}},kt=["IMG","IFRAME","VIDEO"];return t.prototype={update:function(t){var e,n,a,i=this._settings,o=X(t,i);{if(h(this,o.length),!tt&&et)return H(i)?(e=i,n=this,o.forEach(function(t){-1!==kt.indexOf(t.tagName)&&F(t,e,n)}),void h(n,0)):(t=this._observer,i=o,t.disconnect(),a=t,void i.forEach(function(t){a.observe(t)}));this.loadAll(o)}},destroy:function(){this._observer&&this._observer.disconnect(),Q(this._settings).forEach(function(t){y(t)}),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var e=this,n=this._settings;X(t,n).forEach(function(t){b(t,e),V(t,n,e)})},restoreAll:function(){var e=this._settings;Q(e).forEach(function(t){U(t,e)})}},t.load=function(t,e){e=i(e);V(t,e)},t.resetStatus=function(t){r(t)},Z&&function(t,e){if(e)if(e.length)for(var n,a=0;n=e[a];a+=1)o(t,n);else o(t,e)}(t,window.lazyLoadOptions),t});!function(e,t){"use strict";function a(){t.body.classList.add("litespeed_lazyloaded")}function n(){console.log("[LiteSpeed] Start Lazy Load Images"),d=new LazyLoad({elements_selector:"[data-lazyloaded]",callback_finish:a}),o=function(){d.update()},e.MutationObserver&&new MutationObserver(o).observe(t.documentElement,{childList:!0,subtree:!0,attributes:!0})}var d,o;e.addEventListener?e.addEventListener("load",n,!1):e.attachEvent("onload",n)}(window,document);</script><script data-no-optimize="1">var litespeed_vary=document.cookie.replace(/(?:(?:^|.*;\s*)_lscache_vary\s*\=\s*([^;]*).*$)|^.*$/,"");litespeed_vary||fetch("/wp-content/plugins/litespeed-cache/guest.vary.php",{method:"POST",cache:"no-cache",redirect:"follow"}).then(e=>e.json()).then(e=>{console.log(e),e.hasOwnProperty("reload")&&"yes"==e.reload&&(sessionStorage.setItem("litespeed_docref",document.referrer),window.location.reload(!0))});</script><script data-optimized="1" type="litespeed/javascript" data-src="https://foolishdeveloper.com/wp-content/litespeed/js/e06f9a8e9f9b4d7bb2f81f2339980ae8.js?ver=8928e"></script><script>const litespeed_ui_events=["mouseover","click","keydown","wheel","touchmove","touchstart"];var urlCreator=window.URL||window.webkitURL;function litespeed_load_delayed_js_force(){console.log("[LiteSpeed] Start Load JS Delayed"),litespeed_ui_events.forEach(e=>{window.removeEventListener(e,litespeed_load_delayed_js_force,{passive:!0})}),document.querySelectorAll("iframe[data-litespeed-src]").forEach(e=>{e.setAttribute("src",e.getAttribute("data-litespeed-src"))}),"loading"==document.readyState?window.addEventListener("DOMContentLoaded",litespeed_load_delayed_js):litespeed_load_delayed_js()}litespeed_ui_events.forEach(e=>{window.addEventListener(e,litespeed_load_delayed_js_force,{passive:!0})});async function litespeed_load_delayed_js(){let t=[];for(var d in document.querySelectorAll('script[type="litespeed/javascript"]').forEach(e=>{t.push(e)}),t)await new Promise(e=>litespeed_load_one(t[d],e));document.dispatchEvent(new Event("DOMContentLiteSpeedLoaded")),window.dispatchEvent(new Event("DOMContentLiteSpeedLoaded"))}function litespeed_load_one(t,e){console.log("[LiteSpeed] Load ",t);var d=document.createElement("script");d.addEventListener("load",e),d.addEventListener("error",e),t.getAttributeNames().forEach(e=>{"type"!=e&&d.setAttribute("data-src"==e?"src":e,t.getAttribute(e))});let a=!(d.type="text/javascript");!d.src&&t.textContent&&(d.src=litespeed_inline2src(t.textContent),a=!0),t.after(d),t.remove(),a&&e()}function litespeed_inline2src(t){try{var d=urlCreator.createObjectURL(new Blob([t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1")],{type:"text/javascript"}))}catch(e){d="data:text/javascript;base64,"+btoa(t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1"))}return d}</script></body>

</html>
				
			

CSS (style.css)

				
					.bill-container {
  margin: auto;
  display: flex;
  background-color: #fff;
  justify-content: space-between;
  border-radius: 10px;
  max-width: 700px;
  gap: 20px;
  margin-top: 20px;
}

.inside_left {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.input-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.input-container>label {
  color: #6f3cff;
  font-size: 20px;
}

.amount-container {
  display: flex;
  width: 100%;
  height: 35px;
  padding: 10px;
  align-items: center;
  font-size: 20px;
  gap: 10px;
  border: 1px solid black;
  border-radius: 4px;
  color: #6f3cff;
}

.amount-container>input {
  border: none;
  outline: none;
  width: 100%;
  height: 30px;
  background-color: transparent;
  font-size: 20px;
  color: #6f3cff;
}

input[type='number']::-webkit-inner-spin-button,
input[type='number']::-webkit-outer-spin-button {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  margin: 0;
}

.tip-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.tip-container>label {
  color: #6f3cff;
  font-size: 20px;
}

.btn-tip {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
  gap: 15px;
}

.customTip {
  width: 100%;
}

.customTip>input {
  width: 100%;
  height: 35px;
  padding: 10px;
  font-size: 15px;
  outline: none;
  border: none;
  background-color: #ccc;
  color: #6f3cff;
}

.btn {
  padding: 10px;
  border: none;
  outline: none;
  border-radius: 5px;
  font-size: 20px;
}

.btn.true {
  background-color: #9c60ff;
  color: #fff;
  cursor: pointer;
}

.btn.active {
  outline: 4px solid rgba(255, 162, 0, 0.888);
}

.people-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.people-container>label {
  color: #6f3cff;
  font-size: 20px;
}

.people-container>input {
  width: 100%;
  height: 35px;
  padding: 10px;
  font-size: 15px;
  outline: none;
  border: none;
  background-color: #ccc;
  color: #6f3cff;
}

.generate {
  width: 100%;
  height: 40px;
  border: none;
  font-size: 15px;
  border-radius: 7px;
  cursor: not-allowed;
}

.generate.active {
  background-color: #9c60ff;
  color: white;
  cursor: pointer;
}

.inside_right {
  background: #34568b;
  width: 100%;
  display: flex;
  margin: 30px 0 20px 0;
  flex-direction: column;
  justify-content: space-between;
  padding: 30px;
  border-radius: 10px;
}

.total-amount {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.tip-amount {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.tip-amount>h4 {
  font-size: 16px;
  color: #fff;
}

.tip-amount>span {
  font-size: 25px;
  color: #c39fff;
  font-weight: 700;
}

.total {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.total>h4 {
  font-size: 16px;
  color: #fff;
}

.total>span {
  font-size: 25px;
  color: #c39fff;
  font-weight: 700;
}

#reset {
  padding: 12px;
  border: none;
  border-radius: 5px;
  font-size: 16px;
  width: 100%;
  cursor: not-allowed;
}

#reset.active {
  background-color: #ffffff;
  color: black;
  cursor: pointer;
}

@media only screen and (max-width: 600px) {
  .bill-container {
    flex-direction: column;
  }

  .total-amount {
    gap: 10px;
  }

  .btn-tip {
    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  }
}
				
			

JavaScript (index.js)

				
					const amount = document.getElementById('amount');
const tipButton = document.querySelectorAll('.btn');
const customTip = document.getElementById('customTip');
const noOfPeople = document.getElementById('person');
const generateBill = document.getElementById('generate-bill');
const tipValue = document.querySelector('.tipValue');
const totalValue = document.querySelector('.totalValue');
const eachPersonBill = document.querySelector('.bill');
const resetBtn = document.getElementById('reset');

let billValue = 0;
let tip = 0;
let people = 0;

function validateInput() {
  if (billValue > 0 && tip > 0 && people > 0) {
    generateBill.classList.add('active');
    generateBill.disabled = false;
    return true;
  } else {
    generateBill.classList.remove('active');
    generateBill.disabled = true;
    return false;
  }
}

function validateBill() {
  billValue = parseFloat(amount.value);
  tipButton.forEach((btn) => {
    if (billValue > 0) {
      btn.classList.add('true');
      btn.disabled = false;
      customTip.disabled = false;
      noOfPeople.disabled = false;
    } else {
      btn.classList.remove('true');
      btn.disabled = true;
      customTip.disabled = true;
      noOfPeople.disabled = true;
    }
  });

  validateInput();
}

function selectTip(e) {
  tipButton.forEach((btn) => {
    btn.classList.remove('active');
    if (e && e.target.innerHTML == btn.innerHTML) {
      btn.classList.add('active');
      tip = parseFloat(btn.innerHTML) / 100;
    }
  });
  customTip.value = '';
  validateInput();
}

function tipCustomValue() {
  if (customTip.value !== 0) {
    tip = parseFloat(customTip.value / 100);
    tipButton.forEach((btn) => {
      btn.classList.remove('active');
    });
  }
  validateInput();
}

function setPeopleValue() {
  people = parseFloat(noOfPeople.value);
  validateInput();
}

function calculate() {
  if (people >= 1) {
    let tipAmount = billValue * tip;
    let totalAmount = billValue + tipAmount;
    let divideBill = totalAmount / people;

    tipValue.innerHTML = '&#8377;' + tipAmount.toFixed(2);
    totalValue.innerHTML = '&#8377;' + totalAmount.toFixed(2);
    eachPersonBill.innerHTML = '&#8377;' + divideBill.toFixed(2);
    resetBtn.classList.add('active');
    resetBtn.disabled = false;
  }
}

function handleReset() {
  amount.value = '';
  validateBill();
  tipButton.forEach((btn) => {
    btn.classList.remove('true');
    btn.disabled = true;
  });
  tip = '';
  customTip.value = '';
  selectTip();
  noOfPeople.value = '';
  setPeopleValue();
  validateInput();
  generateBill.disabled = true
  tipValue.innerHTML = '';
  totalValue.innerHTML = '';
  eachPersonBill.innerHTML = '';
  resetBtn.classList.remove('active');
  resetBtn.disabled = true;
}

amount.addEventListener('input', validateBill);
generateBill.addEventListener('click', calculate);
customTip.addEventListener('input', tipCustomValue);
noOfPeople.addEventListener('input', setPeopleValue);
resetBtn.addEventListener('click', handleReset);
tipButton.forEach((btn) => {
  btn.addEventListener('click', selectTip);
});

				
			

OUTPUT :

OUTPUT