Lesson Goal
A shopping cart is one of the best JavaScript projects because it teaches how data and UI work together. Students learn how to store products, update the page when something changes, calculate totals, and handle user actions like add, remove, and quantity changes.
Main ideas in this lesson
- Store products in JavaScript objects
- Render lists into HTML
- Handle button clicks
- Update totals dynamically
Before starting
- Create a file named index.html
- Open it in a browser
- Open the live editor below
- Save and refresh after every step
Live HTML Preview Editor
Students can paste the code from any step into this editor and preview it immediately. This is useful for experimenting, testing changes, and comparing step-by-step progress.
Embedded HTML Preview Editor
How to use it
- Copy the code from a lesson step.
- Paste it into the embedded editor.
- Run or preview the page.
- Change text, styles, and JavaScript to experiment safely.
Step 0 — Create the basic page
We begin with the smallest working page.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Shopping Cart Lesson</title>
</head>
<body>
<h1>Shopping Cart</h1>
<p>We will build a shopping cart here.</p>
</body>
</html>
Check
You should see a heading and a short paragraph.
Step 1 — Add the page structure
Now we create product and cart areas.
<body>
<h1>Shopping Cart</h1>
<main>
<section>
<h2>Products</h2>
<div id="products">
Product cards will appear here.
</div>
</section>
<section>
<h2>Your Cart</h2>
<div id="cartItems">
Your cart is empty.
</div>
<p>Total: ₹<span id="cartTotal">0</span></p>
</section>
</main>
</body>
Check
You should now see two areas: one for products and one for the cart.
Step 2 — Add CSS layout and card styling
This makes the cart look like a real app.
<style>
:root{
--bg:#fff8ef;
--panel:#ffffff;
--ink:#1f2937;
--muted:#6b7280;
--brand:#d97706;
--line:#ead7c4;
}
*{box-sizing:border-box}
body{
margin:0;
font-family:Arial, Helvetica, sans-serif;
background:var(--bg);
color:var(--ink);
line-height:1.6;
}
.container{
width:min(1100px, calc(100% - 32px));
margin:0 auto;
}
h1,h2,h3{
margin-top:0;
}
.layout{
display:grid;
grid-template-columns:2fr 1fr;
gap:20px;
margin:24px 0;
}
.panel{
background:var(--panel);
border:1px solid var(--line);
border-radius:18px;
padding:20px;
}
.products-grid{
display:grid;
grid-template-columns:repeat(2, 1fr);
gap:16px;
}
.product-card{
border:1px solid var(--line);
border-radius:16px;
padding:16px;
background:#fffdf9;
}
.price{
color:var(--brand);
font-weight:800;
margin:8px 0;
}
.btn{
border:none;
background:var(--brand);
color:#fff;
padding:10px 14px;
border-radius:10px;
cursor:pointer;
font-weight:800;
}
@media (max-width: 850px){
.layout{
grid-template-columns:1fr;
}
.products-grid{
grid-template-columns:1fr;
}
}
</style>
How to use this CSS
Put it inside the <head>. Then wrap your content in a div with class container and use layout, panel, and products-grid.
Check
The page should now feel more organized, even if the cart is not working yet.
Step 3 — Add product data in JavaScript
Now we start using real data.
<script>
const products = [
{ id: 1, name: "Notebook", price: 120 },
{ id: 2, name: "Pen Set", price: 80 },
{ id: 3, name: "Water Bottle", price: 250 },
{ id: 4, name: "Backpack", price: 900 }
];
</script>
Why this matters
Once products are stored in data, we can loop through them and generate HTML automatically. That is much better than hardcoding every product card by hand.
Check
No visual change yet, but your JavaScript now knows which products exist.
Step 4 — Render the products on the page
We use JavaScript to draw product cards.
<div class="container">
<h1>Shopping Cart</h1>
<div class="layout">
<section class="panel">
<h2>Products</h2>
<div id="products" class="products-grid"></div>
</section>
<aside class="panel">
<h2>Your Cart</h2>
<div id="cartItems">Your cart is empty.</div>
<p>Total: ₹<span id="cartTotal">0</span></p>
</aside>
</div>
</div>
<script>
const productsEl = document.getElementById("products");
function renderProducts() {
productsEl.innerHTML = "";
products.forEach((product) => {
productsEl.innerHTML += `
<div class="product-card">
<h3>${product.name}</h3>
<p class="price">₹${product.price}</p>
<button class="btn">Add to Cart</button>
</div>
`;
});
}
renderProducts();
</script>
Check
You should now see four product cards with names, prices, and Add to Cart buttons.
Step 5 — Add items to the cart
Now the cart starts working.
<script>
const cart = [];
const cartItemsEl = document.getElementById("cartItems");
const cartTotalEl = document.getElementById("cartTotal");
function renderProducts() {
productsEl.innerHTML = "";
products.forEach((product) => {
productsEl.innerHTML += `
<div class="product-card">
<h3>${product.name}</h3>
<p class="price">₹${product.price}</p>
<button class="btn" onclick="addToCart(${product.id})">Add to Cart</button>
</div>
`;
});
}
function addToCart(productId) {
const product = products.find((item) => item.id === productId);
cart.push(product);
renderCart();
}
function renderCart() {
if (cart.length === 0) {
cartItemsEl.innerHTML = "Your cart is empty.";
cartTotalEl.textContent = "0";
return;
}
cartItemsEl.innerHTML = "";
let total = 0;
cart.forEach((item) => {
cartItemsEl.innerHTML += `<p>${item.name} — ₹${item.price}</p>`;
total += item.price;
});
cartTotalEl.textContent = total;
}
renderProducts();
renderCart();
</script>
Check
- Click Add to Cart on a product.
- The product should appear in the cart area.
- The total should increase.
Step 6 — Improve the cart with quantity and removal
Now we make the cart behave like a real cart.
<script>
const cart = [];
function addToCart(productId) {
const existingItem = cart.find((item) => item.id === productId);
if (existingItem) {
existingItem.quantity += 1;
} else {
const product = products.find((item) => item.id === productId);
cart.push({ ...product, quantity: 1 });
}
renderCart();
}
function increaseQty(productId) {
const item = cart.find((item) => item.id === productId);
if (item) {
item.quantity += 1;
renderCart();
}
}
function decreaseQty(productId) {
const item = cart.find((item) => item.id === productId);
if (!item) return;
item.quantity -= 1;
if (item.quantity <= 0) {
removeItem(productId);
return;
}
renderCart();
}
function removeItem(productId) {
const index = cart.findIndex((item) => item.id === productId);
if (index !== -1) {
cart.splice(index, 1);
renderCart();
}
}
function clearCart() {
cart.length = 0;
renderCart();
}
function renderCart() {
if (cart.length === 0) {
cartItemsEl.innerHTML = "Your cart is empty.";
cartTotalEl.textContent = "0";
return;
}
cartItemsEl.innerHTML = "";
let total = 0;
cart.forEach((item) => {
const itemTotal = item.price * item.quantity;
total += itemTotal;
cartItemsEl.innerHTML += `
<div class="cart-row">
<strong>${item.name}</strong>
<div>₹${item.price} × ${item.quantity} = ₹${itemTotal}</div>
<div class="cart-actions">
<button onclick="decreaseQty(${item.id})">-</button>
<button onclick="increaseQty(${item.id})">+</button>
<button onclick="removeItem(${item.id})">Remove</button>
</div>
</div>
`;
});
cartItemsEl.innerHTML += `<p><button class="btn" onclick="clearCart()">Clear Cart</button></p>`;
cartTotalEl.textContent = total;
}
</script>
.cart-row{
border:1px solid var(--line);
border-radius:14px;
padding:12px;
margin-bottom:12px;
background:#fffdf9;
}
.cart-actions{
display:flex;
gap:8px;
flex-wrap:wrap;
margin-top:10px;
}
.cart-actions button{
border:none;
background:#f3e5d0;
color:#7c2d12;
padding:8px 10px;
border-radius:10px;
font-weight:800;
cursor:pointer;
}
Check
- Add the same item multiple times and quantity should increase.
- Use + and - buttons to change quantity.
- Use Remove to delete one product completely.
- Use Clear Cart to empty everything.
Final Build — Complete Single HTML Page
This is the complete finished shopping cart in one HTML file. Students can copy it into index.html and run it directly.
Notebook × 2
Bottle × 1
Total: ₹490
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Shopping Cart App</title>
<meta name="description" content="A beginner shopping cart app built using HTML, CSS, and JavaScript." />
<style>
:root{
--bg:#fff8ef;
--panel:#ffffff;
--soft:#fff3df;
--ink:#1f2937;
--muted:#6b7280;
--brand:#d97706;
--brand-dark:#b45309;
--line:#ead7c4;
--shadow:0 10px 28px rgba(0,0,0,.08);
}
*{box-sizing:border-box}
body{
margin:0;
font-family:Arial, Helvetica, sans-serif;
background:var(--bg);
color:var(--ink);
line-height:1.6;
}
.container{
width:min(1100px, calc(100% - 32px));
margin:0 auto;
}
h1,h2,h3,p{
margin-top:0;
}
.site-header{
padding:24px 0;
border-bottom:1px solid var(--line);
background:#fffaf2;
}
.site-header h1{
margin-bottom:6px;
}
.site-header p{
color:var(--muted);
margin-bottom:0;
}
.layout{
display:grid;
grid-template-columns:2fr 1fr;
gap:20px;
padding:24px 0 40px;
}
.panel{
background:var(--panel);
border:1px solid var(--line);
border-radius:20px;
padding:20px;
box-shadow:var(--shadow);
}
.products-grid{
display:grid;
grid-template-columns:repeat(2, 1fr);
gap:16px;
}
.product-card{
border:1px solid var(--line);
border-radius:18px;
padding:16px;
background:#fffdf9;
}
.product-image{
height:120px;
border-radius:14px;
margin-bottom:12px;
display:grid;
place-items:center;
font-weight:800;
color:#92400e;
background:linear-gradient(135deg,#fde7c0,#fff1dd);
}
.price{
color:var(--brand);
font-weight:900;
margin:8px 0 12px;
}
.btn{
border:none;
background:var(--brand);
color:#fff;
padding:10px 14px;
border-radius:10px;
cursor:pointer;
font-weight:800;
transition:transform .2s ease, background .2s ease;
}
.btn:hover{
transform:translateY(-2px);
background:var(--brand-dark);
}
.cart-row{
border:1px solid var(--line);
border-radius:14px;
padding:12px;
margin-bottom:12px;
background:#fffdf9;
}
.cart-row-title{
font-weight:800;
margin-bottom:4px;
}
.cart-row-meta{
color:var(--muted);
margin-bottom:10px;
}
.cart-actions{
display:flex;
gap:8px;
flex-wrap:wrap;
}
.cart-actions button{
border:none;
background:#f3e5d0;
color:#7c2d12;
padding:8px 10px;
border-radius:10px;
font-weight:800;
cursor:pointer;
}
.summary-box{
margin-top:16px;
padding-top:14px;
border-top:1px solid var(--line);
}
.empty{
color:var(--muted);
}
@media (max-width: 850px){
.layout{
grid-template-columns:1fr;
}
.products-grid{
grid-template-columns:1fr;
}
}
</style>
</head>
<body>
<header class="site-header">
<div class="container">
<h1>Simple Shopping Cart</h1>
<p>A beginner-friendly cart built with HTML, CSS, and JavaScript.</p>
</div>
</header>
<main class="container">
<div class="layout">
<section class="panel">
<h2>Products</h2>
<div id="products" class="products-grid"></div>
</section>
<aside class="panel">
<h2>Your Cart</h2>
<div id="cartItems"></div>
<div class="summary-box">
<p><strong>Total: ₹<span id="cartTotal">0</span></strong></p>
<button class="btn" onclick="clearCart()">Clear Cart</button>
</div>
</aside>
</div>
</main>
<script>
const products = [
{ id: 1, name: "Notebook", price: 120 },
{ id: 2, name: "Pen Set", price: 80 },
{ id: 3, name: "Water Bottle", price: 250 },
{ id: 4, name: "Backpack", price: 900 }
];
const cart = [];
const productsEl = document.getElementById("products");
const cartItemsEl = document.getElementById("cartItems");
const cartTotalEl = document.getElementById("cartTotal");
function renderProducts() {
productsEl.innerHTML = "";
products.forEach((product) => {
productsEl.innerHTML += `
<div class="product-card">
<div class="product-image">${product.name}</div>
<h3>${product.name}</h3>
<p class="price">₹${product.price}</p>
<button class="btn" onclick="addToCart(${product.id})">Add to Cart</button>
</div>
`;
});
}
function addToCart(productId) {
const existingItem = cart.find((item) => item.id === productId);
if (existingItem) {
existingItem.quantity += 1;
} else {
const product = products.find((item) => item.id === productId);
cart.push({ ...product, quantity: 1 });
}
renderCart();
}
function increaseQty(productId) {
const item = cart.find((item) => item.id === productId);
if (item) {
item.quantity += 1;
renderCart();
}
}
function decreaseQty(productId) {
const item = cart.find((item) => item.id === productId);
if (!item) return;
item.quantity -= 1;
if (item.quantity <= 0) {
removeItem(productId);
return;
}
renderCart();
}
function removeItem(productId) {
const index = cart.findIndex((item) => item.id === productId);
if (index !== -1) {
cart.splice(index, 1);
renderCart();
}
}
function clearCart() {
cart.length = 0;
renderCart();
}
function renderCart() {
if (cart.length === 0) {
cartItemsEl.innerHTML = '<p class="empty">Your cart is empty.</p>';
cartTotalEl.textContent = "0";
return;
}
cartItemsEl.innerHTML = "";
let total = 0;
cart.forEach((item) => {
const itemTotal = item.price * item.quantity;
total += itemTotal;
cartItemsEl.innerHTML += `
<div class="cart-row">
<div class="cart-row-title">${item.name}</div>
<div class="cart-row-meta">₹${item.price} × ${item.quantity} = ₹${itemTotal}</div>
<div class="cart-actions">
<button onclick="decreaseQty(${item.id})">-</button>
<button onclick="increaseQty(${item.id})">+</button>
<button onclick="removeItem(${item.id})">Remove</button>
</div>
</div>
`;
});
cartTotalEl.textContent = total;
}
renderProducts();
renderCart();
</script>
</body>
</html>
Final Check
- Products render automatically from JavaScript data.
- Add to Cart works.
- Quantity increase and decrease work.
- Remove and Clear Cart work.
- Total updates correctly.
Practice Tasks for Students
Basic tasks
- Add 4 more products
- Add product images
- Add a cart item count at the top
- Show “Empty Cart” in a styled box
Upgrade tasks
- Save cart in localStorage
- Add search by product name
- Add category filters
- Add discount coupon logic