Project HTML CSS & JavaScript: Website Marketplace Sederhana
Membuat website marketplace sederhana menggunakan HTML, CSS, dan JavaScript adalah proyek yang bagus untuk mempelajari pengembangan web front-end. Dalam panduan ini, kita akan membuat sebuah mini marketplace dengan fitur:
✅ Daftar produk dengan gambar
✅ Keranjang belanja sederhana
✅ Animasi hover dan transisi
✅ Tampilan responsif (mobile-friendly)
✅ Filter produk berdasarkan kategori
Mari kita mulai langkah demi langkah!
Persiapan Proyek
Struktur File
/marketplace │── index.html │── cart.html │── style.css │── script.js │── script-cart.js └── assets/ └── images/
Tools yang Dibutuhkan
- Visual Studio Code (atau teks editor lainnya)
- Browser modern (Chrome, Firefox, Edge)
- Gambar produk (opsional)
1. File index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Marketplace - Azroi</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="style.css"> </head> <body> <header> <div class="logo"> <i class="fas fa-store"></i> <span>MarketPlace</span> </div> <div class="search-cart"> <div class="cart-icon"> <i class="fas fa-shopping-cart"></i> <span class="cart-count">0</span> </div> </div> </header> <main> <section class="categories"> <button class="category-btn active" data-category="all">Semua</button> <button class="category-btn" data-category="elektronik">Elektronik</button> <button class="category-btn" data-category="fashion">Fashion</button> <button class="category-btn" data-category="makanan">Makanan</button> </section> <section class="products" id="productsContainer"> <!-- Produk akan dimuat via JavaScript --> </section> </main> <script src="script.js"></script> </body> </html>
2. File cart.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Keranjang Belanja - Azroi</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="style.css"> </head> <body> <header> <div class="logo"> <i class="fas fa-store"></i> <span>MarketPlace</span> </div> <div class="cart-icon"> <i class="fas fa-shopping-cart"></i> <span class="cart-count">0</span> </div> </header> <main class="cart-container"> <h1><i class="fas fa-shopping-cart"></i> Keranjang Belanja</h1> <div class="cart-items" id="cartItems"> <!-- Item akan dimuat via JavaScript --> </div> <div class="cart-summary"> <h3>Ringkasan Belanja</h3> <div class="summary-item"> <span>Total Item:</span> <span id="totalItems">0</span> </div> <div class="summary-item"> <span>Total Harga:</span> <span id="totalPrice">Rp 0</span> </div> <button class="checkout-btn">Proses Checkout</button> </div> </main> <script src="script-cart.js"></script> </body> </html>
3. File style.css
/* Global Styles */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', sans-serif; } body { background: #f5f5f5; color: #333; } header { background: #4CAF50; color: white; padding: 1rem 2rem; display: flex; justify-content: space-between; align-items: center; box-shadow: 0 2px 10px rgba(0,0,0,0.1); position: sticky; top: 0; z-index: 100; } .logo { display: flex; align-items: center; gap: 10px; font-size: 1.5rem; font-weight: bold; cursor: pointer; } .search-cart { display: flex; align-items: center; gap: 20px; } .cart-icon { position: relative; cursor: pointer; font-size: 1.2rem; } .cart-count { position: absolute; top: -10px; right: -10px; background: #FF5722; color: white; border-radius: 50%; width: 20px; height: 20px; display: flex; justify-content: center; align-items: center; font-size: 0.7rem; } /* Categories */ .categories { display: flex; gap: 10px; padding: 1rem 2rem; overflow-x: auto; background: white; position: sticky; top: 70px; z-index: 90; } .category-btn { background: white; border: 1px solid #ddd; padding: 0.5rem 1rem; border-radius: 20px; cursor: pointer; transition: all 0.3s; white-space: nowrap; } .category-btn:hover { background: #f0f0f0; } .category-btn.active { background: #4CAF50; color: white; border-color: #4CAF50; } /* Products */ .products { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; padding: 1rem 2rem; } .product-card { background: white; border-radius: 10px; overflow: hidden; box-shadow: 0 3px 10px rgba(0,0,0,0.1); transition: all 0.3s; animation: fadeIn 0.5s ease forwards; opacity: 0; } .product-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0,0,0,0.15); } .product-image { width: 100%; height: 180px; object-fit: cover; border-bottom: 1px solid #eee; } .product-info { padding: 1rem; } .product-title { font-size: 1rem; margin-bottom: 0.5rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } .product-price { color: #4CAF50; font-weight: bold; font-size: 1.2rem; margin-bottom: 1rem; } .add-to-cart { width: 100%; padding: 0.5rem; background: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; transition: background 0.3s; font-weight: 500; } .add-to-cart:hover { background: #388E3C; } /* Cart Page */ .cart-container { max-width: 800px; margin: 2rem auto; padding: 1rem; } .cart-items { margin-top: 2rem; } .cart-item { display: flex; gap: 1rem; padding: 1rem; border-bottom: 1px solid #eee; align-items: center; background: white; border-radius: 5px; margin-bottom: 10px; box-shadow: 0 2px 5px rgba(0,0,0,0.05); } .cart-item-image { width: 80px; height: 80px; object-fit: cover; border-radius: 5px; } .cart-item-details { flex-grow: 1; } .cart-item h3 { margin-bottom: 0.5rem; } .quantity-controls { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.5rem; } .quantity-btn { width: 25px; height: 25px; border: none; background: #4CAF50; color: white; border-radius: 3px; cursor: pointer; display: flex; align-items: center; justify-content: center; } .remove-item { background: transparent; border: none; color: #f44336; cursor: pointer; font-size: 1.2rem; padding: 0.5rem; } .cart-summary { margin-top: 2rem; padding: 1.5rem; background: white; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } .summary-item { display: flex; justify-content: space-between; margin-bottom: 1rem; font-size: 1.1rem; } .total-price { font-weight: bold; color: #4CAF50; font-size: 1.2rem; } .checkout-btn { width: 100%; padding: 1rem; background: #4CAF50; color: white; border: none; border-radius: 5px; font-size: 1rem; cursor: pointer; transition: background 0.3s; margin-top: 1rem; font-weight: bold; } .checkout-btn:hover { background: #388E3C; } /* Animations */ @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes bounce { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.2); } } .bounce { animation: bounce 0.3s ease; } /* Responsive */ @media (max-width: 768px) { header { padding: 1rem; } .products { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); padding: 1rem; } .cart-item { flex-direction: column; text-align: center; } .quantity-controls { justify-content: center; } }
4. File script.js
// Data Produk const products = [ { id: 1, name: "Smartphone X", price: 4999000, category: "elektronik", image: "https://images.unsplash.com/photo-1592899677977-9c10ca588bbd?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80" }, { id: 2, name: "Laptop Pro", price: 12999000, category: "elektronik", image: "https://images.unsplash.com/photo-1496181133206-80ce9b88a853?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80" }, { id: 3, name: "Kemeja Flanel", price: 299000, category: "fashion", image: "https://images.unsplash.com/photo-1529374255404-311a2a4f1fd9?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80" }, { id: 4, name: "Sepatu Sneakers", price: 599000, category: "fashion", image: "https://images.unsplash.com/photo-1542291026-7eec264c27ff?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80" }, { id: 5, name: "Kopi Premium", price: 99000, category: "makanan", image: "https://images.unsplash.com/photo-1517705008128-361805f42e86?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80" }, { id: 6, name: "Coklat Belgia", price: 129000, category: "makanan", image: "https://images.unsplash.com/photo-1606313564200-e75d5e30476c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80" } ]; // Variabel Global let cart = JSON.parse(localStorage.getItem('cart')) || []; const productsContainer = document.getElementById('productsContainer'); const categoryButtons = document.querySelectorAll('.category-btn'); const cartCount = document.querySelector('.cart-count'); const cartIcon = document.querySelector('.cart-icon'); // Fungsi untuk menampilkan produk function displayProducts(filteredProducts = products) { productsContainer.innerHTML = ''; filteredProducts.forEach((product, index) => { const productCard = document.createElement('div'); productCard.classList.add('product-card'); productCard.style.animationDelay = `${index * 0.1}s`; productCard.innerHTML = ` <img src="${product.image}" alt="${product.name}" class="product-image"> <div class="product-info"> <h3 class="product-title">${product.name}</h3> <p class="product-price">Rp ${product.price.toLocaleString('id-ID')}</p> <button class="add-to-cart" data-id="${product.id}">Tambah ke Keranjang</button> </div> `; productsContainer.appendChild(productCard); }); // Tambahkan event listener ke tombol document.querySelectorAll('.add-to-cart').forEach(button => { button.addEventListener('click', function() { const productId = parseInt(this.dataset.id); addToCart(productId); // Animasi feedback this.textContent = "✓ Ditambahkan"; this.style.backgroundColor = "#388E3C"; setTimeout(() => { this.textContent = "Tambah ke Keranjang"; this.style.backgroundColor = "#4CAF50"; }, 1000); }); }); } // Fungsi untuk menambahkan produk ke keranjang function addToCart(productId) { const product = products.find(p => p.id === productId); const existingItem = cart.find(item => item.id === productId); if (existingItem) { existingItem.quantity += 1; } else { cart.push({ ...product, quantity: 1 }); } updateCartCount(); saveCart(); } // Fungsi untuk memperbarui jumlah keranjang function updateCartCount() { const totalItems = cart.reduce((total, item) => total + item.quantity, 0); cartCount.textContent = totalItems; // Animasi cartCount.classList.add('bounce'); setTimeout(() => { cartCount.classList.remove('bounce'); }, 300); } // Fungsi untuk menyimpan keranjang ke localStorage function saveCart() { localStorage.setItem('cart', JSON.stringify(cart)); } // Filter produk berdasarkan kategori categoryButtons.forEach(button => { button.addEventListener('click', () => { // Update tombol aktif categoryButtons.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); const category = button.dataset.category; if (category === 'all') { displayProducts(); } else { const filteredProducts = products.filter(product => product.category === category); displayProducts(filteredProducts); } }); }); // Navigasi ke keranjang cartIcon.addEventListener('click', () => { window.location.href = 'cart.html'; }); // Navigasi ke beranda saat logo diklik document.querySelector('.logo').addEventListener('click', () => { window.location.href = 'index.html'; }); // Inisialisasi displayProducts(); updateCartCount();
5. File script-cart.js
// Ambil data dari localStorage let cart = JSON.parse(localStorage.getItem('cart')) || []; const cartItemsContainer = document.getElementById('cartItems'); const totalItemsElement = document.getElementById('totalItems'); const totalPriceElement = document.getElementById('totalPrice'); const cartCount = document.querySelector('.cart-count'); const checkoutBtn = document.querySelector('.checkout-btn'); // Fungsi untuk menampilkan keranjang function displayCart() { cartItemsContainer.innerHTML = ''; if (cart.length === 0) { cartItemsContainer.innerHTML = ` <div class="empty-cart"> <i class="fas fa-shopping-cart" style="font-size: 3rem; opacity: 0.3;"></i> <p>Keranjang belanja kosong</p> <a href="index.html" class="back-to-shop">Kembali Berbelanja</a> </div> `; totalItemsElement.textContent = '0'; totalPriceElement.textContent = 'Rp 0'; checkoutBtn.style.display = 'none'; return; } let totalItems = 0; let totalPrice = 0; cart.forEach(item => { totalItems += item.quantity; totalPrice += item.price * item.quantity; const cartItem = document.createElement('div'); cartItem.classList.add('cart-item'); cartItem.innerHTML = ` <img src="${item.image}" alt="${item.name}" class="cart-item-image"> <div class="cart-item-details"> <h3>${item.name}</h3> <p>Rp ${item.price.toLocaleString('id-ID')}</p> <div class="quantity-controls"> <button class="quantity-btn" data-id="${item.id}" data-action="decrease">-</button> <span class="quantity">${item.quantity}</span> <button class="quantity-btn" data-id="${item.id}" data-action="increase">+</button> </div> </div> <button class="remove-item" data-id="${item.id}"> <i class="fas fa-trash"></i> </button> `; cartItemsContainer.appendChild(cartItem); }); // Update total totalItemsElement.textContent = totalItems; totalPriceElement.textContent = `Rp ${totalPrice.toLocaleString('id-ID')}`; checkoutBtn.style.display = 'block'; // Tambahkan event listeners document.querySelectorAll('.quantity-btn').forEach(button => { button.addEventListener('click', updateQuantity); }); document.querySelectorAll('.remove-item').forEach(button => { button.addEventListener('click', removeItem); }); } // Fungsi untuk memperbarui kuantitas function updateQuantity(e) { const productId = parseInt(e.target.dataset.id); const action = e.target.dataset.action; const item = cart.find(item => item.id === productId); if (action === 'increase') { item.quantity += 1; } else if (action === 'decrease' && item.quantity > 1) { item.quantity -= 1; } updateCart(); } // Fungsi untuk menghapus item function removeItem(e) { const productId = parseInt(e.target.closest('button').dataset.id); cart = cart.filter(item => item.id !== productId); updateCart(); } // Fungsi untuk memperbarui keranjang function updateCart() { saveCart(); displayCart(); updateCartCount(); } // Fungsi untuk menyimpan keranjang function saveCart() { localStorage.setItem('cart', JSON.stringify(cart)); } // Fungsi untuk update counter keranjang function updateCartCount() { const total = cart.reduce((sum, item) => sum + item.quantity, 0); cartCount.textContent = total; } // Proses checkout checkoutBtn.addEventListener('click', () => { alert(`Checkout berhasil! Total belanja: Rp ${totalPriceElement.textContent}`); cart = []; updateCart(); }); // Inisialisasi displayCart(); updateCartCount();
Fitur Utama yang Telah Dibangun
- Sistem Produk:
- Menampilkan daftar produk dengan gambar
- Filter produk berdasarkan kategori
Kesimpulan
Kita telah berhasil membuat website marketplace sederhana dengan:
✅ HTML untuk struktur
✅ CSS untuk styling dan animasi
✅ JavaScript untuk interaktivitas
Proyek ini cocok untuk pemula yang ingin belajar pengembangan web front-end.