Study Cate Getaway
Pada materi ini, kita akan melakukan studi kasus secara menyeluruh untuk membangun halaman landing page menggunakan HTML dan CSS. Tutorial ini dirancang khusus untuk memperkuat pemahaman kamu terkait tata letak (layouting), penempatan elemen (positioning), dan penulisan kode yang terstruktur.
Tahap 1: Struktur Proyek dan Aset
Dalam pengembangan web, kerapian struktur folder sangat penting. Struktur yang berantakan akan menyulitkan kamu saat proyek berskala besar. Kita akan menerapkan pola Separation of Concerns (SoC), yaitu prinsip memisahkan file berdasarkan tanggung jawab dan fungsinya masing-masing.
Langkah 1: Menyiapkan Direktori Utama
Buat folder baru bernama Study-case-getaway. Di dalam folder ini, buat file index.html yang akan menjadi fondasi dari seluruh tampilan web kamu.
Langkah 2: Mengatur Folder CSS Modular
Alih-alih menyatukan semua kode CSS dalam satu file besar, kita akan membaginya secara spesifik. Buat folder assets/css/ dan di dalamnya buat dua file:
font-style.cssstyle.css
Mengapa dipisahkan?
Kita memisahkan font-style.css khusus untuk definisi tipografi (jenis dan ukuran huruf), sedangkan style.css difokuskan murni untuk tata letak dan warna. Pemisahan ini memastikan kamu bisa mengganti atau memperbarui font sistem tanpa risiko merusak tata letak grid atau flexbox halaman.
Langkah 3: Optimasi Media Public
Simpan aset gambar di dalam folder public/images/. Untuk efisiensi beban loading, kita menggunakan format .avif yang memiliki rasio kompresi lebih baik dibandingkan JPEG/PNG.
background.avifdummy-avatar.jpg
Visualisasi Struktur Folder Akhir
Pastikan hierarki direktori kamu terlihat persis seperti ini:
Tahap 2: Membangun Struktur HTML (index.html)
Pada tahap ini, kita akan menyusun elemen-elemen kerangka menggunakan HTML. Mari kita pecah dan Penjelasan Koding index.html ke dalam beberapa blok agar mudah dipahami.
Blok 1: Konfigurasi Head & Metadata
Mengapa kita membutuhkan blok ini?
Bagian <head> mengontrol instruksi teknis untuk browser, mengatur penyesuaian layar (responsiveness), dan memuat sumber daya eksternal (font dan CSS) sebelum halaman dirender.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Playball&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="assets/css/font-style.css" />
<link rel="stylesheet" href="assets/css/style.css" />
</head>
<body>
</body>
</html>Penjelasan Koding:
meta charset="UTF-8": Standar pengkodean karakter agar browser dapat membaca berbagai simbol dan huruf spesifik.meta name="viewport": Properti ini memaksa lebar website mengikuti lebar perangkat fisik (misalnya layar smartphone), sangat penting untuk Responsive Web Design.link rel="preconnect": Memberi tahu browser untuk membangun koneksi awal ke server Google Fonts. Proses resolusi DNS dilakukan lebih awal sehingga font diunduh lebih cepat.link rel="stylesheet": Memuat CSS yang kita buat di tahap 1. Pastikanfont-style.cssdimuat sebelumstyle.css.
Menggunakan Google Fonts
Jika kamu ingin mencari font sendiri, kunjungi fonts.google.com. Pilih font yang kamu inginkan (misal: Roboto), klik Get font, lalu Get embed code. Salin blok tag <link> yang diberikan dan tempelkan ke dalam bagian <head> kamu menggantikan kode font pada baris ke-9 di atas.
Blok 2: Navigasi (Header Menu)
Mengapa kita membutuhkan blok ini?
Kita menggunakan tag semantik seperti <header> dan <nav> untuk memudahkan mesin pencari (SEO) dan screen reader memahami bagian mana yang berisi menu navigasi utama.
<header>
<div class="navigation">
<div class="logo">
<div class="roboto-semibold">PW 1</div>
<span class="playball-regular">Studi Kasus</span>
</div>
<nav class="navigation-bar">
<ul class="nav-list">
<li class="nav-link active">Home</li>
<li class="nav-link">Shop</li>
<li class="nav-link">Collection</li>
<li class="nav-link">About</li>
<li class="nav-link">Blog</li>
<li class="nav-link">Contact</li>
</ul>
</nav>
<div>
<button class="btn">Contact Us</button>
</div>
</div>
</header>Penjelasan Koding:
<nav class="navigation-bar">: Tag pembungkus khusus untuk tautan navigasi web.class="nav-link active": Class tambahanactivedigunakan untuk memberikan penanda visual di CSS nantinya bahwa pengguna sedang berada di halaman "Home".
Blok 3: Area Headline (Hero Section)
Mengapa kita membutuhkan blok ini?
Ini adalah elemen visual pertama yang dilihat pengguna. Kita menggunakan <h1> tunggal agar hierarki SEO tetap terjaga.
<div class="headline">
<h1>Find Your Perfect Getaway, <span class="playball-regular">Instantly</span></h1>
<p>
Explore stylish short-term rentals in the world's best destinations whether you crave a
city loft or a beachside escape.
</p>
<button class="btn btn-primary">Booking Now</button>
</div>Penjelasan Koding:
<h1>: Judul level utama. Batasi penggunaan tag<h1>hanya satu kali dalam satu halaman.<span>: Tag inline serbaguna. Di sini digunakan untuk menyisipkan font bergaya Playball secara spesifik hanya pada kata "Instantly" tanpa memutus struktur block teks.
Blok 4: Elemen Mengambang (Social Proof & Info)
Mengapa kita membutuhkan blok ini? Bagian ini bertujuan untuk menaruh elemen statistik dan avatar review yang nantinya akan kita posisikan secara melayang di pojok kiri dan kanan bawah menggunakan CSS Absolute Positioning.
<div class="happy-user">
<div class="list-avatar">
<div class="avatar"><img src="public/images/dummy-avatar.jpg" alt="avatar user 1" /></div>
<div class="avatar"><img src="public/images/dummy-avatar.jpg" alt="avatar user 2" /></div>
<div class="avatar"><img src="public/images/dummy-avatar.jpg" alt="avatar user 3" /></div>
</div>
<span> 100K Review With 4.9 Rating </span>
</div>
<div class="info">
<div>
<div>80+</div>
<div>Countries</div>
</div>
<div>
<div>150+</div>
<div>Trips Planned</div>
</div>
<div>
<div>100K+</div>
<div>Happy Travelers</div>
</div>
<div>
<div>4.9</div>
<div>Rating</div>
</div>
</div>
</header>Penjelasan Koding:
.list-avatar: Mengelompokkan gambar profil pengguna (social proof)..info: Menggunakan beberapa elemen<div>bersarang (nested divs). Di CSS, kita akan merubah tumpukan elemen ini menjadi sejajar menggunakan Flexbox.
Tahap 3: Implementasi CSS Tipografi (font-style.css)
Buka file assets/css/font-style.css. Kita akan mendefinisikan class tipografi yang dapat digunakan ulang.
/* 1. Gaya Huruf Roboto Regular */
.roboto-regular {
font-family: "Roboto", sans-serif;
font-weight: 400;
}
/* 2. Gaya Huruf Roboto Bold */
.roboto-bold {
font-family: "Roboto", sans-serif;
font-weight: 700;
}
/* 3. Gaya Huruf Playball (Dekoratif) */
.playball-regular {
font-family: "Playball", cursive;
font-weight: 400;
}Penjelasan Koding:
.(Titik): Karakter ini menandakan bahwa kita sedang membuat aturan untuk sebuah Class.font-family: Mendeklarasikan font utama ("Roboto"). Teks di sebelahnya (sans-serifataucursive) adalah fallback font. Jika font Google gagal dimuat akibat kendala jaringan, browser otomatis menggantinya dengan font generik sistem terdekat.font-weight: Mengontrol ketebalan teks (400 = Regular/Normal, 700 = Bold/Tebal).
Tahap 4: Styling Tata Letak Lengkap (style.css)
Sekarang, mari kita ubah struktur kerangka HTML di atas menjadi antarmuka visual yang modern. Buka file assets/css/style.css. Kita membagi kodenya ke dalam 6 blok fungsional.
Blok 1: Global Reset & Base Variables
Mengapa? Setiap browser (Chrome, Firefox, Safari) memiliki gaya default (margin & padding bawaan) yang berbeda. Teknik CSS Reset memastikan tampilan web kamu konsisten di semua browser.
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: "Roboto", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
}Penjelasan Koding:
*(Asterisk): Menargetkan semua elemen HTML.margin: 0; padding: 0;: Menghapus ruang kosong eksternal dan internal bawaan browser.box-sizing: border-box;: Memastikan penambahanpaddingatau garis tepi (border) tidak memperlebar ukuran dimensi asli elemen yang sudah ditentukan.
Blok 2: Konfigurasi Header Latar Belakang
Mengapa? Kita akan membungkus seluruh konten menggunakan gambar background dan menambahkan efek gradasi gelap (overlay) agar teks berwarna putih di atasnya tetap terbaca jelas.
header {
background-image:
linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.9)),
url("../../public/images/background.avif");
min-height: 100vh;
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
position: relative;
}Penjelasan Koding:
linear-gradient(...): Memberikan gradasi transparan dari atas menuju warna hitam pekat (rgba(0, 0, 0, 0.9)) di bagian paling bawah layar.min-height: 100vh;: Menginstruksikan tinggi elemen menempati 100% dari Viewport Height (ketinggian layar pengguna).background-size: cover;: Memaksa gambar direnggangkan menjaga rasio aslinya agar menutupi seluruh wadah tanpa celah putih.position: relative;: Mendeklarasikan referensi batas bagi elemen anak di dalamnya yang akan diatur menggunakan absolute positioning (Blok 6).
Blok 3: Area Navigasi & Identitas (Flexbox)
Mengapa? Kita menggunakan modul tata letak Flexbox (Flexible Box) untuk menyejajarkan Logo, Menu, dan Tombol secara horizontal tanpa memerlukan penghitungan piksel yang rumit.
header > .navigation {
display: flex;
justify-items: center;
justify-content: space-between;
padding: 2rem;
align-items: center;
}
.logo {
font-size: 1.5rem;
text-align: center;
line-height: 20px;
}
.logo > span {
font-style: italic;
}
.btn {
padding: 0px 20px;
min-height: 40px;
border-radius: 20px;
font-weight: bold;
border: none;
}
.btn-primary {
background-color: white;
color: black;
}Penjelasan Koding:
display: flex;: Mengubah elemen.navigationmenjadi wadah Flexbox.justify-content: space-between;: Mendorong secara otomatis elemen pertama (Logo) rata kiri, elemen di tengah (Menu) ke tengah ruang, dan elemen terakhir (Tombol) rata kanan.
Blok 4: Bar Menu dan Interaksi (Hover/Active)
Mengapa? Bagian ini mengatur pembungkus menu berwujud kapsul, dan menambahkan animasi transisi saat kursor tetikus (mouse) diarahkan ke link.
.navigation-bar {
background-color: #000000;
padding: 10px;
border-radius: 50px;
display: inline-flex;
justify-content: center;
align-items: center;
}
.nav-list {
display: flex;
list-style: none;
gap: 12px;
margin: 0;
padding: 0;
align-items: center;
}
.nav-link {
color: #9ca3af;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
font-size: 15px;
font-weight: 500;
padding: 10px 22px;
cursor: pointer;
border-radius: 40px;
transition: all 0.2s ease-in-out;
}
.nav-link:hover:not(.active) {
color: #ffffff;
background-color: rgba(255, 255, 255, 0.15);
}
.nav-link.active {
background-color: #ffffff;
color: #000000;
font-weight: 600;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}Penjelasan Koding:
border-radius: 50px;: Menciptakan efek ujung melengkung ekstrem seperti kapsul obat.gap: 12px;: Memberikan ruang spasi konsisten sebesar 12px di antara setiap list menu<nav-link>.transition: all 0.2s ease-in-out;: Memastikan perubahan warna saat kursor menunjuk (hover) terjadi secara halus (berdurasi 0.2 detik).:hover:not(.active): Sebuah pseudo-class kompleks. Terapkan gaya warna putih jika pengguna melakukan hover, asalkan class-nya BUKAN sedang memiliki class.active.
Blok 5: Penempatan Teks Konten Utama (Headline)
Mengapa? Teks konten utama harus dipusatkan persis di tengah layar untuk memusatkan fokus visual pembaca.
.headline {
margin: auto;
text-align: center;
max-width: 50vw;
display: flex;
justify-content: center;
align-items: center;
min-height: calc(100vh - 124px);
flex-direction: column;
gap: 1rem;
color: white;
}
.headline > h1 {
font-size: 5rem;
}
.headline > p {
font-size: 1.2rem;
}Penjelasan Koding:
flex-direction: column;: Mengatur elemen (Judul H1, Deskripsi P, Tombol) ditumpuk dari atas ke bawah (vertikal), karena default flexbox adalah horizontal.min-height: calc(100vh - 124px);: Properti matematis. Kita mengambil tinggi 100% layar, lalu dikurangi 124px (perkiraan ruang yang dikonsumsi oleh bar navigasi atas) sehingga teks headline tepat di poros tengah.
Blok 6: Pengaturan Posisi Mengambang (Review & Info)
Mengapa? Elemen statistik pengunjung ingin kita letakkan secara tetap di sudut ujung kiri bawah dan kanan bawah tanpa mempedulikan posisi teks di sekitarnya. Ini dapat dicapai melalui penempatan secara Absolute.
.happy-user {
position: absolute;
bottom: 1.5rem;
left: 1.5rem;
display: flex;
align-items: center;
gap: 25px;
color: white;
}
.happy-user > span {
font-style: italic;
}
.list-avatar {
display: flex;
}
.avatar {
margin-right: -20px;
}
.avatar > img {
width: 42px;
height: 42px;
border-radius: 100%;
border: 2px solid orange;
}
.avatar:first-child { z-index: 1; }
.avatar:nth-child(2) { z-index: 2; }
.avatar:last-child { z-index: 3; }
.info {
position: absolute;
bottom: 1.5rem;
right: 1.5rem;
display: flex;
align-items: center;
gap: 25px;
color: white;
}
.info > div > div:first-child {
text-align: center;
font-weight: bold;
font-size: 32px;
}
.info > div > div:nth-child(2) {
font-style: italic;
}Penjelasan Koding:
position: absolute;: Melepaskan elemen dari struktur normal dan memindahkannya menempel ke koordinat tertentu.bottom: 1.5rem; left: 1.5rem;: Menempel pada garis jarak dasar (bawah) dan garis tepi (kiri) sejauh 1.5 rem (sekitar 24px) dari batas wadah induknya (<header>yang berstatus relative).margin-right: -20px;: Penambahan nilai minus memaksa setiap gambar avatar untuk saling menimpa satu sama lain (overlapping).z-index: 1, 2, 3;: Menentukan prioritas tumpukan kedalaman layar (stacking context). Semakin tinggi angka z-index, elemen akan ditampilkan di atas tumpukan lainnya.
Hasil
Koding keseluruhan
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Playball&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="assets/css/font-style.css" />
<link rel="stylesheet" href="assets/css/style.css" />
</head>
<body>
<header>
<div class="navigation">
<div class="logo">
<div class="roboto-semibold">PW 1</div>
<span class="playball-regular">Studi Kasus</span>
</div>
<nav class="navigation-bar">
<ul class="nav-list">
<li class="nav-link active">Home</li>
<li class="nav-link">Shop</li>
<li class="nav-link">Collection</li>
<li class="nav-link">About</li>
<li class="nav-link">Blog</li>
<li class="nav-link">Contact</li>
</ul>
</nav>
<div>
<button class="btn">Contact Us</button>
</div>
</div>
<div class="headline">
<h1>Find Your Perfect Getaway, <span class="playball-regular">Instantly</span></h1>
<p>
Explore stylish short-term rentals in the world's best destinations whether you crave a
city loft or a beachside escape.
</p>
<button class="btn btn-primary">Booking Now</button>
</div>
<div class="happy-user">
<div class="list-avatar">
<div class="avatar">
<img src="public/images/dummy-avatar.jpg" alt="avatar user 1"/>
</div>
<div class="avatar">
<img src="public/images/dummy-avatar.jpg" alt="avatar user 2"/>
</div>
<div class="avatar">
<img src="public/images/dummy-avatar.jpg" alt="avatar user 3"/>
</div>
</div>
<span> 100K Review With 4.9 Rating </span>
</div>
<div class="info">
<div>
<div>80+</div>
<div>Countries</div>
</div>
<div>
<div>150+</div>
<div>Trips Planned</div>
</div>
<div>
<div>100K+</div>
<div>Happy Travelers</div>
</div>
<div>
<div>4.9</div>
<div>Rating</div>
</div>
</div>
</header>
</body>
</html>.roboto-regular {
font-family: "Roboto", sans-serif;
font-weight: 400;
}
.roboto-bold {
font-family: "Roboto", sans-serif;
font-weight: 700;
}
.playball-regular {
font-family: "Playball", cursive;
font-weight: 400;
} * {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: "Roboto", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
}
header {
background-image:
linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.9)),
url("../../public/images/background.avif");
min-height: 100vh;
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
position: relative;
}
header > .navigation {
display: flex;
justify-items: center;
justify-content: space-between;
padding: 2rem;
align-items: center;
}
.logo {
font-size: 1.5rem;
text-align: center;
line-height: 20px;
}
.logo > span {
font-style: italic;
}
.btn {
padding: 0px 20px 0px 20px;
min-height: 40px;
border-radius: 20px;
font-weight: bold;
border: none;
}
.btn-primary {
background-color: white;
color: black;
}
.navigation-bar {
background-color: #000000;
padding: 10px;
border-radius: 50px;
display: inline-flex;
justify-content: center;
align-items: center;
}
.nav-list {
display: flex;
list-style: none;
gap: 12px;
margin: 0;
padding: 0;
align-items: center;
}
.nav-link {
color: #9ca3af;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
font-size: 15px;
font-weight: 500;
padding: 10px 22px;
cursor: pointer;
border-radius: 40px;
transition: all 0.2s ease-in-out;
}
.nav-link:hover:not(.active) {
color: #ffffff;
background-color: rgba(255, 255, 255, 0.15);
}
.nav-link.active {
background-color: #ffffff;
color: #000000;
font-weight: 600;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.headline {
margin: auto;
text-align: center;
max-width: 50vw;
display: flex;
justify-content: center;
align-items: center;
min-height: calc(100vh - 124px);
flex-direction: column;
gap: 1rem;
color: white;
}
.headline > h1 {
font-size: 5rem;
}
.headline > p {
font-size: 1.2rem;
}
.happy-user {
position: absolute;
bottom: 1.5rem;
left: 1.5rem;
display: flex;
align-items: center;
gap: 25px;
color: white;
}
.happy-user > span {
font-style: italic;
}
.list-avatar {
display: flex;
}
.avatar {
margin-right: -20px;
}
.avatar > img {
width: 42px;
height: 42px;
border-radius: 100%;
border: 2px solid orange;
}
.avatar:first-child {
z-index: 1;
}
.avatar:nth-child(2) {
z-index: 2;
}
.avatar:last-child {
z-index: 3;
}
.info {
position: absolute;
bottom: 1.5rem;
right: 1.5rem;
display: flex;
align-items: center;
gap: 25px;
color: white;
}
.info > div > div:first-child {
text-align: center;
font-weight: bold;
font-size: 32px;
}
.info > div > div:nth-child(2) {
font-style: italic;
}