A shopping cart is a compulsory section in modern ecommerce web application. Ecommerce web apps processes payment of products. Through shopping cart, the web app is able to:
- Keep track of items selected.
- Get price of each selected item.
- Get quantity of items to be purchased.
- Compute shipping fees
- Compute total amount to be paid for the items.
In summary, shopping cart facilitates the purchase of product or service.
In this tutorial, I'm going to illustrate how to build an interactive shopping cart with html, tailwindcss and javascript.
To follow along with this tutorial, you need to be familiar with the following:
- html
- tailwindcss
- javascript
- dom manipulation
NOTE: This tutorial assumes you already select items from the home page. Now you are in the shopping cart page.
Let's start creating shopping cart.
Create html file and configure tailwindcss
First create index.html file and configure tailwindcss to index.html. For installation of tailwindcss in your project, checkout here.
Now create index.html in our project.
Add the head tag. Inside head tag, link the following:
- google font to use in the project (fraunces, montserrat).
-
output.cssfile (generated by tailwindcss when project executes) -
index.jsfile (created later)
Below is how head tag looks
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,700&family=Fraunces:opsz,wght@9..144,500;9..144,700&family=Montserrat:wght@400;500;700&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="./output.css" />
<script type="module" src="./index.js" defer></script>
<title>cart</title>
</head>
Now go to the body tag. The body tag contains, the header tag, section tag and footer tag.
The header tag consist of the cart logo. The section tag is currently empty (later add cart items). The footer tag contains cart total price, shipping fee and checkout price and checkout button.
<body>
<main class="md:p-6 md:pt-10 px-2 pt-6">
<div class="md:flex md:flex-row md:items-center md:justify-between">
<header class=" flex md:flex flex-row gap-x-2 pb-3 items-center">
<img src="./images/bag-2.png" alt="" srcset="" />
<p class="text-darkBlue text-2xl font-bold">Cart</p>
</header>
</div>
<section class="lg:flex lg:flex-row lg:justify-start">
<section class="lg:w-[65%] lg:pr-4">
<div
class="md:w-full border-y-2 py-4 border-lineColor flex flex-row justify-between text-grey font-medium"
>
<div class="md:flex md:w-[45%] md:flex-row md:justify-between ">
<p>PRODUCT</p>
<p>PRICE</p>
</div>
<div class="md:flex md:w-[30%] md:flex-row md:justify-between">
<p>TOTAL</p>
<p>QTY</p>
</div>
</div>
<section id="add-items" class="add-cart-items">
<!-- purchased items -->
</section>
<footer class="bg-totalsGrey p-4 lg:px-4 lg:p-0 lg:w-[35%]">
<div class="total-section">
<p class="total-amount-name">TOTAL AMOUNT IN CART</p>
<p id="add-items-cost" class="total-amount">$</p>
</div>
<div class="total-section">
<p class="total-amount-name">SHIPPING FEE</p>
<p id="shipping-fee" class="total-amount">$</p>
</div>
<div class="total-section">
<p class="total-amount-name">TOTAL AMOUNT</p>
<p id="total-amount-to-pay" class="total-amount">$</p>
</div>
<button id='checkout-btn' class="total-amount mt-4 py-3 w-full active:bg-grey hover:bg-darkBlue bg-blue text-white ">Checkout <span id="checkout-btn-amount">708.85</span></button>
</footer>
</section>
</main>
</body>
NOTE: The colors used in this project are custom colors (not tailwind default colors). These colors are
darkBlue,totalsGrey,grey. For more information about tailwind custom colors check here.
Create two javascript files
The first file is item.js file. This file has newItem function. The newItem function takes an object as a parameter. The object has three properties(image, name, price).
The function has two local variables named createDiv and itemHtml. Variable createDiv stores newly created html div. The itemHtml stores html code in a string variable.
The innerHtml property of createDiv is assign to itemHtml. The newItem function returns createDiv. The function is then exported.
export default function newItem(item){
const createDiv = document.createElement("div");
const itemHtml = `<div class="border-b-2 md:justify-between border-lineColor flex flex-row py-6">
<div class="flex md:w-[45%] md:justify-between flex-col md:flex-row md:items-center w-[60%] ">
<div class="flex flex-row gap-x-2">
<img class="max-w-[7.5rem] h-auto" src="${item.image}" alt="" srcset="" />
<div class="md:pr-6 md:flex md:flex-col md:justify-center" >
<p class="text-lightGrey text-sm md:text-base">Footwear</p>
<p style="white-space:wrap;overflow:hidden;width:100%" class="item-description md:text-lg text-base">
${item.name}
</p>
</div>
</div>
<p class="self-end md:self-center text-xl md:text-2xl font-bold mr-4 md:mr-0">${item.price}</p>
</div>
<div class="w-[40%] md:w-[30%] flex md:flex-row-reverse md:items-center flex-col items-end justify-between">
<p id="total-item-cost" class="text-xl md:text-2xl text-purple font-bold">${item.price}</p>
<div
class="flex flex-row gap-x-2 items-center border-y-[2px] border-lineColor"
>
<button id="decrease" class="increment-btn">-</button>
<p class="px-2">1</p>
<button id="increase" class="increment-btn ">+</button>
</div>
</div>
</div>`;
createDiv.innerHTML = itemHtml;
return createDiv;
}
Create index.js file. In index.js file import the newItem function from item.js file. Rename the imported function to newShoeItem.
import newShoeItem from "./item.js";
The index.js file, contains an array of objects named shoes. The object has image, name and price properties. The objects displays later as cart selected items.
const shoes = [
{
name:"Nike Air Force 1",
price:110,
image:"https://static.nike.com/a/images/c_limit,w_592,f_auto/t_product_v1/e777c881-5b62-4250-92a6-362967f54cca/air-force-1-07-womens-shoes-b19lqD.png"
},
{
name:"Air Jordan 4 'Black Cat'",
price:240,
image:"https://images.stockx.com/images/Air-Jordan-4-Retro-Black-Cat-2020-Product.jpg?fit=fill&bg=FFFFFF&w=700&h=500&fm=webp&auto=compress&q=90&dpr=2&trim=color&updated_at=1606315877"
},
{
name: "Air Jordan 7 Retro",
price: 200,
image: "https://static.nike.com/a/images/t_PDP_864_v1/f_auto,b_rgb:f5f5f5/bd3da02f-2ddc-4f0c-bb7b-f94c634cc0dd/air-jordan-7-retro-mens-shoes-7Zr804.png",
},
{
name: "Air Jordan 1 Utility",
price: 170,
image: "https://static.nike.com/a/images/c_limit,w_592,f_auto/t_product_v1/956b0723-ef2f-4b49-8982-e2ec37e14f9c/air-jordan-1-utility-mens-shoes.png"
}];
Add DOMContentLoaded event listener. The event calls addItemToCart function after loading dom content.
The addItemsToCart function does the follow:
Get empty
selecttag with idadd-itemsCreate a loop to get each item object in the array of shoes
Call
newShoeItem(imported function) passing each shoe as argument-
Insert returned html code to empty
selecttag of idadd-items
document.addEventListener("DOMContentLoaded",addItemToCart); function addItemToCart() { const addSelectedShoes = document.getElementById("add-items"); shoes.forEach(shoe=>{ addSelectedShoes.appendChild(shoeItem(shoe)); }) }
Now run index.html file in the browser. Your output should resemble the image below
Quantity manipulation
You'll notice the increment(+) and decrement(-) buttons are not working when clicked. You should make the buttons functional in index.js file.
Increment quantity
Start with increment button.To make items quantity increase when + button is clicked, follow the steps below:
Inside addItemsToCart function
-
Get all increment buttons
const incrementButtons = document.querySelectorAll("#increase"); -
Use
forEachmethod to triggerincreaseItemsfunction on each button.
incrementButtons.forEach(increaseItems) -
The
increaseItemsfunction, does the following- Pass in
buttonas parameter - Add
clickevent listener to thebutton - Use
eventobject to get the current quantity of the items -
Increments the current quantity
function increaseItems(button){ button.addEventListener("click", function (e){ e.target.previousElementSibling.textContent++; }) }
- Pass in
Decrement quantity
Make items quantity decrease when clicking - button.
Inside addItemsToCart function
-
Get all decrement buttons
const decrementButtons = document.querySelectorAll("#decrease"); -
Use
forEachmethod to triggerdecreaseItemsfunction on each button.
decrementButtons.forEach(decreaseItems) -
The
decreaseItemsfunction does the following:- Pass in
buttonas parameter - Add
clickevent listener to thebutton - Use
eventobject to get current item quantity -
Decrement current quantity, if current quantity is greater than 1
function decreaseItems(button) { button.addEventListener("click", function (e) { let currentQuantity = e.target.nextElementSibling.textContent; if(currentQuantity > 1){ e.target.nextElementSibling.textContent--; } }); }
- Pass in
Now, you are able to increment and decrement the quantity when + button and - button are clicked as shown below.

You are able to increase and decrease the quantity. But the quantity amount is still constant.
Updating total item price
Multiply item price with quantity to get total item price
Create totalItemPrice function. The function will take in two parameters element and siblingPostion. The totalItemPrice function does the following:
Use
elementparameter(clicked button) to get item price by dom traverseUse
siblingPositionparameter to get item quantityMultiply item price with item quantity to get total item price
-
Use
elementto get text content of total item price and update total item price
function totalItemPrice(element,siblingPosition){ let itemPrice = element.parentElement.parentElement.previousElementSibling.children[1].textContent.slice(1); let itemQuantity = siblingPosition.textContent; let totalItemPrice = itemPrice * itemQuantity; element.parentElement.previousElementSibling.textContent = `$${totalItemPrice}`; }
Now you need to call totalItemPrice function inside decreaseItem and increaseItem function. This will make item total price update everytime increment and decrement button is clicked.
Call totalItemPrice function inside click event function of increaseItem and decreaseItem function.
Use the event object to get the arguments in totalItemPrice.
In increaseItem the arguments used in event function are e.target and e.target.previousElementSibling.
const previousSibling = e.target.previusElementSibling;
totalItemPrice(e.target,previousSibling);
In decreaseItem the arguments used in event function are e.target and e.target.nextElementSibling.
const nextSibling = e.target.nextElementSibling;
totalItemPrice(e.target,previousSibling);
The e.target is the button clicked. The e.target.previousElementSibling and e.target.nextElementSibling gets item quantity
Total item price updates when + and - buttons are clicked.

Now sum up item total price.
Compute cart Total price, shipping fee and checkout price
A cart need to sum up total item price, compute shipping fees and calculate the checkout price of the items. You are going to create calculateTotals function. The function returns an array.
The calculateTotals function does the following:
- Declare
cartTotalPricevariable and initializecartTotalPriceto 0. - Get each item total price and add them to
cartTotalPrice. - Declare
shippingFeevariable and initialize it to 7% ofcartTotalPrice. - Declare
totalCashToPayvariable and initialize it to sum ofcartTotalPriceandshippingFee. -
Returns an array consisting of three variables;
cartTotalPrice,shippingFeeandtotalCashToPay.
function calculateTotals() { let cartTotalPrice = 0; const getItemPrices = document.querySelectorAll("#total-item-cost"); getItemPrices.forEach(itemPrice =>{ cartTotalPrice += Number(itemPrice.textContent.slice(1)); }) const shippingFee = (cartTotalPrice*7/100); const totalCashToPay = cartTotalPrice + shippingFee; return [cartTotalPrice.toFixed(2), shippingFee.toFixed(2), totalCashToPay.toFixed(2)] }
Updating cart Total price, shipping fee and checkout price on corresponding elements
You need to update the UI with computed values. Everytime the user decrement or increment quantity, the UI needs to show real time values.
Create updateTotals function which takes in two parameters. The parameters are elementId and value. The function gets the element of the id and update the element text content with the value.
function updateTotals(elementId,value){
const element = document.querySelector(elementId);
element.textContent = value;
}
Call calculateTotals and updateTotals function inside the totalItemPrice function. This will make updates when either increment or decrement button is clicked.
The calculateTotals function will return an array. Then destructure the array to get three independent value.
const [totalPrice,shippingFee,checkoutPrice] = calculateTotals();
Now call the updateTotals function to change the initial value of the elements to current value.
- Update content of element with id
add-items-costtototalPricevalue. - Update content of element with id
shipping-feetoshippingFeevalue. - Update content of element with id
total-amount-to-paytocheckoutPricevalue. -
Update checkout button to read
checkoutPrice.
updateTotals("#add-items-cost",`$${totalPrice}`); updateTotals("#shipping-fee",`$${shippingFee}`); updateTotals("#total-amount-to-pay",`$${checkoutPrice}`); updateTotals("#checkout-btn",`Checkout $${checkoutPrice}`);
Finally your shopping cat should be responsive and resemble the image below.

Now the shopping cart is responsive and manipulable. In summary the shopping cart is able to:
- Increase and decrease item quantity
- Compute item total price
- Sum item total price
- Compute shipping fee
- Compute total checkout price

Top comments (0)