Ecommerce Website with HTML, CSS, and JS

Building an ecommerce website is one of the best beginner projects for web developers. It teaches you how to structure HTML, style with CSS, and add real interactive features with JavaScript. This guide will take you from zero to a working, small ecommerce front-end: product listing, search, filters, cart, and checkout simulation — all with plain HTML, CSS and JavaScript.

Note: This article shows the full plan, best practices, deployment tips, accessibility pointers, SEO tips, and where to paste your code. If you already have the base index.html file uploaded (you do), I’ll tell you exactly where it fits.

Why build an ecommerce website with HTML, CSS & JS?

  • Practical learning: You practice real-world features — product cards, search, filtering, sorting, cart logic, and localStorage.
  • Stack flexibility: A static front-end can later be connected to any backend (Node, PHP, Python, Firebase).
  • Portfolio value: Recruiters love projects that show end-to-end features.
  • Fast to prototype: No backend needed for a demo — perfect for beginners.

If you want to learn full-stack later, this front-end will be the perfect base to add a backend/API, payment gateway, and database.

Project Overview — What we’ll build

  1. A header with search, category filter, sort, and cart button.
  2. A product grid showing cards (image, name, description, price, Add to Cart).
  3. A cart sidebar showing items, quantity, total and a simulated checkout button.
  4. Client-side product search, filter by category, sort by price.
  5. LocalStorage support so cart persists on page reload.
  6. Responsive design for mobile and tablet.
  7. Basic performance & SEO tips for static sites.

You already provided HTML/CSS/JS. I’ll show where each file goes and how they interact.

Ecommerce Website with HTML, CSS, and JS

Files & Project Structure

A simple structure:

ecommerce-project/
├─ index.html        ← main HTML (you uploaded). :contentReference[oaicite:2]{index=2}
├─ styles.css        ← CSS file (you provided styles; paste into styles.css)
├─ script.js         ← JS file (you provided script; paste into script.js)

You uploaded index.html already — perfect start. Place your CSS in styles.css and JS in script.js The index.html you uploaded already links to styles.css and script.js

The HTML (Where to paste)

You gave index.html. If you want to include it in your project folder, use that file as index.html. It already contains markup for header, search, filters, product container, cart sidebar and footer. (I can see your index.html content uploaded — which is the exact starting point we need.) index

If you want a quick checklist of where to paste code:

  • Put the HTML you uploaded as index.html in your project root. index
  • Put CSS in styles.css and link it from <head>.
  • Put JS in script.js and include it at the end of <body> (your index.html already does this).

HTML Code:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>CodeWithRandom - Simple Ecommerce</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <header class="site-header">
    <h1>CodeWithRandom Clothing Store</h1>
    <nav>
      <input type="text" id="search" placeholder="Search products..." />
      <select id="category-filter">
        <option value="all">All Categories</option>
        <option value="men">Men</option>
        <option value="women">Women</option>
        <option value="kids">Kids</option>
      </select>
      <select id="sort">
        <option value="default">Sort By</option>
        <option value="low">Price: Low to High</option>
        <option value="high">Price: High to Low</option>
      </select>
      <button id="cart-btn">Cart (<span id="cart-count">0</span>)</button>
    </nav>
  </header>

  <section class="banner">
    <h2>Welcome to CodeWithRandom</h2>
    <p>Shop stylish clothes at affordable prices!</p>
  </section>

  <main>
    <section class="products" id="products">
      <!-- Products will be injected by JS -->
    </section>

    <aside id="cart" class="cart hidden">
      <h2>Your Cart</h2>
      <ul id="cart-items"></ul>
      <div class="cart-footer">
        <strong>Total: ₹<span id="cart-total">0</span></strong>
        <button id="checkout">Checkout</button>
        <button id="close-cart">Close</button>
      </div>
    </aside>
  </main>

  <footer>
    <p>© <span id="year"></span> CodeWithRandom. All rights reserved. — <a href="https://codewithrandom.in" target="_blank">codewithrandom.in</a></p>
  </footer>

  <script src="script.js"></script>
</body>
</html>
Ecommerce Website with HTML, CSS, and JS

CSS Code:

/* styles.css - improved */
:root{
  --accent:#2b6cb0;
  --muted:#6b7280;
  --card:#ffffff;
  --bg:#f3f4f6;
}
*{box-sizing:border-box}
body{
  font-family: Inter, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial;
  margin:0; background:var(--bg); color:#111827;
}
.site-header{
  display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center;
  padding:16px 24px; background:linear-gradient(90deg,#fff,#eef2ff); box-shadow:0 2px 6px rgba(2,6,23,0.06);
}
.site-header h1{margin:0;font-size:1.1rem;flex:1}
.site-header nav{display:flex;gap:8px;flex-wrap:wrap}
.site-header nav input,.site-header nav select{
  padding:6px 8px;border-radius:6px;border:1px solid #d1d5db
}
.site-header nav button{
  background:var(--accent); color:#fff; border:0; padding:8px 12px; border-radius:8px; cursor:pointer;
}

.banner{
  text-align:center;padding:30px 10px;background:#fff;box-shadow:0 2px 6px rgba(0,0,0,0.05);margin-bottom:20px
}
.banner h2{margin:0 0 10px;font-size:1.4rem}
.banner p{margin:0;color:var(--muted)}

main{max-width:1200px;margin:24px auto;padding:0 16px; display:flex; gap:20px; align-items:flex-start;}
.products{flex:1; display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:18px;}

.card{
  background:var(--card); padding:14px; border-radius:10px; box-shadow:0 6px 18px rgba(15,23,42,0.06); display:flex; flex-direction:column
}
.card img{width:100%; height:180px; object-fit:cover; border-radius:8px}
.card h3{margin:10px 0 6px; font-size:1rem}
.card p{margin:0 0 8px; color:var(--muted); font-size:0.9rem;flex-grow:1}
.card .price{font-weight:700; margin-bottom:8px}
.card button{background:#111827;color:#fff;border:0;padding:8px 10px;border-radius:8px;cursor:pointer}

.cart{
  width:320px; background:var(--card); padding:12px; border-radius:12px; box-shadow:0 10px 30px rgba(2,6,23,0.08);
}
.hidden{display:none}
.cart ul{list-style:none;padding:0;margin:0;max-height:340px;overflow:auto}
.cart li{display:flex; justify-content:space-between; padding:8px 0;border-bottom:1px solid #eef2ff}
.cart-footer{margin-top:12px; display:flex; gap:8px; align-items:center; justify-content:space-between}
.cart-footer button{padding:8px 10px;border-radius:8px;border:0;cursor:pointer}

footer{margin-top:36px;text-align:center;padding:18px 8px;color:var(--muted);font-size:0.9rem}
@media(max-width:800px){
  main{flex-direction:column}
  .cart{width:100%}
}
Ecommerce Website with HTML, CSS, and JS

JAVASCRIPT Code:

// script.js - improved
const products = [
  {id:1, name:'Classic White T-Shirt', desc:'100% cotton, comfortable fit', price:399, img:'https://thehouseofrare.com/cdn/shop/files/PERSUSWHITE50.webp?v=1743754863'},
  {id:2, name:'Blue Denim Jacket', desc:'Stylish jacket for all seasons', price:1299, img:'https://encrypted-tbn3.gstatic.com/shopping?q=tbn:ANd9GcTnX8K5ooEc-8nFqFGmXgMOufGDhKk6Sdjuu0uPrbOqmvm9CBpGePeaeTHxtWuhVJcBXaDSRWugHUYC5IFMHTwtyCbHJVCdW3LYc04KOpHC97tBo0KJe2MzCic'},
  {id:3, name:'Casual Chinos', desc:'Smart casual trousers', price:799, img:'https://encrypted-tbn2.gstatic.com/shopping?q=tbn:ANd9GcRvCPXlxxvksQPzHCoHIlkstKRc_puo6Y9L6kyYV_lo7Obgnx8JmlqEmmDBAJ1xvqncH6naiyTgvl9eg4_JmwcM9AW63tPHK45AbcJ7XwoG'},
  {id:4, name:'Red Floral Dress', desc:'Lightweight summer dress', price:999, img:'https://encrypted-tbn3.gstatic.com/shopping?q=tbn:ANd9GcRygV6LE_UlUl8_n_oLb1JIlYCRhrawBofR9ooDet22pp8bjREX9WwACjUOFTa4Og-MF6SgnjXR6VwQ9EWDyb4nph4uMb69hqMhTh6Z4ir5cNnHHZjymHh_Ug'},
  {id:5, name:'Kids Hoodie', desc:'Warm and soft hoodie for kids', price:599, img:'https://image.hm.com/assets/hm/7c/1b/7c1b789da66070660e39ea56ecfb6f583da04696.jpg?imwidth=820'},
  {id:6, name:'Formal Shirt', desc:'Perfect for office wear', price:699, img:'https://mcrshopping.com/cdn/shop/files/mcrshirts-bravo-oyt-full-sleeve-formal-white-shirt-for-men.jpg?v=1742901668'},
  {id:7, name:'Sports Shorts', desc:'Comfortable shorts for running', price:349, img:'https://encrypted-tbn0.gstatic.com/shopping?q=tbn:ANd9GcSnHXhI_Id1GdzfIZXLEVLPbPvi5AcIlJnFEHMCXrY-wctG6TYYoNmvkBzaWH-cS8W2HnstFxxs4Laehj9nzq9WtkiDIIg4kBVhcXkwx56S60fmug_pwpshhQ'},
  {id:8, name:'Women’s Blazer', desc:'Elegant blazer for women', price:1499, img:'https://encrypted-tbn0.gstatic.com/shopping?q=tbn:ANd9GcQpvl4kFoBIqho7aRQrBkIQQgD3pgDQ2hrAP2otvguqjW-zgCosUxRJ5wMQHT5xavr-M6TNjXiAYZrblVCetgOGoFpfF0KKfjZPlHL4RHCjKAXT1XU5qq0v'}
];

let cart = [];

const productsEl = document.getElementById('products');
const cartBtn = document.getElementById('cart-btn');
const cartEl = document.getElementById('cart');
const cartItemsEl = document.getElementById('cart-items');
const cartCountEl = document.getElementById('cart-count');
const cartTotalEl = document.getElementById('cart-total');
const closeCartBtn = document.getElementById('close-cart');
const checkoutBtn = document.getElementById('checkout');
const searchInput = document.getElementById('search');
const categoryFilter = document.getElementById('category-filter');
const sortSelect = document.getElementById('sort');

function init(){
  document.getElementById('year').textContent = new Date().getFullYear();
  renderProducts(products);
  attachEvents();
  updateCartUI();
}

function renderProducts(list){
  productsEl.innerHTML = '';
  list.forEach(p=>{
    const card = document.createElement('article');
    card.className = 'card';
    card.innerHTML = `
      <img src="${p.img}" alt="${p.name}">
      <h3>${p.name}</h3>
      <p>${p.desc}</p>
      <div class="price">₹ ${p.price}</div>
      <button data-id="${p.id}">Add to Cart</button>
    `;
    productsEl.appendChild(card);
  });
}

function attachEvents(){
  productsEl.addEventListener('click', e=>{
    if(e.target.tagName === 'BUTTON'){
      const id = Number(e.target.dataset.id);
      addToCart(id);
    }
  });
  cartBtn.addEventListener('click', ()=> cartEl.classList.toggle('hidden'));
  document.getElementById('close-cart').addEventListener('click', ()=> cartEl.classList.add('hidden'));
  document.getElementById('checkout').addEventListener('click', ()=> {
    if(cart.length===0){ alert('Your cart is empty!'); return; }
    alert('Checkout simulated. Total: ₹' + cartTotal());
    cart = [];
    updateCartUI();
    cartEl.classList.add('hidden');
  });
  searchInput.addEventListener('input', filterProducts);
  categoryFilter.addEventListener('change', filterProducts);
  sortSelect.addEventListener('change', filterProducts);
}

function filterProducts(){
  let filtered = [...products];
  const q = searchInput.value.toLowerCase();
  if(q) filtered = filtered.filter(p=>p.name.toLowerCase().includes(q));
  const cat = categoryFilter.value;
  if(cat!=='all'){
    if(cat==='men') filtered = filtered.filter(p=> p.name.toLowerCase().includes('shirt')||p.name.toLowerCase().includes('t-shirt')||p.name.toLowerCase().includes('denim')||p.name.toLowerCase().includes('chinos')||p.name.toLowerCase().includes('shorts'));
    if(cat==='women') filtered = filtered.filter(p=> p.name.toLowerCase().includes('dress')||p.name.toLowerCase().includes('blazer'));
    if(cat==='kids') filtered = filtered.filter(p=> p.name.toLowerCase().includes('kids'));
  }
  if(sortSelect.value==='low') filtered.sort((a,b)=>a.price-b.price);
  if(sortSelect.value==='high') filtered.sort((a,b)=>b.price-a.price);
  renderProducts(filtered);
}

function addToCart(id){
  const prod = products.find(p=>p.id===id);
  const item = cart.find(c=>c.id===id);
  if(item) item.qty += 1;
  else cart.push({id:prod.id, name:prod.name, price:prod.price, qty:1});
  updateCartUI();
}

function removeFromCart(id){
  cart = cart.filter(c=>c.id!==id);
  updateCartUI();
}

function cartTotal(){
  return cart.reduce((s,i)=> s + i.price * i.qty, 0);
}

function updateCartUI(){
  cartItemsEl.innerHTML = '';
  cart.forEach(i=>{
    const li = document.createElement('li');
    li.innerHTML = `<span>${i.name} x ${i.qty}</span><span>₹${i.price * i.qty} <button data-remove="${i.id}">×</button></span>`;
    cartItemsEl.appendChild(li);
  });
  cartItemsEl.querySelectorAll('button[data-remove]').forEach(btn=>{
    btn.addEventListener('click', ()=> removeFromCart(Number(btn.dataset.remove)));
  });
  cartCountEl.textContent = cart.reduce((s,i)=>s+i.qty,0);
  cartTotalEl.textContent = cartTotal();
  if(cart.length===0){
    cartItemsEl.innerHTML = '<li>Your cart is empty</li>';
  }
}

init();

Paste that JS into script.js. It wires everything together with DOM lookups referenced in index.html.

Walkthrough of the JavaScript logic

Let’s explain the important bits so you (and readers) truly understand the logic:

  1. Products array: An array of objects, each object is a product (id, name, desc, price, img). This is your static data store.
  2. renderProducts(list): This function takes a list of product objects and creates HTML cards dynamically:
    • Creates article.card with image, title, description, price and Add button.
    • Adds data-id on button so later we know which product to add.
  3. attachEvents(): Attaches listeners:
    • Click on product container to handle Add to Cart (event delegation).
    • Cart button to toggle cart visibility.
    • Checkout button to simulate checkout.
    • Search input and filter/select change to call filterProducts().
  4. filterProducts(): Reads search query, category and sort to filter and sort the products array, then calls renderProducts(filtered).
  5. addToCart(id): Finds product by id, adds to cart or increments quantity, then calls updateCartUI().
  6. removeFromCart(id): Removes item from cart and updates UI.
  7. cartTotal(): Sums cart items to return total amount.
  8. updateCartUI(): Rebuilds the cart list in DOM, sets cart count, totals, attaches remove button handlers. If cart empty, shows “Your cart is empty”.
  9. init(): Entry point — sets current year, renders products, attaches events, updates cart UI.

This setup is clean and beginner-friendly. It demonstrates the most common front-end ecommerce patterns.

Improve & Extend — Practical Enhancements

Your base is great. Below are suggested improvements (with simple steps) to make it production-ready or stronger for a portfolio:

1. Add product categories in product objects

Right now you filter by name matching — better to add category to each product:

{ id:1, name:'Classic White T-Shirt', category:'men', ... }

Then filterProducts() can use p.category === cat.

2. Lazy-load product images

For performance, add loading="lazy" to <img> tags:

<img src="..." alt="..." loading="lazy">
3. Improve cart UX: quantity control

Instead of only increasing qty by clicking Add again, show + and - buttons to change qty in the cart UI.

4. Save cart in localStorage

If not already implemented, save the cart array:

localStorage.setItem('cart', JSON.stringify(cart));

And load on init:

cart = JSON.parse(localStorage.getItem('cart') || '[]');

Your script already calls saveTasks() style functions; ensure saveCart() is implemented to persist cart.

5. Simple product details modal

Add click on product image or name to open a modal with larger image, full description and Add to Cart button.

6. Add currency formatting & decimal

Show ₹ 1,299.00 format using:

new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR' }).format(amount)
7. Improve accessibility
  • Add alt tags for images (your code already has alt from name).
  • Make buttons focusable and add aria-labels for cart, close buttons.
8. Checkout flow (simulate or integrate)

You can integrate payment simulators or a real gateway later:

  • Simulate by clearing cart and showing a thank-you page.
  • Or integrate Stripe/Razorpay if you want real payments (requires backend).

Host & Deploy — Quick Steps (Free options)

Once your files are ready, host them easily:

  • Netlify — drag & drop your folder or connect GitHub repo. Free plan supports static hosting, redirects, forms.
  • Vercel — great for static front-end, connect your GitHub repo.
  • GitHub Pages — free static hosting for public repos (good for demo projects).
  • Firebase Hosting — simple CLI deploy for static sites.

Tip: Use a custom domain (like shop.codewithrandom.in) and HTTPS for professional demos.

SEO & Performance Tips for Ecommerce Pages

For portfolio/demo SEO and visibility:

  1. Use meaningful <title> and <meta name="description">.
  2. Add Open Graph tags for social sharing:
<meta property="og:title" content="CodeWithRandom Shop — Simple Ecommerce Demo">
<meta property="og:description" content="A demo ecommerce built with HTML, CSS & JS.">
<meta property="og:image" content="https://.../share-image.png">
  1. Use semantic HTML: <header> <main> <article> <aside> <footer>.
  2. Compress images and use WebP where possible.
  3. Minify CSS & JS for production.
  4. Add structured data for product pages (JSON-LD) if you later make product detail pages.
  5. Minify CSS & JS for production.
  6. Add structured data for product pages (JSON-LD) if you later make product detail pages.

Security & Privacy Notes (Important)

  • Don’t store sensitive info in localStorage (like payment data).
  • If you add payments, use server-side code to handle secrets.
  • Validate user inputs before using them.

Testing & Debugging Checklist

Before you show your project to others:

  • Test on mobile (responsive layout).
  • Test search/filter/sort combinations.
  • Test cart persistence (reload, close tab, open again).
  • Check image loading and broken images handling (use placeholder if image fails).
  • Run Lighthouse audit in Chrome DevTools to check performance/accessibility.

Bonus Features You Can Add Later (Nice-to-haves)

  • Product sorting by popularity or rating.
  • User accounts and order history (requires backend).
  • Wishlist & Saved Items.
  • Admin panel to add/edit products (simple static JSON editor or backend).
  • Reviews & ratings stored in backend.
  • Multi-currency & language support.

Code Placement — exactly where to paste your code

You told me you have full HTML, CSS and JS. Here’s the exact placement:

  1. index.html — Use the uploaded index.html as the root file. It already contains header, search input, category filter, sort, product placeholder (<section id="products">), cart aside (<aside id="cart">) and footer. index
  2. styles.css — Paste your CSS (the styles you shared earlier) into styles.css. Link is already present in index.html:
<link rel="stylesheet" href="styles.css">

script.js — Paste your JavaScript into script.js. The index.html links it at the bottom:

<script src="script.js"></script>

Assets — Images can be external URLs (as you used) or local in assets/images/.

Example: Where your index.html slots in (short extract)

Your index.html includes these key elements — use them as the main template (you already uploaded):

  • Header with inputs (search, category, sort)
  • <section class="products" id="products"> — product cards injected by JS.
  • <aside id="cart" class="cart hidden"> — cart sidebar
  • <footer> — with year and link to CodeWithRandom

(Full index.html content is already in your uploaded file.)

Final Checklist before publishing
  • HTML validated (no missing tags)
  • images optimized (compressed)
  • script tested on Chrome & mobile
  • localStorage persists cart
  • responsive layout verified
  • Lighthouse score checked (aim >= 80)
  • meta tags added for SEO & OG sharing
  • analytics added (Google Analytics / Plausible)
Example README (for your GitHub repo)

Use this short README when you push the project to GitHub:

# Simple Ecommerce - CodeWithRandom

A simple frontend ecommerce demo built with HTML, CSS, and JavaScript.
Features: product listing, search, filters, cart with localStorage, checkout simulation.

## How to run
1. Clone repo
2. Open index.html in your browser
3. Or host on Netlify / Vercel / GitHub Pages

## Files
- index.html
- styles.css
- script.js

Made by CodeWithRandom — https://codewithrandom.in
Hurry Out Project is Complete
Ecommerce Website with HTML, CSS, and JS

Full Souce Code : Github
Live : Link

Thanks for reading! If you try this ecommerce project, share your live link in the comments or Follow me on Instagram. Keep building and stay curious — CodeWithRandom team

Article Author : Ashutosh Mishra

 

Leave a Comment