E-commerce Product Page with HTML, CSS & JavaScript
40 DAYS 40 PROJECT CHALLENGE
Day #03
Project Overview
The E-commerce Product Page is a modern and responsive frontend project built using HTML, CSS, and JavaScript. It simulates a product shopping experience where users can view product images, check pricing and ratings, select a shoe size, adjust the quantity, and add products to their cart or wishlist.
This project features a Premium Sneakers product with an image gallery, size selection, quantity controls, cart panel, and wishlist panel. JavaScript manages user interactions and dynamically updates the cart and wishlist content. This project is useful for learning UI development, DOM manipulation, event handling, and responsive design.
Key Features
- Product Image Gallery: This page displays a main product image along with multiple thumbnails. Users can click on a thumbnail to update the main image using JavaScript.
- Product Information: The product section of this project includes the product name, rating, price, description and the product is displayed as Premium Sneakers with a price of ₹2,499.
- Size Selection: Users can select from different shoe sizes, including 6, 7, 8, and 9. The selected size receives an active styling class so users can identify their choice.
- Quantity Selector: The quantity section includes increase and decrease buttons. Users can increase the quantity or decrease it, but the quantity cannot go below one.
- Add to Cart: Users must select a size before adding the product to the cart and the selected size, quantity, product name, total price are stored in the cart array.
- Dynamic Cart Panel: The cart opens in a side panel after a product is added. It displays the product name, selected size, quantity, and calculated total price.
- Remove from Cart: It allows users to remove individual cart items by clicking the Remove button. JavaScript updates the cart display after removing the selected item.
- Wishlist Functionality: Users can add the product to their wishlist. The wishlist opens in a separate side panel and displays the saved product name.
- Dynamic Wishlist Updates: Wishlist items are rendered dynamically using JavaScript. Users can also remove items from the wishlist.
- Responsive Design: The product card uses Flexbox for its layout. On smaller screens, a media query changes the product layout from horizontal to vertical.
- Interactive User Interface: Buttons, image thumbnails, size options, and side panels respond to user actions through JavaScript event handlers.
- Side Panel Navigation: Cart and Wishlist panels slide into view using the
.activeCSS class. Users can close either panel using the close button.
What You'll Learn
- How to structure an e-commerce product page using HTML.
- How to create responsive layouts with CSS Flexbox.
- How to build an interactive product image gallery.
- How to handle size selection using JavaScript event listeners.
- How to implement quantity increase and decrease functionality.
- How to use arrays and objects to manage cart data.
- How to dynamically display cart and wishlist items using the DOM.
- How to calculate the total product price based on quantity.
- How to use JavaScript functions for adding and removing items.
- How to create sliding side panels using CSS classes.
- How to apply responsive styling with media queries.
HTML Code
The HTML structure creates the main product page inside the .wrapper and .product-card containers. The left section contains the main product image and thumbnail images. Each thumbnail uses the onclick event to call the changeImage() function when selected.
The right section displays the product name, rating, price, description, size buttons, quantity controls, and action buttons also, these Add to Cart and Wishlist buttons call their respective JavaScript functions.
HTML also includes separate cart and wishlist side panels. These panels contain headings, close buttons, and empty containers where JavaScript dynamically inserts the cart and wishlist items. Finally, the HTML file connects the external CSS and JavaScript files.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Modern Product Page</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="wrapper">
<div class="product-card">
<!-- LEFT SIDE -->
<div class="left">
<img id="mainImage" src="https://picsum.photos/500?1" class="main-img">
<div class="thumbnails">
<img src="https://picsum.photos/500?1" onclick="changeImage(this)">
<img src="https://picsum.photos/500?2" onclick="changeImage(this)">
<img src="https://picsum.photos/500?3" onclick="changeImage(this)">
<img src="https://picsum.photos/500?4" onclick="changeImage(this)">
</div>
</div>
<!-- RIGHT SIDE -->
<div class="right">
<h2>Premium Sneakers</h2>
<p class="rating">⭐ 4.5</p>
<p class="price">₹2,499</p>
<p class="description">
Lightweight premium sneakers built for comfort and everyday style.
Breathable material with durable sole for long-lasting performance.
</p>
<!-- SIZE -->
<div class="sizes">
<p>Size:</p>
<button class="size-btn">6</button>
<button class="size-btn">7</button>
<button class="size-btn">8</button>
<button class="size-btn">9</button>
</div>
<!-- QUANTITY -->
<div class="quantity">
<button onclick="decreaseQty()">−</button>
<input type="number" id="qty" value="1" min="1">
<button onclick="increaseQty()">+</button>
</div>
<!-- BUTTONS -->
<div class="actions">
<button class="primary" onclick="addToCart()">Add to Cart</button>
<button class="secondary" onclick="addToWishlist()">Wishlist</button>
</div>
</div>
</div>
</div>
<!-- CART PANEL -->
<div class="side-panel" id="cartPanel">
<div class="panel-header">
<h3>Cart</h3>
<button onclick="closeCart()">✕</button>
</div>
<div id="cartItems"></div>
</div>
<!-- WISHLIST PANEL -->
<div class="side-panel" id="wishlistPanel">
<div class="panel-header">
<h3>Wishlist</h3>
<button onclick="closeWishlist()">✕</button>
</div>
<div id="wishlistItems"></div>
</div>
<script src="script.js"></script>
</body>
</html> CSS Code
The CSS code creates a clean product layout for this E-commerce Product Page using Flexbox, spacing, rounded corners, and shadows. The body selector sets the page background, while .wrapper centers the product card on the screen, .product-card class creates the main white container with a maximum width, padding, and a two-column layout.
The .main-img and .thumbnails img selectors style the product images. The thumbnail hover effect uses transform: scale(1.05) to provide visual feedback when users move their cursor over an image and the .size-btn class styles the size selection buttons, while .size-btn.active highlights the selected size with a dark background and white text. The .quantity selectors organize the quantity controls and style the buttons and input field.
This .side-panel class creates the fixed cart and wishlist panels which remain outside the screen initially using right: -350px. When the active class is added, the panel moves into view using the right: 0 property and a CSS transition.
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: 'Segoe UI', sans-serif;
background: #042354;
}
.wrapper {
display: flex;
justify-content: center;
padding: 60px 20px;
}
.product-card {
max-width: 1000px;
width: 100%;
background: #fff;
border-radius: 14px;
display: flex;
gap: 50px;
padding: 40px;
box-shadow: 0 10px 30px rgba(0,0,0,0.08);
}
/* LEFT */
.left {
flex: 1;
}
.main-img {
width: 100%;
max-width: 420px;
border-radius: 12px;
}
.thumbnails {
display: flex;
gap: 12px;
margin-top: 15px;
}
.thumbnails img {
width: 75px;
border-radius: 8px;
cursor: pointer;
transition: 0.2s;
}
.thumbnails img:hover {
transform: scale(1.05);
}
/* RIGHT */
.right {
flex: 1;
}
.rating {
color: #f59e0b;
font-weight: 600;
margin: 8px 0;
}
.price {
font-size: 22px;
font-weight: bold;
margin-bottom: 15px;
}
.description {
color: #555;
line-height: 1.6;
margin-bottom: 20px;
}
/* SIZE */
.sizes {
margin-bottom: 20px;
}
.size-btn {
padding: 8px 14px;
margin-right: 10px;
border: 1px solid #ddd;
background: #fff;
cursor: pointer;
border-radius: 6px;
transition: 0.2s;
}
.size-btn.active {
background: #111;
color: #fff;
border-color: #111;
}
/* QUANTITY */
.quantity {
display: flex;
align-items: center;
margin-bottom: 25px;
}
.quantity button {
width: 35px;
height: 35px;
border: none;
background: #111;
color: #fff;
font-size: 18px;
cursor: pointer;
}
.quantity input {
width: 60px;
text-align: center;
height: 35px;
border: 1px solid #ddd;
}
/* BUTTONS */
.actions button {
padding: 12px 20px;
border: none;
cursor: pointer;
border-radius: 8px;
font-weight: 600;
}
.primary {
background: #111;
color: #fff;
margin-right: 10px;
}
.secondary {
background: #eee;
}
/* SIDE PANEL */
.side-panel {
position: fixed;
top: 0;
right: -350px;
width: 320px;
height: 100%;
background: #fff;
padding: 20px;
box-shadow: -5px 0 20px rgba(0,0,0,0.1);
transition: 0.3s;
overflow-y: auto;
}
.side-panel.active {
right: 0;
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.cart-item {
margin: 20px 0;
padding-bottom: 15px;
border-bottom: 1px solid #eee;
}
.cart-item button {
background: crimson;
color: #fff;
border: none;
padding: 6px 10px;
border-radius: 6px;
cursor: pointer;
}
/* RESPONSIVE */
@media(max-width: 768px) {
.product-card {
flex-direction: column;
padding: 25px;
}
} Javascript Code
The JavaScript code controls the product gallery, size selection, quantity management, cart functionality, and wishlist functionality. First, the cart and wishlist arrays store the selected items, while the price variable stores the product price. The selectedSize variable tracks the size chosen by the user.
This changeImage() function updates the main product image using the selected thumbnail’s src attribute. Next, event listeners are added to all size buttons and when a size is selected, the function removes the active class from other buttons, adds it to the selected button, and stores the selected size, increaseQty() and decreaseQty() functions update the quantity input which decrease function checks that the quantity is greater than one before reducing its value.
This addToCart() function first checks whether the user has selected a size. If a size is selected, it creates a cart object containing the product name, size, quantity, and total price. The updateCart() function then displays the cart items dynamically using template literals. Users can remove an item through the removeFromCart() function, which uses splice() to update the cart array.
Similarly, addToWishlist() adds the product to the wishlist array and opens the wishlist panel. The updateWishlist() function displays wishlist items, while removeFromWishlist() deletes a selected item. Finally, the closeCart() and closeWishlist() functions remove the active class to hide their respective panels.
let cart = [];
let wishlist = [];
const price = 2499;
let selectedSize = null;
/* IMAGE CHANGE */
function changeImage(img) {
document.getElementById("mainImage").src = img.src;
}
/* SIZE SELECTION */
const sizeButtons = document.querySelectorAll(".size-btn");
sizeButtons.forEach(button => {
button.addEventListener("click", function () {
sizeButtons.forEach(btn => btn.classList.remove("active"));
this.classList.add("active");
selectedSize = this.innerText;
});
});
/* QUANTITY */
function increaseQty() {
let qty = document.getElementById("qty");
qty.value = parseInt(qty.value) + 1;
}
function decreaseQty() {
let qty = document.getElementById("qty");
if (qty.value > 1) {
qty.value = parseInt(qty.value) - 1;
}
}
/* ADD TO CART */
function addToCart() {
if (!selectedSize) {
alert("Please select a size");
return;
}
let qty = parseInt(document.getElementById("qty").value);
cart.push({
name: "Premium Sneakers",
size: selectedSize,
qty: qty,
total: qty * price
});
updateCart();
document.getElementById("cartPanel").classList.add("active");
}
/* UPDATE CART */
function updateCart() {
let cartItems = document.getElementById("cartItems");
cartItems.innerHTML = "";
cart.forEach((item, index) => {
cartItems.innerHTML += `
<div class="cart-item">
<p><strong>${item.name}</strong></p>
<p>Size: ${item.size}</p>
<p>Qty: ${item.qty}</p>
<p>Total: ₹${item.total}</p>
<button onclick="removeFromCart(${index})">Remove</button>
</div>
`;
});
}
/* REMOVE FROM CART */
function removeFromCart(index) {
cart.splice(index, 1);
updateCart();
}
/* CLOSE CART */
function closeCart() {
document.getElementById("cartPanel").classList.remove("active");
}
/* WISHLIST */
function addToWishlist() {
wishlist.push("Premium Sneakers");
updateWishlist();
document.getElementById("wishlistPanel").classList.add("active");
}
function updateWishlist() {
let wishlistItems = document.getElementById("wishlistItems");
wishlistItems.innerHTML = "";
wishlist.forEach((item, index) => {
wishlistItems.innerHTML += `
<div class="cart-item">
<p>${item}</p>
<button onclick="removeFromWishlist(${index})">Remove</button>
</div>
`;
});
}
function removeFromWishlist(index) {
wishlist.splice(index, 1);
updateWishlist();
}
function closeWishlist() {
document.getElementById("wishlistPanel").classList.remove("active");
} Related Projects
Day 1 : Admin Dashboard UI
User signup and login system with validated credentials and a clean UI.
Concepts: DOM manipulation, form validation, LocalStorage.
Day 5 : Chat UI (Frontend Only)
A simple chat interface with message sending and display functionality.
Concepts: DOM manipulation, event handling, dynamic UI updates.
Day 6 : File Upload Progress Bar
File upload interface with a visual progress bar and smooth animation.
Concepts: File API, progress tracking, animations, event handling.