Study Cate Getaway

Study case ini mencangkup pemahaman secara penuh penggunaan HTML dan CSS.
Author : Celvine
Last Update : 21 March 2026

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:

  1. font-style.css
  2. style.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.

  1. background.avif
  2. dummy-avatar.jpg

Visualisasi Struktur Folder Akhir

Pastikan hierarki direktori kamu terlihat persis seperti ini:

index.html
font-style.css
style.css
background.avif
dummy-avatar.jpg

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.

index.html (Bagian Head)
<!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. Pastikan font-style.css dimuat sebelum style.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.

index.html (Bagian Body - Navigasi)
<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 tambahan active digunakan 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.

index.html (Bagian Body - Headline)
<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.

index.html (Bagian Body - Info Panel)
<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.

font-style.css
/* 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-serif atau cursive) 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.

style.css (Blok 1)
* {
  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 penambahan padding atau 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.

style.css (Blok 2)
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.

style.css (Blok 3)
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 .navigation menjadi 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.

style.css (Blok 4)
.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.

style.css (Blok 5)
.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.

style.css (Blok 6)
.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

demo

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;
  }

On this page