Contoh Web HTML dan Tailwind CSS yang Sudah Jadi (Siap Pakai)
Daftar Isi
PendahuluanPreviewDownloadCara MenggunakanStruktur Folder & FileKode HTML & Tailwind CSSHeadBodyHeaderMainAds SectionWhy us?Popular restaurantNear you restaurantExpert chefKode JavaScriptcard.jsdropdown.jsmain.jstab.jsinput.css.gitignorepackage.jsonvercel.jsonCara MengeditBeragam Template HTML + Tailwind CSS (FREE) 🙌Penutup
Pendahuluan
Pernah nggak sih kamu pengen bikin website tapi bingung harus mulai dari mana? Rasanya kayak mau masak, tapi nggak punya resep bahan-bahan yang udah ada, dan nggak tahu urutannya gimana. Nah, artikel ini hadir buat bantu kamu yang baru belajar HTML dan Tailwind CSS biar nggak nyasar di awal. Di sini, kamu bakal nemuin contoh web sederhana yang udah jadi, lengkap sama struktur HTML-nya dan gaya-gaya dasarnya pakai Tailwind CSS. Serunya lagi, ini bukan cuma contoh doang, kamu bisa langsung pakai atau modifikasi sesuai gaya kamu. Jadi, daripada pusing bikin dari nol, mending mulai dari sesuatu yang udah siap santap. Siap? Yuk, kita bahas bareng-bareng.
Preview
Yuk, intip dulu tampilannya! Gambar di bawah ini semacam 'cuplikan trailer' dari proyek keren yang bakal kamu pelajari.
Resto - Open in Browser
Kalau kamu penasaran dan pengin lihat langsung hasil jadinya, tenang aja aku udah siapin link-nya di bawah ini ya. Tinggal klik aja.
https://resto-rose.vercel.app/
Download
Kamu nggak cuma bisa lihat aja, lho! Di sini aku juga udah sediain file proyeknya biar kamu bisa download dan cobain sendiri. Tinggal klik link Google Drive di bawah ini, terus buka pakai text editor favorit kamu. Aku sendiri sih pakai Visual Studio Code. Yuk klik di bawah ini:
File Zip Proyek Resto
Cara Menggunakan
Biar proyeknya bisa kamu utak-atik, pastikan dulu kamu udah buka foldernya di text editor, ya. Di sini aku pakai Visual Studio Code. Terus, buka terminalnya dengan cara pencet Ctrl + backtick (``` yang di bawah tombol Esc itu, lho). Kalau udah, tinggal jalanin perintah di bawah ini:
npm install
Kalau kamu udah buka terminal dan ketik npm install, itu akan menjalankan proses buat ngedownload semua 'alat bantu' yang dibutuhin proyek ini. Ibaratnya kayak kamu baru pindah rumah, terus npm install itu tugas kamu buat masukin semua perabotan yang udah ada di daftar biar rumahnya langsung siap ditempati. Jadi, semua package yang dibutuhin bakal otomatis didownload ke folder node_modules. Kamu tinggal duduk manis nunggu prosesnya selesai.
Setelah semua ‘perabotan’ alias package-nya udah masuk berkat npm install, sekarang saatnya kita ‘nyalain’ rumahnya biar bisa dipakai. Jalankan perintah di bawah ini buat mulai proyeknya. Anggap aja ini kayak kamu nyalain lampu dan buka pintu langsung keliatan deh isi websitenya di browser. Yuk jalankan perintah ini:
npm run dev
Struktur Folder & File
Sekarang kita intip dulu isi ‘dalaman’ proyek ini, yuk! Jadi, di dalam folder utama bernama RESTO-MAIN, kamu bakal nemuin beberapa bagian penting kayak ini:
/RESTO-MAIN
├── node_modules/
├── src/
│ ├── assets/
│ │ └── images/
│ │ ├── icons/
│ │ │ ├── arrow_bottom.svg
│ │ │ ├── arrow_right.svg
│ │ │ ├── cost.svg
│ │ │ ├── discount.svg
│ │ │ ├── eat.svg
│ │ │ ├── info_square.svg
│ │ │ ├── Location.svg
│ │ │ ├── logo.svg
│ │ │ ├── search.svg
│ │ │ ├── shield.svg
│ │ │ ├── sign_right.svg
│ │ │ ├── sparkle.svg
│ │ │ └── star.svg
│ │ └── thumbnails/
│ │ ├── ads-1.png
│ │ ├── ads-2.png
│ │ ├── chef-1.png
│ │ ├── chef-2.webp
│ │ ├── chef-3.webp
│ │ ├── chef-4.webp
│ │ ├── near-1.png
│ │ ├── near-2.png
│ │ ├── near-3.png
│ │ ├── resto-1.png
│ │ ├── resto-2.png
│ │ ├── resto-3.png
│ │ └── resto-4.png
│ ├── js/
│ │ ├── card.js
│ │ ├── dropdown.js
│ │ ├── main.js
│ │ └── tab.js
│ ├── index.html
│ ├── input.css
│ └── output.css
├── .gitignore
├── package-lock.json
├── package.json
└── vercel.json
VSCode - Folder and File Structure Sidebar
node_modules/
Ini semacam gudang besar berisi semua alat bantu (dependencies) yang tadi kamu download lewat npm install. Jangan diutak-atik manual ya, cukup diurus sama npm-nya aja.
src/
Ini jantungnya proyek kita semua file inti buat tampilannya ada di sini.
assets/
Tempat semua media kayak gambar dan ikon disimpan.
images/
Nah, di sinilah seluruh gambar dikelompokkan jadi dua bagian:
icons/
Berisi semua file SVG yang dipakai buat ikon-ikon kecil, kayak arrow_right.svg, search.svg, sampai logo.svg. Ibaratnya, ini koleksi stiker digital kamu buat dekor halaman.
thumbnails/
Ini kumpulan gambar tampilan kayak iklan, chef, resto, dan lokasi. Bayangin ini kayak album foto buat mempercantik tampilan website.
js/
Folder ini isinya semua file JavaScript yang ngatur interaksi di website kamu. Mulai dari card.js buat fitur kartu, dropdown.js buat menu turun, sampai tab.js buat navigasi tab.
index.html
File utama HTML yang jadi fondasi tampilan web kamu.
input.css dan output.css
input.css tempat kamu nulis style Tailwind, dan output.css adalah hasil akhirnya setelah diproses sama Tailwind. Anggap aja ini kayak nulis resep di input.css, dan ngeluarin masakan siap saji di output.css.
.gitignore
File ini bilang ke Git: "Hei, jangan ikutin file-file tertentu ya, kayak node_modules."
package.json dan package-lock.json
Ini dua file penting buat npm. package.json nyatet semua paket yang kamu butuhin dan script yang bisa dijalankan, sedangkan package-lock.json ngunci versi-versinya biar nggak berubah-ubah.
vercel.json
File ini buat ngasih tau Vercel (platform hosting) gimana cara ngejalanin dan build proyek kamu.
Kode HTML & Tailwind CSS
Head
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Resto - Landing Page</title>
<link href="./output.css" rel="stylesheet" />
<!-- Swiper CSS -->
<link rel="stylesheet" href="<https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css>" />
</head>
Bayangin aja bagian <head> itu kayak ruang kontrolnya halaman web kamu, tempat kamu ngatur semuanya biar berjalan mulus. Di sini, kamu kasih tahu browser, “Hey, pakai karakter UTF-8 ya biar tulisan nggak aneh-aneh!” terus juga atur supaya tampilan web kamu bisa adaptasi dengan baik di semua gadget, dari HP sampai layar gede, lewat viewport. Nah, kamu juga kasih judul keren buat halaman kamu, misalnya “Resto - Landing Page,” biar pengunjung langsung tahu mereka di mana. Gak cuma itu, kamu sambungin file output.css supaya semua gaya kece dari Tailwind bisa nempel di halaman kamu. Terus ada juga link ke Swiper JS dari CDN, ini nih yang bikin slider kamu jadi asik dan interaktif. Jadi intinya, di ruang kontrol ini kamu siapin semua senjata dulu sebelum tampilan aslinya keluar ke layar.
Body
<body>
<!-- Navbar -->
<header class="px-[60px] mt-[60px]">
...
</header>
<main>
...
</main>
<!-- Swiper JS -->
<script src="<https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js>"></script>
<script src="./js/main.js"></script>
<script src="./js/tab.js"></script>
<script src="./js/card.js"></script>
<script src="./js/dropdown.js"></script>
</body>
Disini <main> ini spot utama buat semua konten keren kamu, entah itu gambar, teks, atau fitur-fitur yang pengen kamu pamerin. Pokoknya, semua yang pengunjung cari pasti ada di sini.
Nah, jangan lupa, biar web kamu hidup dan gak cuma statis, kamu juga masukin beberapa file JavaScript di bawah sini. Ada Swiper JS dari CDN, yang tadi udah kita bahas buat bikin slider jadi keren dan interaktif. Terus, ada beberapa skrip lokal kayak main.js, tab.js, card.js, dan dropdown.js. Mereka ini kayak kru di balik layar yang jaga biar fitur-fitur di web kamu jalan mulus, mulai dari navigasi tab, interaksi kartu, sampai dropdown yang muncul pas kamu klik sesuatu. Jadi, semua bagian ini kerja barengan biar pengalaman kamu dan pengunjung makin asik dan dinamis!
Header
Resto - Navtop Section
<header class="px-[60px] mt-[60px]">
<div class="flex justify-between items-center min-w-[1320px] h-14">
<nav>
<ul class="flex gap-[30px]">
<!-- Home -->
<li class="group flex flex-col justify-between h-[28px]">
<a href="#" class="text-[16px] leading-[24px] font-medium">Home</a>
<span class="transition-all duration-300 h-0.5 w-full rounded-full bg-secondary opacity-0 group-hover:opacity-100"></span>
</li>
<!-- Category Dropdown -->
<li class="dropdown relative flex flex-col cursor-pointer">
<div class="flex items-center h-6 w-full">
<button type="button" class="dropdown-button text-[16px] leading-[24px] font-medium cursor-pointer w-full text-left">Category</button>
<div class="flex items-center justify-center h-6 w-6 shrink-0">
<img src="./assets/images/icons/arrow_bottom.svg" alt="" class="dropdown-arrow transition-transform duration-300" />
</div>
</div>
<ul class="dropdown-menu z-50 opacity-0 flex transition-all duration-300 absolute top-full left-0 mt-2 min-w-[150px] flex-col gap-1.5 bg-white rounded-xl py-2.5 shadow-lg">
<li class="group">
<a href="#" class="block py-1.5 px-5 text-[16px] leading-[24px] font-medium transition-all duration-300 hover:bg-secondary/5"> Foods </a>
</li>
<li class="group">
<a href="#" class="block py-1.5 px-5 text-[16px] leading-[24px] font-medium transition-all duration-300 hover:bg-secondary/5"> Drinks </a>
</li>
<li class="group">
<a href="#" class="block py-1.5 px-5 text-[16px] leading-[24px] font-medium transition-all duration-300 hover:bg-secondary/5"> Desserts </a>
</li>
</ul>
</li>
<!-- Services -->
<li class="group flex flex-col justify-between h-[28px]">
<a href="#" class="text-[16px] leading-[24px] font-medium">Services</a>
<span class="transition-all duration-300 h-0.5 w-full rounded-full bg-secondary opacity-0 group-hover:opacity-100"></span>
</li>
<!-- About Us -->
<li class="group flex flex-col justify-between h-[28px]">
<a href="#" class="text-[16px] leading-[24px] font-medium">About us</a>
<span class="transition-all duration-300 h-0.5 w-full rounded-full bg-secondary opacity-0 group-hover:opacity-100"></span>
</li>
</ul>
</nav>
<!-- Logo -->
<a href="./">
<img src="./assets/images/icons/logo.svg" alt="" class="h-[38px] w-auto" />
</a>
<!-- Search and Login -->
<div class="flex gap-5">
<form class="group flex w-[322px] gap-2.5 py-4 px-7 bg-white rounded-[12px] transition-all duration-300 focus-within:ring-2 focus-within:ring-secondary hover:ring-2 hover:ring-secondary">
<div class="flex items-center justify-center h-6 w-6 shrink-0">
<img src="./assets/images/icons/search.svg" alt="" class="" />
</div>
<input type="text" class="w-full text-[16px] font-medium leading-6 placeholder-placeholder group-hover:outline-none focus:outline-none" placeholder="Search your favorite food" />
</form>
<a href="#" class="w-[104px] h-14 flex items-center justify-center bg-secondary/10 text-secondary text-[16px] font-semibold leading-6 rounded-[12px] transition-all duration-300 hover:shadow-secondary"> Log In </a>
</div>
</div>
</header>
Jadi header di sini ibarat pintu gerbang keren yang nyambut pengunjung waktu mereka buka web kamu. Dibungkus dengan padding kiri-kanan 60px dan jarak atas 60px biar nggak mepet, tampilannya jadi lega dan enak dipandang.
Di dalamnya ada container utama yang pakai flex buat ngejalanin semua item secara horizontal dan rapi: navigasi, logo, sama area search + login.
Navigasi (nav):
Ini kayak peta jalan buat pengunjung. Ada beberapa menu utama yang kamu kasih gaya kece supaya interaktif:
Home, Services, About Us: tiap menu ini ada underline halus yang muncul pas kamu hover, kayak lampu yang nyala, biar pengunjung tau lagi hover di mana.Category Dropdown: Ini bagian spesial. Kamu bikin dropdown yang pas di-hover atau diklik, muncul menu pilihan makanan, minuman, sama dessert. Tombolnya ada icon panah kecil yang animasi halus muter saat dropdown dibuka, biar keliatan hidup dan jelas.
Logo:
Tengah-tengah ada logo kamu yang keren, ukurannya pas biar nggak terlalu gede tapi tetap eye-catching. Jadi kayak tanda pengenal yang selalu ada di tengah panggung.
Search dan Login:
Di kanan, kamu punya form search yang tampilannya stylish, lengkap dengan ikon kaca pembesar. Saat kamu klik di kolom search, muncul efek ring warna secondary yang bikin terasa interaktif dan profesional.
Di sebelahnya ada tombol “Log In” yang simple tapi punya hover efek dengan bayangan halus jadi ngajak banget pengunjung buat klik dan masuk.
Main
<main>
<!-- Ads Section -->
<section class="relative flex justify-center">
...
</section>
<!-- Why us? -->
<section class="flex justify-center">
...
</section>
<!-- Popular restaurant -->
<section class="flex justify-center">
...
</section>
<!-- Near you restaurant -->
<section class="flex justify-center">
...
</section>
<!-- Expert chef -->
<section class="mt-[60px] mb-[123px] flex justify-center">
...
</section>
</main>
Bayangin <main> ini kayak etalase utama di toko kamu, tempat semua hal menarik dan andalan ditampilkan buat pengunjung.
Di sini, kamu punya beberapa section yang berjajar rapi, masing-masing punya perannya sendiri:
Ads Section: Ini semacam billboard digital kamu, tempat kamu pasang iklan keren atau promo spesial biar pengunjung langsung tergoda dan ngelirik.Why Us?: Nah, ini kayak momen kamu ngejelasin kenapa pengunjung harus pilih tempat kamu. Bisa berisi alasan-alasan kece yang bikin kamu beda dan layak dipilih.Popular Restaurant: Di sini kamu pamerin restoran-restoran hits yang lagi naik daun. Jadi pengunjung bisa langsung lihat mana yang lagi favorit orang banyak.Near You Restaurant: Sekarang makin personal! Bagian ini ngasih rekomendasi restoran yang deket sama lokasi pengunjung, biar mereka gampang cari makan tanpa jauh-jauh.Expert Chef: Ini bagian yang kasih sentuhan spesial, ngenalin chef-chef jagoan yang bikin makanan di restoran kamu makin spesial. Dengan jarak atas dan bawah yang pas, tampilannya jadi bernafas dan elegan.
Ads Section
Resto - Ads Section
<section class="relative flex justify-center">
<div class="swiper !pl-[140px] !pr-[60px]">
<div class="swiper-wrapper flex py-[60px]">
<!-- Item 1 -->
<div class="group swiper-slide relative !w-[1128px] !h-[564px]">
<div class="w-full h-full rounded-3xl overflow-clip">
<img src="./assets/images/thumbnails/ads-1.png" alt="" class="object-cover w-full" />
</div>
<div class="absolute transition-all duration-300 opacity-0 group-hover:opacity-100 flex flex-col gap-1 -left-20 top-[133px] bottom-[134px] h-[297px] w-[390px] rounded-3xl bg-white pl-6 py-6 pr-[140px]">
<div class="flex items-center h-[27px] w-[210px]">
<div class="flex gap-[6.5px] -mt-[3px] pr-[3px]">
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] shrink-0" />
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] shrink-0" />
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] shrink-0" />
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] shrink-0" />
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] shrink-0" />
</div>
<div class="flex gap-1 items-center">
<p class="text-lg leading-[27px] font-semibold text-star">5.0</p>
<p class="text-[16px] text-muted">(5.2K+)</p>
</div>
</div>
<h2 class="text-[22px] font-semibold leading-[33px]">Padang Restaurant</h2>
<p class="text-lg font-semibold leading-[27px] text-muted">IDR 49.999 - IDR 560.000</p>
<div class="flex gap-1.5 items-center">
<div class="h-6 w-6 flex items-center justify-center">
<img src="./assets/images/icons/Location.svg" alt="" class="h-6 w-6" />
</div>
<p class="text-[16px] leading-6 text-muted">Padang, Indonesia</p>
</div>
<div class="mt-[30px] flex flex-col gap-3">
<a href="#" class="flex items-center justify-center text-[16px] font-semibold leading-6 bg-primary rounded-[12px] w-[226px] h-14 hover:shadow-primary transition-all duration-300">
<span>Make Reservation</span>
<img src="./assets/images/icons/arrow_right.svg" alt="" class="" />
</a>
<div class="flex gap-1.5 items-center">
<img src="./assets/images/icons/info_square.svg" alt="" class="h-6 w-6" />
<p class="text-[16px] leading-6 text-muted">No extra cost</p>
</div>
</div>
</div>
</div>
<!-- Item 2 -->
<div class="group swiper-slide relative !w-[1128px] !h-[564px]">
<!-- ini image -->
<div class="w-full h-full rounded-3xl overflow-clip">
<img src="./assets/images/thumbnails/ads-2.png" alt="" class="object-cover w-full" />
</div>
<!-- ini details -->
<div class="absolute transition-all duration-300 opacity-0 group-hover:opacity-100 flex flex-col gap-1 -left-20 top-[133px] bottom-[134px] h-[297px] w-[390px] rounded-3xl bg-white pl-6 py-6 pr-[140px]">
<div class="flex items-center h-[27px] w-[210px]">
<div class="flex gap-[6.5px] -mt-[3px] pr-[3px]">
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] shrink-0" />
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] shrink-0" />
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] shrink-0" />
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] shrink-0" />
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] shrink-0" />
</div>
<div class="flex gap-1 items-center">
<p class="text-lg leading-[27px] font-semibold text-star">5.0</p>
<p class="text-[16px] text-muted">(5.2K+)</p>
</div>
</div>
<h2 class="text-[22px] font-semibold leading-[33px]">Jember Restaurant</h2>
<p class="text-lg font-semibold leading-[27px] text-muted">IDR 39.999 - IDR 460.000</p>
<div class="flex gap-1.5 items-center">
<div class="h-6 w-6 flex items-center justify-center">
<img src="./assets/images/icons/Location.svg" alt="" class="h-6 w-6" />
</div>
<p class="text-[16px] leading-6 text-muted">Jember, Indonesia</p>
</div>
<div class="mt-[30px] flex flex-col gap-3">
<a href="#" class="flex items-center justify-center text-[16px] font-semibold leading-6 bg-primary rounded-[12px] w-[226px] h-14 hover:shadow-primary transition-all duration-300">
<span>Make Reservation</span>
<img src="./assets/images/icons/arrow_right.svg" alt="" class="" />
</a>
<div class="flex gap-1.5 items-center">
<img src="./assets/images/icons/info_square.svg" alt="" class="h-6 w-6" />
<p class="text-[16px] leading-6 text-muted">No extra cost</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
Bagian HTML ini tuh kayak etalase digital yang keren banget buat nunjukin restoran-restoran kece pakai Swiper.js. Bayangin kamu lagi liat-liat brosur restoran, tapi versi modern, tinggal geser aja. Setiap slide itu semacam kartu gede berisi gambar restoran yang menggoda. Nah, pas kamu arahkan kursor ke gambarnya, langsung muncul detail kayak rating bintang lima, nama tempat, harga, sampai tombol buat langsung reservasi. Semuanya muncul mulus kayak sulap gara-gara efek opacity yang berubah waktu kamu hover.
Slide-nya sendiri ukurannya udah diset fix biar tampilannya konsisten dan mantap, jadi kamu nggak perlu khawatir layout-nya acak-acakan. Gambar restorannya dibikin full tampil biar kesan "wah" langsung dapet. Terus bagian infonya muncul di sebelah kiri gambar, kayak pop-up brosur kecil yang nyodorin promo pas kamu lagi lewat. Kesan interaktif dan mewahnya dapet banget deh, cocok kalau kamu mau bikin orang langsung pengen booking tempat dari tampilan pertama.
Why us?
Resto - Why us? section
<section class="flex justify-center">
<div class="w-[1320px] m-[60px]">
<div class="flex w-fit mx-auto flex-col gap-1.5 text-center mb-[41px]">
<span class="text-[16px] leading-6 font-semibold text-secondary uppercase">Special Benefit For You</span>
<h2 class="text-[28px] leading-[42px] font-semibold">Why Should Choose Us?</h2>
</div>
<div class="flex w-full gap-5">
<!-- Item 1 -->
<div class="flex flex-col gap-[54px] h-fit pt-6 min-h-[347px] w-[315px] bg-white rounded-3xl">
<div class="flex flex-col gap-6">
<div class="ml-[117px] mr-[118px] flex items-center justify-center h-20 w-20 rounded-full bg-primary/15">
<img src="./assets/images/icons/discount.svg" alt="" class="h-[58px] w-[58px]" />
</div>
<h3 class="text-lg leading-[27px] font-semibold text-center">Extra Discounts</h3>
<p class="w-[267px] -mt-3 mx-6 text-[16px] leading-6 text-muted text-center">Get your special discount by using our reservation</p>
</div>
<a href="#" class="w-full mt-auto h-[72px] flex items-center justify-center text-[16px] leading-6 font-semibold rounded-t-xl rounded-b-3xl transition-all duration-300 hover:bg-primary">
<span>View Details</span>
<img src="./assets/images/icons/arrow_right.svg" alt="" class="h-6 w-6" />
</a>
</div>
<!-- Item 2 -->
<div class="flex flex-col gap-[54px] h-fit pt-6 min-h-[347px] w-[315px] bg-white rounded-3xl">
<div class="flex flex-col gap-6">
<div class="ml-[117px] mr-[118px] flex items-center justify-center h-20 w-20 rounded-full bg-primary/15">
<img src="./assets/images/icons/eat.svg" alt="" class="h-[58px] w-[58px]" />
</div>
<h3 class="text-lg leading-[27px] font-semibold text-center">Come and Eat</h3>
<p class="w-[267px] -mt-3 mx-6 text-[16px] leading-6 text-muted text-center">Get your own table quickly & without waiting in line</p>
</div>
<a href="#" class="w-full mt-auto h-[72px] flex items-center justify-center text-[16px] leading-6 font-semibold rounded-t-xl rounded-b-3xl transition-all duration-300 hover:bg-primary">
<span>View Details</span>
<img src="./assets/images/icons/arrow_right.svg" alt="" class="h-6 w-6" />
</a>
</div>
<!-- Item 3 -->
<div class="flex flex-col gap-[54px] h-fit pt-6 min-h-[347px] w-[315px] bg-white rounded-3xl">
<div class="flex flex-col gap-6">
<div class="ml-[117px] mr-[118px] flex items-center justify-center h-20 w-20 rounded-full bg-primary/15">
<img src="./assets/images/icons/cost.svg" alt="" class="h-[58px] w-[58px]" />
</div>
<h3 class="text-lg leading-[27px] font-semibold text-center">No Extra Fee</h3>
<p class="w-[267px] -mt-3 mx-6 text-[16px] leading-6 text-muted text-center">Get tax free if you want to order food and make a reservation</p>
</div>
<a href="#" class="w-full mt-auto h-[72px] flex items-center justify-center text-[16px] leading-6 font-semibold rounded-t-xl rounded-b-3xl transition-all duration-300 hover:bg-primary">
<span>View Details</span>
<img src="./assets/images/icons/arrow_right.svg" alt="" class="h-6 w-6" />
</a>
</div>
<!-- Item 4 -->
<div class="flex flex-col gap-[54px] h-fit pt-6 min-h-[347px] w-[315px] bg-white rounded-3xl">
<div class="flex flex-col gap-6">
<div class="ml-[117px] mr-[118px] flex items-center justify-center h-20 w-20 rounded-full bg-primary/15">
<img src="./assets/images/icons/sparkle.svg" alt="" class="h-[58px] w-[58px]" />
</div>
<h3 class="text-lg leading-[27px] font-semibold text-center">Guaranteed Cleanliness</h3>
<p class="w-[267px] -mt-3 mx-6 text-[16px] leading-6 text-muted text-center">We ensure the cleanliness of the place as well as the food</p>
</div>
<a href="#" class="w-full mt-auto h-[72px] flex items-center justify-center text-[16px] leading-6 font-semibold rounded-t-xl rounded-b-3xl transition-all duration-300 hover:bg-primary">
<span>View Details</span>
<img src="./assets/images/icons/arrow_right.svg" alt="" class="h-6 w-6" />
</a>
</div>
</div>
</div>
</section>
Pernah nggak sih kamu bingung mau pilih tempat makan atau booking restoran, tapi semua kelihatan sama aja? Nah, di sinilah kita beda! Bayangin kamu lagi cari tempat nongkrong yang nggak cuma enak makanannya, tapi juga punya extra diskon, bisa langsung datang tanpa nunggu, nggak ada biaya tambahan, dan pastinya tempatnya bersih kinclong kayak baru dipel tiap 5 menit. Semua benefit ini kita siapin biar kamu bisa dapetin pengalaman terbaik, tanpa ribet dan tanpa biaya yang bikin dompet meringis. Dan yang bikin tampilannya enak dilihat? Semua kontennya dibungkus dalam card layout yang elegan dan responsif pakai Tailwind CSS. Class kayak w-[315px], rounded-3xl, dan gap-[54px] bikin tiap kartu punya ukuran pas, sudut membulat yang modern, dan jarak antar elemen yang lapang banget.
Setiap kartu ini juga punya tombol View Details di bawahnya yang udah dikasih transisi halus (transition-all duration-300) jadi saat kamu hover, warnanya langsung berubah jadi lebih hidup (thanks to hover:bg-primary). Terus, biar ikon di atas judul kelihatan standout, kita masukin ke dalam lingkaran transparan (bg-primary/15) dengan tinggi-lebar 80px, yang bikin elemen visualnya jadi lebih "ngomong" tanpa bikin layout rame. Semuanya disusun pakai utility-first class dari Tailwind nggak pakai CSS tambahan yang ribet. Hasilnya? Tampilan bersih, struktur rapi, dan pastinya performa juga ringan. Desainnya udah disetting secara fleksibel dalam flex flex-col dan gap antar elemen yang bikin antar bagian nggak dempet-dempetan. Jadi kalau kamu lihat ini, bukan cuma enak dibaca, tapi juga feel-nya profesional dan friendly banget.
Popular restaurant
Resto - Popular restaurant Section
<section class="flex justify-center">
<div class="flex items-center w-[1320px] m-[60px]">
<div class="w-[367px]">
<div class="flex flex-col gap-1.5">
<span class="text-[16px] leading-6 font-semibold text-secondary uppercase">Top 3 Featured Restaurant</span>
<h2 class="w-full text-[28px] leading-[42px] font-semibold">Most Popular Restaurants</h2>
</div>
<p class="mt-5 w-[360px] pr-5 text-[16px] leading-6 text-muted">The best restaurant in our opinion is how much customers like it in terms of place, price, comfort and of course the taste of the food itself.</p>
<a href="#" class="mt-14 flex items-center justify-center text-[16px] leading-6 font-semibold h-[56px] w-[238px] bg-primary rounded-xl transition-all duration-300 hover:shadow-primary">
<span>View All Restaurant</span>
<img src="./assets/images/icons/arrow_right.svg" alt="" class="h-6 w-6" />
</a>
</div>
<div class="ml-[85px] flex gap-5">
<!-- Card 1 -->
<div class="card group transition-all duration-300 relative h-[475px] w-[400px] rounded-3xl overflow-clip shrink-0 hover:w-[400px]" data-card="1">
<img src="./assets/images/thumbnails/resto-1.png" alt="" class="object-cover w-full h-full" />
<div class="card-info transition-all duration-300 delay-1000 ease-in-out flex gap-2 p-6 items-center absolute left-6 bottom-6 right-6 bg-white rounded-3xl">
<div class="flex flex-col gap-1 w-[260px]">
<div class="flex items-center">
<img src="./assets/images/icons/star.svg" alt="" class="h-auto w-[18px] -mt-[3px] mr-[3px]" />
<p class="text-[16px] leading-6 font-semibold text-star mr-1">5.0</p>
<p class="text-[16px] leading-6 text-muted">(7.6K+)</p>
</div>
<h3 class="text-lg leading-[27px] font-semibold">Bind Balorant</h3>
<div class="flex gap-1.5">
<img src="./assets/images/icons/Location.svg" alt="" class="h-6 w-6" />
<p class="text-[16px] leading-6 text-muted">Jakarta, Indonesia</p>
</div>
</div>
<a href="#" class="flex items-center justify-center h-9 w-9 rounded-xl bg-primary shrink-0 transition-all duration-300 hover:shadow-primary">
<img src="./assets/images/icons/sign_right.svg" alt="" class="" />
</a>
</div>
</div>
<!-- Card 2 -->
<div class="card group transition-all duration-300 relative h-[475px] w-[214px] rounded-3xl overflow-clip shrink-0 hover:w-[400px]" data-card="2">
<img src="./assets/images/thumbnails/resto-2.png" alt="" class="object-cover h-full w-full" />
<div class="card-info transition-all duration-300 delay-1000 ease-in-out gap-2 p-6 items-center absolute left-6 bottom-6 right-6 bg-white rounded-3xl hidden">
<div class="flex flex-col gap-1 w-[260px]">
<div class="flex items-center">
<img src="./assets/images/icons/star.svg" alt="" class="h-auto w-[18px] -mt-[3px] mr-[3px]" />
<p class="text-[16px] leading-6 font-semibold text-star mr-1">4.8</p>
<p class="text-[16px] leading-6 text-muted">(5.2K+)</p>
</div>
<h3 class="text-lg leading-[27px] font-semibold">Green Garden</h3>
<div class="flex gap-1.5">
<img src="./assets/images/icons/Location.svg" alt="" class="h-6 w-6" />
<p class="text-[16px] leading-6 text-muted">Bandung, Indonesia</p>
</div>
</div>
<a href="#" class="flex items-center justify-center h-9 w-9 rounded-xl bg-primary shrink-0 transition-all duration-300 hover:shadow-primary">
<img src="./assets/images/icons/sign_right.svg" alt="" class="" />
</a>
</div>
</div>
<!-- Card 3 -->
<div class="card group transition-all duration-300 relative h-[475px] w-[214px] rounded-3xl overflow-clip shrink-0 hover:w-[400px]" data-card="3">
<img src="./assets/images/thumbnails/resto-3.png" alt="" class="object-cover h-full w-full" />
<div class="card-info transition-all duration-300 delay-1000 ease-in-out gap-2 p-6 items-center absolute left-6 bottom-6 right-6 bg-white rounded-3xl hidden">
<div class="flex flex-col gap-1 w-[260px]">
<div class="flex items-center">
<img src="./assets/images/icons/star.svg" alt="" class="h-auto w-[18px] -mt-[3px] mr-[3px]" />
<p class="text-[16px] leading-6 font-semibold text-star mr-1">4.9</p>
<p class="text-[16px] leading-6 text-muted">(6.8K+)</p>
</div>
<h3 class="text-lg leading-[27px] font-semibold">Sundanese Delight</h3>
<div class="flex gap-1.5">
<img src="./assets/images/icons/Location.svg" alt="" class="h-6 w-6" />
<p class="text-[16px] leading-6 text-muted">Sunda, Indonesia</p>
</div>
</div>
<a href="#" class="flex items-center justify-center h-9 w-9 rounded-xl bg-primary shrink-0 transition-all duration-300 hover:shadow-primary">
<img src="./assets/images/icons/sign_right.svg" alt="" class="" />
</a>
</div>
</div>
</div>
</div>
</section>
Kamu pernah lihat deretan restoran yang langsung bikin kamu pengen klik salah satunya? Nah, bagian ini tuh kayak etalase yang ditata rapi dan glowing biar kamu tinggal pilih tanpa mikir dua kali. Di sebelah kiri, ada teks pengantar yang fungsinya kayak MC: ngenalin kamu ke tiga restoran paling favorit versi kita. Dengan struktur flex justify-center dan container w-[1320px], semuanya udah diposisikan pas di tengah layar. Terus bagian infonya dikemas rapi dalam lebar w-[367px], lengkap dengan heading “Most Popular Restaurants” dan subjudul kecil buat narik perhatian mata. Oh, dan tombol “View All Restaurant” itu bukan tombol biasa udah dikasih animasi transisi hover:shadow-primary yang bikin efek glowing halus setiap kamu arahkan kursor, kayak ngajak kamu buat eksplor lebih jauh.
Sekarang kita ke bagian yang seru tiga kartu restoran yang tampilannya keren banget. Bayangin ini kayak tiga showcase makanan, satu lagi besar di depan, dua lainnya ngintip di samping. Kartu pertama dikasih lebar penuh w-[400px], sedangkan dua lainnya lebih ramping w-[214px], tapi semuanya punya trik rahasia: hover interaktif. Begitu kamu arahkan mouse ke kartu mana pun, ukurannya langsung membesar jadi hover:w-[400px], seolah-olah bilang "eh, aku nih yang kamu cari!" Ini dimungkinkan karena kita pakai Tailwind transition-all duration-300, jadi semua perubahan ukuran terasa mulus. Tiap kartu juga punya lapisan info yang muncul dari bawah dengan absolute bottom-6 left-6 right-6 dan bg-white rounded-3xl, lengkap sama rating, lokasi, nama restoran, dan tombol masuk kecil berikon.
Dan yang bikin makin ciamik, info dua kartu samping awalnya disembunyiin (hidden) dan baru ditampilin saat interaksi (nanti bisa dikontrol pakai JS atau toggle class di hover). Jadi kamu bisa bikin UX yang dinamis banget hanya dengan mainin kombinasi class Tailwind dan sedikit logika interaktif. Ini bukan cuma pamer visual, ini storytelling visual yang ngajak user buat penasaran, eksplor, dan akhirnya klik.
Near you restaurant
Resto - Near you restaurant Section
<section class="flex justify-center">
<div class="flex flex-col gap-[34px] w-[1321px] m-[60px]">
<div class="flex w-full items-center justify-between">
<div class="flex flex-col gap-1.5">
<span class="text-[16px] leading-6 font-semibold text-secondary uppercase">Restaurant Based by City</span>
<h2 class="w-full text-nowrap text-[28px] leading-[42px] font-semibold">Restaurant Near You</h2>
</div>
<div class="relative dropdown flex flex-col">
<button type="button" class="dropdown-button flex cursor-pointer gap-1.5 px-6 py-5 items-center h-[64px] w-[252px] rounded-xl bg-[#f2f2f2]">
<img src="./assets/images/icons/Location.svg" alt="" class="" />
<div class="flex">
<p class="text-[16px] leading-6 font-medium text-muted">Jakarta, Indonesia</p>
<div class="flex items-center justify-center h-6 w-6">
<img src="./assets/images/icons/arrow_bottom.svg" alt="" class="dropdown-arrow transition-all duration-300" />
</div>
</div>
</button>
<ul class="dropdown-menu z-50 opacity-0 transition-all duration-300 absolute top-full left-0 mt-2 min-w-[150px] flex-col gap-1.5 bg-white rounded-xl py-2.5 shadow-lg">
<li class="group">
<button type="button" class="flex cursor-pointer gap-1.5 px-6 py-5 items-center h-[64px] w-[252px] transition-all duration-300 hover:bg-[#f2f2f2]">
<img src="./assets/images/icons/Location.svg" alt="" class="" />
<div class="flex">
<p class="text-[16px] leading-6 font-medium text-muted">Bandung, Indonesia</p>
</div>
</button>
</li>
<li class="group">
<button type="button" class="flex cursor-pointer gap-1.5 px-6 py-5 items-center h-[64px] w-[252px] transition-all duration-300 hover:bg-[#f2f2f2]">
<img src="./assets/images/icons/Location.svg" alt="" class="" />
<div class="flex">
<p class="text-[16px] leading-6 font-medium text-muted">Bali, Indonesia</p>
</div>
</button>
</li>
<li class="group">
<button type="button" class="flex cursor-pointer gap-1.5 px-6 py-5 items-center h-[64px] w-[252px] transition-all duration-300 hover:bg-[#f2f2f2]">
<img src="./assets/images/icons/Location.svg" alt="" class="" />
<div class="flex">
<p class="text-[16px] leading-6 font-medium text-muted">Jember, Indonesia</p>
</div>
</button>
</li>
</ul>
</div>
</div>
<div class="flex gap-5">
<!-- Item 1 -->
<div class="relative h-[415px] w-[427px] rounded-3xl overflow-clip shrink-0">
<img src="./assets/images/thumbnails/near-1.png" alt="" class="object-cover w-full h-full" />
<div class="flex gap-[35px] p-6 items-center absolute left-6 bottom-[33px] right-6 bg-white rounded-3xl">
<div class="flex flex-col gap-1 w-[260px]">
<div class="flex items-center">
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] -mt-[3.5px] mr-[3px]" />
<p class="text-[16px] leading-6 font-semibold text-star mr-1">5.0</p>
<p class="text-[16px] leading-6 text-muted">(6.6K+)</p>
</div>
<h3 class="text-lg leading-[27px] font-semibold">Batavia Restaurant</h3>
<p class="text-lg font-semibold leading-6 text-muted">IDR 29.000 - IDR 259.999</p>
</div>
<a href="#" class="flex items-center justify-center h-9 w-9 rounded-xl bg-primary shrink-0 transition-all duration-300 hover:shadow-primary">
<img src="./assets/images/icons/sign_right.svg" alt="" class="" />
</a>
</div>
</div>
<!-- Item 2 -->
<div class="relative h-[415px] w-[427px] rounded-3xl overflow-clip shrink-0">
<img src="./assets/images/thumbnails/near-2.png" alt="" class="object-cover w-full h-full" />
<div class="flex gap-[35px] p-6 items-center absolute left-6 bottom-[33px] right-6 bg-white rounded-3xl">
<div class="flex flex-col gap-1 w-[260px]">
<div class="flex items-center">
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] -mt-[3.5px] mr-[3px]" />
<p class="text-[16px] leading-6 font-semibold text-star mr-1">5.0</p>
<p class="text-[16px] leading-6 text-muted">(3.6K+)</p>
</div>
<h3 class="text-lg leading-[27px] font-semibold">Split Ascent Restaurant</h3>
<p class="text-lg font-semibold leading-6 text-muted">IDR 49.999 - IDR 560.000</p>
</div>
<a href="#" class="flex items-center justify-center h-9 w-9 rounded-xl bg-primary shrink-0 transition-all duration-300 hover:shadow-primary">
<img src="./assets/images/icons/sign_right.svg" alt="" class="" />
</a>
</div>
</div>
<!-- Item 3 -->
<div class="relative h-[415px] w-[427px] rounded-3xl overflow-clip shrink-0">
<img src="./assets/images/thumbnails/near-3.png" alt="" class="object-cover w-full h-full" />
<div class="flex gap-[35px] p-6 items-center absolute left-6 bottom-[33px] right-6 bg-white rounded-3xl">
<div class="flex flex-col gap-1 w-[260px]">
<div class="flex items-center">
<img src="./assets/images/icons/star.svg" alt="" class="w-[18px] -mt-[3.5px] mr-[3px]" />
<p class="text-[16px] leading-6 font-semibold text-star mr-1">5.0</p>
<p class="text-[16px] leading-6 text-muted">(11K+)</p>
</div>
<h3 class="text-lg leading-[27px] font-semibold">Daza Fracture Restaurant</h3>
<p class="text-lg font-semibold leading-6 text-muted">IDR 29.999 - IDR 560.000</p>
</div>
<a href="#" class="flex items-center justify-center h-9 w-9 rounded-xl bg-primary shrink-0 transition-all duration-300 hover:shadow-primary">
<img src="./assets/images/icons/sign_right.svg" alt="" class="" />
</a>
</div>
</div>
</div>
<a href="#" class="mt-[22px] mx-auto flex items-center justify-center h-14 w-[238px] bg-primary rounded-xl text-[16px] leading-6 font-semibold transition-all duration-300 hover:shadow-primary">
<span>View All Restaurant</span>
<img src="./assets/images/icons/arrow_right.svg" alt="" class="h-6 w-6" />
</a>
</div>
</section>
<section> ini kerja kayak wrapper utama yang pake Flexbox buat nge-center semua konten secara horizontal. Di dalamnya ada sebuah <div> container yang diatur pakai flex-col biar isinya berdiri vertikal dengan jarak (gap) 34px antar elemen, kayak kamu ngatur layout pake CSS Flexbox supaya rapi dan responsif. Ukuran lebar container juga fixed di 1321px dan ada margin 60px buat kasih ruang di sekitar, jadi tampilannya nggak nempel ke tepi layar.
Bagian header-nya diatur pake Flexbox juga, justify-between supaya judul di kiri dan dropdown lokasi di kanan bisa “menjauh” saling berjauhan. Dropdown ini pakai positioning relative dan absolute buat dropdown menunya, yang awalnya opacity-0 dan disembunyiin, lalu muncul dengan animasi transisi halus (transition-all duration-300) saat tombol diklik. Tombolnya sendiri dikasih padding, rounded corners, dan background abu-abu muda buat kasih kesan tombol interaktif yang ramah buat user.
Nah, bawahnya ada tiga card restoran yang ukurannya fixed (lebar 427px, tinggi 415px), tiap card pakai overflow-clip dan rounded-3xl supaya gambar dan konten gak keluar batas dan tampilannya jadi elegan. Gambar restoran dipasang dengan object-cover supaya memenuhi kotak tanpa nge-distorsi. Di bagian bawah tiap kartu, info restoran dikemas dalam flex dengan jarak antar elemen yang pas, plus tombol action kecil yang diberi efek hover shadow buat interaksi lebih hidup. Terakhir ada tombol “View All Restaurant” yang desainnya eye-catching, dengan ukuran fixed dan efek hover untuk meningkatkan user engagement.
Expert chef
Resto - Expert chef Section
<section class="mt-[60px] mb-[123px] flex justify-center">
<div class="flex items-center gap-[64px] w-[1321px]">
<!-- Tab content -->
<div class="tab-content relative h-[848px] w-[660px]">
<div class="absolute left-[60px] right-10 h-full w-[560px] rounded-3xl overflow-clip">
<img src="./assets/images/thumbnails/chef-1.png" alt="" class="object-cover w-full h-full" loading="lazy" />
</div>
<div class="absolute top-10 right-0 px-[46px] py-[30px] flex flex-col items-center h-[203px] w-[179px] bg-white rounded-3xl drop-shadow-custom">
<div class="mb-3 flex items-center justify-center h-20 w-20 bg-[#FFF7ED] rounded-full">
<img src="./assets/images/icons/shield.svg" alt="" class="h-[50px] w-[50px] shrink-0" />
</div>
<div class="w-[87px] text-center">
<p class="experience-years text-lg leading-[27px] font-semibold">12 Years</p>
<p class="text-[16px] leading-6 text-muted">Experience</p>
</div>
</div>
<div class="p-6 absolute left-0 bottom-10 flex items-center gap-3 h-auto w-[330px] rounded-3xl bg-white drop-shadow-custom2">
<div class="h-[132px] w-[96px] rounded-xl overflow-clip shrink-0">
<img src="./assets/images/thumbnails/resto-4.png" alt="" class="object-cover w-full h-full" />
</div>
<div class="w-[174px] h-auto">
<div class="flex flex-col gap-6">
<div class="flex flex-col gap-1">
<span class="text-[16px] leading-6 text-muted">Chef at restaurant:</span>
<p class="resto-name text-lg leading-[27px] font-semibold">Pearl Dolphin</p>
</div>
<a href="#" class="flex text-[16px] leading-6 font-semibold text-primary">
<span>View Details</span>
<div class="flex items-center justify-center h-6 w-6 mask-[url('./assets/images/icons/arrow_right.svg')] mask-no-repeat mask-contain bg-primary">
<img src="./assets/images/icons/arrow_right.svg" alt="" class="opacity-0" />
</div>
</a>
</div>
</div>
</div>
</div>
<div class="flex flex-col gap-8 w-[596px]">
<div class="flex flex-col gap-1">
<span class="text-[18px] leading-6 font-semibold text-secondary uppercase">Top 4 Expert Chefs</span>
<h2 class="w-full text-nowrap text-[32px] leading-[48px] font-semibold">Expert Chefs In Fuddy</h2>
</div>
<!-- Tab menu -->
<div class="tab-menu flex flex-col gap-5">
<!-- Tab item 1 -->
<div class="tab-item cursor-pointer p-6 flex flex-col gap-1.5 h-[141px] w-[596px] rounded-3xl group transition-all duration-300 hover:bg-white">
<span class="text-[16px] leading-6 font-medium text-muted uppercase">Pizza</span>
<div class="w-full flex items-center justify-between">
<h2 class="text-[22px] leading-[33px] font-semibold line-clamp-1 mr-0.5">Phoenix Satcheup</h2>
<a href="#" class="flex text-[16px] opacity-100 leading-6 font-medium text-primary shrink-0">
<span>Profile Details</span>
<div class="flex items-center justify-center h-6 w-6 mask-[url('./assets/images/icons/arrow_right.svg')] mask-no-repeat mask-contain bg-primary shrink-0">
<img src="./assets/images/icons/arrow_right.svg" alt="" class="opacity-0" />
</div>
</a>
</div>
<div class="flex items-center gap-1.5">
<div class="location-icon transition-all duration-300 mask-[url('./assets/images/icons/Location.svg')] mask-no-repeat mask-contain">
<img src="./assets/images/icons/Location.svg" alt="" class="h-6 w-6 opacity-0" />
</div>
<p class="text-[16px] leading-6 text-muted">Jakarta, Indonesia</p>
</div>
</div>
<!-- Tab item 2 -->
<div class="tab-item cursor-pointer p-6 flex flex-col gap-1.5 h-[141px] w-[596px] rounded-3xl group transition-all duration-300 hover:bg-white">
<span class="text-[16px] leading-6 font-medium text-muted uppercase">Vegan</span>
<div class="w-full flex items-center justify-between">
<h2 class="text-[22px] leading-[33px] font-semibold line-clamp-1 mr-0.5">Chamber Botfrag</h2>
<a href="#" class="opacity-0 flex text-[16px] leading-6 font-medium text-primary shrink-0">
<span>Profile Details</span>
<div class="flex items-center justify-center h-6 w-6 mask-[url('./assets/images/icons/arrow_right.svg')] mask-no-repeat mask-contain bg-primary shrink-0">
<img src="./assets/images/icons/arrow_right.svg" alt="" class="opacity-0" />
</div>
</a>
</div>
<div class="flex items-center gap-1.5">
<div class="location-icon transition-all duration-300 mask-[url('./assets/images/icons/Location.svg')] mask-no-repeat mask-contain bg-foreground">
<img src="./assets/images/icons/Location.svg" alt="" class="h-6 w-6 opacity-0" />
</div>
<p class="text-[16px] leading-6 text-muted">Bandung, Indonesia</p>
</div>
</div>
<!-- Tab item 3 -->
<div class="tab-item cursor-pointer p-6 flex flex-col gap-1.5 h-[141px] w-[596px] rounded-3xl group transition-all duration-300 hover:bg-white">
<span class="text-[16px] leading-6 font-medium text-muted uppercase">Roast Chicken</span>
<div class="w-full flex items-center justify-between">
<h2 class="text-[22px] leading-[33px] font-semibold line-clamp-1 mr-0.5">Asep Vandal</h2>
<a href="#" class="opacity-0 flex text-[16px] leading-6 font-medium text-primary shrink-0">
<span>Profile Details</span>
<div class="flex items-center justify-center h-6 w-6 mask-[url('./assets/images/icons/arrow_right.svg')] mask-no-repeat mask-contain bg-primary">
<img src="./assets/images/icons/arrow_right.svg" alt="" class="opacity-0" />
</div>
</a>
</div>
<div class="flex items-center gap-1.5">
<div class="location-icon transition-all duration-300 mask-[url('./assets/images/icons/Location.svg')] mask-no-repeat mask-contain bg-foreground shrink-0">
<img src="./assets/images/icons/Location.svg" alt="" class="h-6 w-6 opacity-0" />
</div>
<p class="text-[16px] leading-6 text-muted">Sunda, Indonesia</p>
</div>
</div>
<!-- Tab item 4 -->
<div class="tab-item cursor-pointer p-6 flex flex-col gap-1.5 h-[141px] w-[596px] rounded-3xl group transition-all duration-300 hover:bg-white">
<span class="text-[16px] leading-6 font-medium text-muted uppercase">Beef Steak</span>
<div class="w-full flex items-center justify-between">
<h2 class="text-[22px] leading-[33px] font-semibold line-clamp-1 mr-0.5">I Made Invoker</h2>
<a href="#" class="opacity-0 flex text-[16px] leading-6 font-medium text-primary shrink-0">
<span>Profile Details</span>
<div class="flex items-center justify-center h-6 w-6 mask-[url('./assets/images/icons/arrow_right.svg')] mask-no-repeat mask-contain bg-primary">
<img src="./assets/images/icons/arrow_right.svg" alt="" class="opacity-0" />
</div>
</a>
</div>
<div class="flex items-center gap-1.5">
<div class="location-icon transition-all duration-300 mask-[url('./assets/images/icons/Location.svg')] mask-no-repeat mask-contain bg-foreground shrink-0">
<img src="./assets/images/icons/Location.svg" alt="" class="h-6 w-6 opacity-0" />
</div>
<p class="text-[16px] leading-6 text-muted">Bali, Indonesia</p>
</div>
</div>
</div>
<a href="#" class="mt-[30px] w-fit flex items-center justify-center text-[16px] leading-6 font-semibold px-7 py-4 bg-primary rounded-xl transition-all duration-300 hover:shadow-primary">
<span>View All Chef</span>
<div class="flex items-center justify-center h-6 w-6 shrink-0">
<img src="./assets/images/icons/arrow_right.svg" alt="" class="" />
</div>
</a>
</div>
</div>
</section>
Kamu lihat di <section> ini, layoutnya tuh pakai Flexbox buat nge-center konten utama, jadi semuanya rapi di tengah layar. Di dalamnya ada dua bagian utama yang ukurannya fixed banget: satu sisi buat tampilin gambar chef yang kece dengan style absolute dan overflow-clip supaya gambarnya ngga keluar batas rounded-3xl, dan di atas gambar itu ada kartu info pengalaman chef yang dikasih drop shadow dan rounded buat bikin kesan keren dan profesional banget. Nah, gambar dan info ini diatur pakai position: absolute supaya bisa layering yang cakep, kayak main layer di design UI.
Di sebelah kanan, kamu punya bagian tab menu yang isinya list chef-chef top yang keren banget. Masing-masing tab item itu clickable dengan efek hover halus (transition-all duration-300 hover:bg-white), pakai flex buat ngatur isi seperti nama chef, jenis masakan, dan lokasi dengan ikon location yang di-mask supaya tampilannya elegan. Teknik line-clamp-1 juga dipakai buat ngebatesin teks supaya ngga kelewat panjang dan tetap rapi tanpa pecah layout. Ini kayak kamu ngatur UI supaya user gampang scroll dan fokus ke satu chef tanpa kebingungan.
Terakhir, ada tombol “View All Chef” yang desainnya eye-catching, dengan background bg-primary, padding dan rounded corners, plus efek shadow saat hover biar tombolnya kayak manggil-manggil kamu buat klik. Tombol ini pake flexbox juga supaya teks dan icon panahnya sejajar rapi. Intinya, struktur dan stylingnya padu banget pakai teknik CSS modern kayak flex, positioning absolute, mask, dan transition biar user experience kamu makin smooth dan keren.
Kode JavaScript
card.js
document.addEventListener("DOMContentLoaded", () => {
const cards = document.querySelectorAll(".card");
// Fungsi untuk mengatur lebar dan tampilan card info
function updateCards() {
cards.forEach((card) => {
const cardInfo = card.querySelector(".card-info");
if (card.classList.contains("active")) {
card.style.width = "400px";
cardInfo.classList.remove("hidden");
cardInfo.classList.add("flex");
} else {
card.style.width = "214px";
cardInfo.classList.remove("flex");
cardInfo.classList.add("hidden");
}
});
}
// Inisialisasi card pertama sebagai aktif
cards[0].classList.add("active");
updateCards();
// Tambahkan event listener untuk hover
cards.forEach((card) => {
card.addEventListener("mouseenter", () => {
cards.forEach((c) => c.classList.remove("active"));
card.classList.add("active");
updateCards();
});
card.addEventListener("mouseleave", () => {
cards.forEach((c) => c.classList.remove("active"));
cards[0].classList.add("active"); // Kembalikan ke card pertama
updateCards();
});
});
});
Kode ini kayak bikin sebuah “slider” atau “carousel” kartu yang interaktif. Begitu halaman kamu selesai dimuat (DOMContentLoaded), skrip ini bakal cari semua elemen dengan kelas .card. Nah, tiap card itu nanti bisa “aktif” atau “nggak aktif” yang aktif ukurannya lebih gede (400px) dan bakal nampilin info tambahan ( .card-info ) pakai class flex, sedangkan yang nggak aktif ukurannya kecil (214px) dan info-nya disembunyiin dengan class hidden. Jadi ini kayak kamu lagi main highlight di antara beberapa kartu, yang lagi dipilih bakal lebih stand out dan jelas tampilannya.
Terus, biar makin keren, tiap kali kamu hover (alias mouse masuk ke card), event listener mouseenter bakal otomatis ngehapus class active di semua card, terus pasang lagi di card yang kamu hover itu. Jadi ukurannya langsung nge-resize dinamis, pakai updateCards() yang nge-handle perubahan width dan tampilan info-nya secara real-time. Nah, kalau mouse keluar dari card (mouseleave), script ini bakal balikin highlight ke card pertama kayak reset posisi supaya user nggak bingung, tetap ada yang aktif terus.
Jadi, kalau kamu pikir ini kayak efek “spotlight” di panggung, di mana spotlight cuma fokus ke satu aktor (card) sekaligus, dan aktor yang lain jadi lebih kecil sambil informasi detailnya disembunyiin. Kode ini ngandelin DOM manipulation dan classList API buat ngatur class CSS dan style inline langsung. Simple tapi powerful buat bikin UI yang responsif dan asik dipakai.
dropdown.js
document.addEventListener("DOMContentLoaded", () => {
// Ambil semua tombol dropdown, menu, dan panah
const dropdownButtons = document.querySelectorAll(".dropdown-button");
const dropdownMenus = document.querySelectorAll(".dropdown-menu");
const dropdownArrows = document.querySelectorAll(".dropdown-arrow");
// Fungsi untuk menangani klik pada tombol dropdown
dropdownButtons.forEach((button, index) => {
const menu = dropdownMenus[index];
const arrow = dropdownArrows[index];
button.addEventListener("click", () => {
if (menu.classList.contains("opacity-0")) {
// Sembunyikan semua dropdown lainnya
dropdownMenus.forEach((m) => {
m.classList.add("opacity-0");
m.classList.remove("opacity-100");
});
dropdownArrows.forEach((a) => (a.style.transform = "rotate(0deg)"));
// Tampilkan dropdown yang dipilih
menu.classList.remove("opacity-0");
menu.classList.add("opacity-100");
arrow.style.transform = "rotate(180deg)";
} else {
// Sembunyikan dropdown saat diklik lagi
menu.classList.remove("opacity-100");
menu.classList.add("opacity-0");
arrow.style.transform = "rotate(0deg)";
}
});
});
// Fungsi untuk menutup dropdown saat mengklik di luar
document.addEventListener("click", (event) => {
dropdownButtons.forEach((button, index) => {
const menu = dropdownMenus[index];
const arrow = dropdownArrows[index];
if (!button.contains(event.target) && !menu.contains(event.target)) {
menu.classList.remove("opacity-100");
menu.classList.add("opacity-0");
arrow.style.transform = "rotate(0deg)";
}
});
});
});
bayangin kamu lagi main sulap dengan dropdown di web, nah kode ini adalah “sihir” yang bikin dropdown-mu hidup! Jadi, pas halaman udah kelar dimuat (DOMContentLoaded), script ini bakal ngambil semua tombol dropdown (.dropdown-button), menu dropdown (.dropdown-menu), sama ikon panahnya (.dropdown-arrow). Intinya, tiap kali kamu klik tombol dropdown, script ini ngecek apakah menu dropdown-nya lagi tersembunyi atau nggak, pakai class CSS opacity-0 buat sembunyiin dan opacity-100 buat nampilin dengan efek transparansi. Jadi dropdownnya kayak magic muncul dan hilang.
Terus, supaya nggak ribet dan rapi, kode ini juga bikin aturan kalau kamu klik satu tombol, semua dropdown lain langsung ditutup dulu. Ini biar gak ada yang buka banyak-banyak sekaligus dan bikin halaman jadi berantakan. Selain itu, ikon panahnya juga ikutan muter 180 derajat pas dropdown kebuka, kayak tanda panah lagi “ngasih kode” ke kamu, ini pakai manipulasi CSS transform: rotate(). Jadi gak cuma dropdown-nya yang interaktif, tapi ikon panahnya juga ikut ngejalanin animasi biar user experience-nya makin keren.
Nah, ada juga bagian yang jenius nih, kalau kamu klik di luar dropdown atau tombolnya, dropdown otomatis nutup sendiri. Ini pake event listener di document yang ngecek target klik kamu, kalau kliknya bukan di tombol atau menu dropdown, ya semua dropdown langsung disembunyikan dan panah diputer balik lagi. Jadi kode ini pinter banget jaga-jaga supaya dropdown gak nyangkut kebuka terus, bikin UI kamu rapi dan enak dipakai. Jadi kamu bisa bilang, ini script dropdown-mu yang kerja kayak asisten pribadi, selalu siap buka tutup menu pas kamu butuh.
main.js
document.addEventListener("DOMContentLoaded", function () {
new Swiper(".swiper", {
slidesPerView: "auto",
spaceBetween: 40,
grabCursor: true,
centeredSlides: false,
});
});
bayangin kamu lagi nyusun slide foto atau konten keren yang bisa digeser-geser di halaman web, nah kode ini tuh yang jadi “otak” di balik layar itu! Jadi pas halaman udah siap (DOMContentLoaded), kamu langsung bikin instance baru dari Swiper, library JavaScript yang super powerfull buat bikin slider yang gampang dikendalikan. Dengan konfigurasi kayak slidesPerView: "auto", setiap slide bakal otomatis sesuaikan lebarnya, jadi gak kaku! Terus jarak antar slide diatur 40 piksel (spaceBetween: 40) biar slide-slide itu gak numpuk, ada ruang napas yang enak buat mata.
Selain itu, ada fitur grabCursor: true yang bikin kursor kamu berubah jadi tangan siap “nangkep” slide, jadi interaksinya berasa lebih natural dan seru. Terus, centeredSlides: false bikin slide mulai dari kiri, bukan di tengah, jadi tampilannya kayak barisan slide biasa yang bisa kamu geser dengan gampang. Intinya, kode ini bikin slider kamu jadi responsif, interaktif, dan stylish cuma dengan beberapa baris aja. Simpel, tapi powerful.
tab.js
document.addEventListener("DOMContentLoaded", () => {
const tabContents = [
{
chefName: "Phoenix Satcheup",
category: "Pizza",
location: "Jakarta, Indonesia",
experience: "12 Years",
restaurant: "Pearl Dolphin",
restaurantImage: "./assets/images/thumbnails/resto-4.png",
chefImage: "./assets/images/thumbnails/chef-1.png",
},
{
chefName: "Chamber Botfrag",
category: "Vegan",
location: "Bandung, Indonesia",
experience: "8 Years",
restaurant: "Green Garden",
restaurantImage: "./assets/images/thumbnails/resto-3.png",
chefImage: "./assets/images/thumbnails/chef-2.webp",
},
{
chefName: "Asep Vandal",
category: "Roast Chicken",
location: "Sunda, Indonesia",
experience: "10 Years",
restaurant: "Sundanese Delight",
restaurantImage: "./assets/images/thumbnails/resto-2.png",
chefImage: "./assets/images/thumbnails/chef-3.webp",
},
{
chefName: "I Made Invoker",
category: "Beef Steak",
location: "Bali, Indonesia",
experience: "15 Years",
restaurant: "Bali Bistro",
restaurantImage: "./assets/images/thumbnails/resto-1.png",
chefImage: "./assets/images/thumbnails/chef-4.webp",
},
];
const tabs = document.querySelectorAll(".tab-item");
function updateTabContent(index) {
const selectedContent = tabContents[index];
const chefImageElement = document.querySelector(".tab-content img");
if (chefImageElement) chefImageElement.src = selectedContent.chefImage;
const chefNameElement = document.querySelector(".tab-content h2");
if (chefNameElement) chefNameElement.textContent = selectedContent.chefName;
const experienceElement = document.querySelector(".experience-years");
if (experienceElement)
experienceElement.textContent = selectedContent.experience;
const restaurantNameElement = document.querySelector(".resto-name");
if (restaurantNameElement)
restaurantNameElement.textContent = selectedContent.restaurant;
const restaurantImageElement = document.querySelector(
".tab-content .h-[132px] img"
);
if (restaurantImageElement)
restaurantImageElement.src = selectedContent.restaurantImage;
}
function setActiveTab(index) {
tabs.forEach((tab) => {
tab.classList.remove("bg-white");
const profileDetailsLink = tab.querySelector("a");
if (profileDetailsLink) {
profileDetailsLink.classList.remove("opacity-100");
profileDetailsLink.classList.add("opacity-0");
}
const locationIcon = tab.querySelector(".location-icon");
if (locationIcon) {
locationIcon.classList.remove("bg-muted");
locationIcon.classList.add("bg-foreground");
}
});
const activeTab = tabs[index];
activeTab.classList.add("bg-white");
const profileDetailsLink = activeTab.querySelector("a");
if (profileDetailsLink) {
profileDetailsLink.classList.remove("opacity-0");
profileDetailsLink.classList.add("opacity-100");
}
const locationIcon = activeTab.querySelector(".location-icon");
if (locationIcon) {
locationIcon.classList.remove("bg-foreground");
locationIcon.classList.add("bg-muted");
}
}
tabs.forEach((tab, index) => {
tab.addEventListener("click", () => {
setActiveTab(index);
updateTabContent(index);
});
});
setActiveTab(0);
updateTabContent(0);
});
Bayangin kamu lagi lihat halaman profil chef yang keren-keren, terus kamu mau lihat detail tiap chef dengan klik tab-tab yang ada. Nah, di sini ada array tabContents yang berisi data lengkap tiap chef, mulai dari nama, kategori makanan, pengalaman kerja, sampai foto chef dan restorannya. Jadi, tiap kali kamu klik salah satu tab, fungsi updateTabContent langsung jalan untuk ngubah isi halaman sesuai data chef yang kamu pilih ganti gambar, nama, pengalaman, dan info resto tanpa reload halaman. Praktis banget, kayak kamu scroll Instagram tapi kontennya berubah cepat dan mulus.
Terus, supaya kamu gak bingung tab mana yang aktif, ada fungsi setActiveTab yang nge-handle styling tab yang lagi kamu pilih. Jadi tab yang aktif bakal punya background putih, link profilnya muncul dengan opacity penuh, dan ikon lokasi juga berubah warna supaya kamu gampang lihat mana yang sedang dipilih. Semua ini diatur dengan nambahin dan ngurangin kelas CSS secara dinamis pakai JavaScript, jadi tampilannya selalu rapi dan keren sesuai interaksi kamu.
Gak cuma itu, setiap tab punya event listener yang siap nangkep klik kamu dan langsung nge-trigger dua fungsi tadi update konten dan set styling aktif. Jadi, kode ini kerja sama kayak DJ yang nyalain playlist sesuai request kamu, bikin pengalaman browsing info chef jadi asik, interaktif, dan smooth banget tanpa harus ribet reload halaman. Pokoknya, kamu tinggal klik, langsung dapet info yang kamu mau dengan tampilan yang kece.
input.css
@import url("<https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap>");
@import "tailwindcss";
:root {
--background: #fafafa;
--foreground: #232631;
--primary: #fdc886;
--secondary: #5a4fcf;
--muted: #656565;
--star: #ffb800;
--placeholder: #858585;
}
@theme inline {
--font-poppins: "Poppins", sans-serif;
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-primary: var(--primary);
--color-secondary: var(--secondary);
--color-muted: var(--muted);
--color-star: var(--star);
--color-placeholder: var(--placeholder);
--drop-shadow-custom: 8px 8px 25px rgba(102, 102, 102, 0.04);
--drop-shadow-custom2: -8px 8px 25px rgba(102, 102, 102, 0.04);
--shadow-primary: 0 4px 10px 0 rgba(253, 200, 134, 0.8);
--shadow-secondary: 0 4px 10px 0 rgba(90, 79, 207, 0.1);
}
@layer base {
body {
@apply bg-background text-foreground font-poppins;
}
}
Bayangin kamu lagi nyiapin wardrobe keren buat website kamu. Di sini, kamu lagi impor font Poppins dari Google Fonts, jadi tipografi di halaman bakal tampil stylish dan modern banget kayak kamu lagi pilih outfit kece dari brand terkenal supaya tampil maksimal. Trus kamu juga impor Tailwind CSS, yang kayak toolkit super lengkap buat styling cepat dan rapi tanpa harus pusing bikin CSS dari nol.
Nah, di bagian :root, kamu bikin semacam ‘warna-warna andalan’ yang nanti bisa dipakai berulang-ulang di seluruh website. Jadi, misalnya kamu mau pakai warna utama buat tombol atau background, tinggal panggil --primary aja. Ini kayak kamu punya palette warna khusus yang selalu kamu pakai biar desainnya konsisten dan gak bikin mata lelah. Ada juga warna khusus buat placeholder, shadow keren, dan warna-warna muted yang bikin tampilan makin dinamis dan enak dilihat.
Terus, di bagian @theme inline kamu bikin varian variabel CSS yang nyambung ke warna dan font tadi, plus beberapa efek shadow custom yang bikin elemen di halaman kayak “ngambang” dengan efek cahaya lembut. Nah, terakhir, di @layer base kamu pakai directive @apply dari Tailwind untuk langsung set style dasar body: background, warna teks, dan font default dari Poppins itu. Jadi, intinya kamu udah bikin fondasi styling yang solid dan mudah dikembangkan tanpa ribet, biar website kamu tampil clean, konsisten, dan super profesional.
.gitignore
node_modules
Gitignore dengan isi node_modules itu ibarat kamu punya lemari yang super gede penuh barang, tapi kamu gak mau semua barang itu ikut kamu bawa ke rumah teman saat nongkrong. Jadi, file node_modules itu tempatnya semua paket dan dependensi yang kamu download dari npm, ukurannya bisa super jumbo dan isinya bisa direbuild kapan aja dari package.json. Dengan nge-ignore folder ini di .gitignore, kamu ngasih tahu Git buat gak ikut nyimpen folder node_modules ke repository, supaya repo kamu tetap ringan, gak penuh sampah, dan proses push-pull jadi lebih cepat. Jadi intinya, folder node_modules itu gampang dibuat ulang, gak perlu dibawa-bawa ke remote git.
package.json
{
"name": "resto",
"version": "1.0.0",
"description": "",
"license": "ISC",
"author": "",
"type": "commonjs",
"main": "/src/index.html",
"scripts": {
"dev": "npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css --watch"
},
"dependencies": {
"@tailwindcss/cli": "^4.1.3",
"tailwindcss": "^4.1.3"
}
}
jadi ini adalah isi file package.json yang jadi otak dari proyek Node.js atau frontend kamu, khususnya yang pakai Tailwind CSS. Di sini, ada beberapa info penting seperti name proyek kamu (dalam hal ini "resto"), versi, dan lisensi. Nah, bagian scripts itu keren banget karena kamu bisa bikin perintah singkat buat jalanin hal-hal yang sering kamu lakukan. Misalnya, script dev ini bakal ngejalanin Tailwind CSS CLI secara otomatis, nge-compile file CSS input (input.css) ke output (output.css), dan yang paling asik, dia terus “watch” alias mantau perubahan di file input, jadi tiap kamu simpan perubahan, Tailwind langsung update CSS-nya tanpa kamu harus ngapa-ngapain lagi.
Terus di bagian dependencies, itu tempat kamu nyimpen paket-paket yang dipakai proyek kamu, dalam hal ini ada @tailwindcss/cli dan tailwindcss versi 4.1.3. Jadi, setiap kali kamu atau temen kamu clone project ini, tinggal ketik npm install atau yarn buat otomatis download semua paket ini sesuai versi yang tertulis, biar semua lingkungan kerja sama dan gak ada yang versi beda-beda. Singkatnya, package.json ini semacam peta dan remote control buat ngatur seluruh dependency dan perintah penting dalam proyek kamu.
vercel.json
{
"builds": [
{
"src": "src/**/*",
"use": "@vercel/static"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/src/$1"
}
]
}
Ini konfigurasi buat Vercel yang ngatur gimana cara nge-deploy project kamu: bagian builds bilang kalau semua file di folder src bakal diproses sebagai konten statis pakai builder @vercel/static, jadi Vercel tahu harus ngirim file-file itu apa adanya ke server. Terus di bagian routes, setiap request URL yang masuk bakal diarahkan ke file yang sesuai di folder src, jadi misalnya kamu buka /about, dia bakal nyari file src/about buat ditampilin, intinya ini bikin routing simple dan bikin file di src bisa langsung diakses kayak di root website kamu.
Cara Mengedit
Buat ngedit sesuatu itu gampang banget, misalnya kamu pengen ubah teks “Why Should Choose Us?” di kodenya. Caranya simpel, kamu tinggal pencet Ctrl + F di VSCode, terus ketik keyword atau kata kunci yang mau kamu cari, misal “Why Should Choose Us?”. Nah, otomatis VSCode bakal langsung bawa kamu ke bagian kodenya yang isinya teks itu. Tinggal kamu ganti deh teksnya sesuai yang kamu mau, terus simpan. Setelah itu, coba reload atau refresh halaman di browser, dan kamu bakal lihat perubahan yang kamu buat langsung muncul tanpa ribet. Contohnya kayak gini:
Resto - Video Tutorial How to Edit
Beragam Template HTML + Tailwind CSS ( FREE )🙌
Shaynakit - HTML Template
Nah, yang terakhir nih, kalau kamu pengen langsung dapetin template yang udah jadi lengkap sama HTML dan Tailwind CSS-nya, tinggal dipakai aja tanpa harus ribet ngoding dari nol, kamu bisa mampir ke situs Shaynakit. Di sana banyak banget pilihan template gratis yang keren-keren, tapi juga ada yang versi premium kalau kamu pengen yang lebih eksklusif. Template-nya juga lengkap banget, mulai dari desain buat mobile sampai desktop, jadi cocok buat apapun kebutuhan proyek kamu.
Pokoknya tinggal daftar atau registrasi, terus pilih deh template mana yang kamu suka, download, dan langsung pakai di proyek kamu. Ini cara yang asik banget buat ngehemat waktu dan tetep dapet hasil desain yang kece tanpa harus pusing mikirin styling dari awal. Jadi, jangan ragu buat eksplor dan manfaatin sumber daya keren ini buat bikin proyek kamu makin mantap.
Penutup
Sebagai penutup, kamu sekarang sudah punya sumber kode HTML dan Tailwind CSS lengkap dengan contoh dan penjelasannya supaya gak bingung. Kalau kamu butuh template kece lainnya, tinggal cek aja situs Shaynakit yang penuh dengan desain dan kode siap pakai. Jadi, semangat terus belajar dan eksplorasi supaya kamu bisa bikin proyek web yang keren banget.