Memahami CSS Position Absolute & Relative lewat Kasus Kartu Belanja

Bagi pemula yang baru belajar CSS, memahami Flexbox mungkin terasa cukup mudah karena sifatnya yang menyusun elemen seperti antrean baris atau kolom. Namun, tantangan baru muncul ketika kita ingin membuat satu elemen khusus melayang di atas elemen lain—misalnya label diskon atau ikon wishlist di pojok kartu produk.

Di sinilah konsep CSS Position: Relative dan Absolute bekerja. Jika Anda masih sering bingung bagaimana kedua properti ini saling bekerja sama, mari kita bedah secara mendalam lewat praktik langkah demi langkah!

ISI_KATA_KUNCI_GAMBAR_DI_SINI

Gambar 1: Memahami CSS Position Absolute dan Position Relative CSS

Konsep Dasar: Apa Bedanya?

Sebelum masuk ke kode, mari kita samakan persepsi lewat analogi sederhana:

  • Aliran Normal (Normal Flow): Tanpa properti position, semua elemen HTML adalah kotak padat yang saling mengantre dari atas ke bawah. Mereka saling mendorong dan tidak bisa bertumpukan.
  • position: absolute (Elemen Anak): Mengubah elemen menjadi seperti "hantu". Elemen ini diangkat ke lapisan atas (3D), kehilangan ruang fisiknya di aliran normal, dan bisa melayang bebas tanpa menggeser elemen lain. Sifat kotaknya juga mengecil pas seukuran teksnya (shrink-to-fit).
  • position: relative (Elemen Induk/Pagar Pembatas): Berfungsi sebagai jangkar atau tolok urut koordinat. Jika tidak ada induk yang dipasangi relative, elemen absolute akan melayang bebas hingga ke pojok layar browser (monitor).
Hukum Emas CSS Position:
Jika ingin anak melayang bebas di dalam kotak induknya, maka Induk wajib relative dan Anak wajib absolute.

Praktik Langkah demi Langkah (Step-by-Step)

Mari kita buat sebuah kartu belanja dari nol. Buat sebuah file HTML baru di komputer Anda, lalu ikuti evolusi kodenya per tahap agar Anda bisa melihat perubahannya secara kasat mata.

Langkah 1: Menyiapkan Kerangka HTML & Batasan Awal

Ketik kode dasar berikut. Di sini kita membuat sebuah kartu (.card), label diskon (.badge), gambar produk, serta area teks (.card-body).

<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8">
  <title>Belajar CSS Position</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #f5f5f5; }

    /* Kotak Induk Utama */
    .card {
      width: 250px;
      border: 1px solid #333;
      background-color: white;
    }
    .card img {
      width: 100%;
      display: block;
    }
  </style>
</head>
<body>
  <div class="card">
    <div class="badge">Diskon 30%</div>
    <img src="https://unsplash.com" alt="Sepatu Keren">
    <div class="card-body">
      <h3>Sepatu Sport Alfe</h3>
      <p>Rp 350.000</p>
      <button class="btn-beli">Beli Sekarang</button>
    </div>
  </div>
</body>
</html>

Kondisi Visual Saat Ini: Label "Diskon 30%" berdiri kaku sebagai baris sendiri di paling atas. Gambar sepatu terdorong ke bawah karena semua elemen masih mematuhi hukum antrean fisik normal.

Langkah 2: Merapikan Konten Bawah dengan Flexbox

Mari kita atur area teks menggunakan Flexbox agar tersusun vertikal dengan jarak yang rapi. Tambahkan CSS ini di dalam tag <style>:

.card-body {
  display: flex;
  flex-direction: column; /* Menyusun dari atas ke bawah */
  gap: 15px;              /* Memberi jarak otomatis antar teks/tombol */
  padding: 20px;
}
.btn-beli {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 10px;
  border-radius: 5px;
  cursor: pointer;
}

Kondisi Visual Saat Ini: Bagian bawah kartu sudah rapi berkat Flexbox. Namun, masalah label diskon yang kaku di atas gambar masih belum terselesaikan.

Langkah 3: Mengangkat Badge Menjadi Melayang (absolute)

Sekarang kita gunakan properti absolute pada elemen anak agar dia keluar dari antrean normal dan melayang. Tambahkan kode ini:

.badge {
  position: absolute;
  top: 10px;
  left: 10px;
  background-color: red;
  color: white;
  padding: 8px 12px;
  font-weight: bold;
  font-size: 12px;
}

⚠️ MASALAH YANG MUNCUL: Badge diskon memang berhasil melayang dan ukurannya mengecil pas seukuran teksnya (shrink-to-fit). TETAPI, posisinya malah melompat ke pojok kiri atas layar monitor browser Anda! Gambar sepatu otomatis naik karena ruang fisik badge sebelumnya dianggap hilang.

Mengapa ini terjadi? Karena elemen anak (.badge) tidak menemukan elemen induk yang memiliki status relative, sehingga koordinat dihitung dari ujung layar browser paling luar.

Langkah 4: Mengunci Koordinat ke Kotak Induk (relative)

Untuk mengurung pergerakan badge agar hanya melayang di dalam kartu produk, kita harus memberikan status relative pada elemen induknya, yaitu .card.

Cari selector .card Anda, lalu tambahkan baris position: relative di dalamnya:

.card {
  width: 250px;
  border: 1px solid #333;
  background-color: white;
  border-radius: 8px;
  
  /* KUNCI UTAMA POSITION */
  position: relative; 
}

Kondisi Visual Akhir: Sempurna! Badge "Diskon 30%" langsung melompat kembali ke dalam kartu produk, bertengger manis menimpa pojok kiri atas gambar sepatu.

Eksperimen Lanjutan: Mengubah Menjadi Pita Miring (Ribbon)

Jika Anda bosan dengan bentuk kotak biasa, kita bisa memodifikasi elemen anak (.badge) ini agar miring di pojok kanan atas menyerupai pita toko online profesional.

1. Tambahkan overflow: hidden; pada induk (.card) agar sisa potongan pita tidak keluar dari batas kartu:

.card {
  overflow: hidden; /* Tambahkan ini di baris terakhir .card Anda */
}

2. Ubah struktur CSS .badge Anda menjadi seperti ini:

.badge {
  position: absolute;
  top: 15px;
  right: -35px;       /* Digeser agak keluar kanan */
  background-color: red;
  color: white;
  padding: 5px 0;
  width: 130px;       /* Menentukan panjang pita */
  text-align: center;
  font-size: 11px;
  font-weight: bold;
  
  /* Memutar kotak sebesar 45 derajat */
  transform: rotate(45deg); 
}

Kesimpulan untuk Diingat

  • Flexbox digunakan untuk mendistribusikan ruang dan menata antrean elemen di jalur horizontal atau vertikal tanpa saling tumpang tindih.
  • Position (Relative & Absolute) digunakan khusus saat kita ingin merusak hukum antrean tersebut demi menumpuk elemen secara visual.
  • Selalu pastikan elemen induk terdekat memiliki position: relative sebelum memberikan position: absolute pada elemen anak.