CSS Dasar #19 - Position Static dan Relative

Setelah mempelajari Box Model dan overflow, sekarang saatnya memahami sistem positioning di CSS. Properti position menentukan bagaimana sebuah elemen ditempatkan dalam halaman. Ada 5 nilai position: static, relative, absolute, fixed, dan sticky. Pada artikel ini, kita akan fokus pada dua yang pertama: static (default) dan relative.


Apa Itu Properti Position?

Position adalah properti CSS yang mengatur metode penempatan suatu elemen. Nilai position menentukan bagaimana elemen diposisikan relatif terhadap posisi normalnya (static flow).

Lima Nilai Position:
1. static → posisi normal (default), tidak terpengaruh top/left/right/bottom.
2. relative → posisi relatif terhadap posisi normalnya (dapat digeser).
3. absolute → posisi absolut terhadap ancestor terdekat yang non-static.
4. fixed → posisi tetap terhadap viewport (tidak ikut scroll).
5. sticky → kombinasi relative dan fixed.

1. Position: Static (Default)

position: static adalah nilai default semua elemen HTML. Elemen dengan position static mengikuti aliran normal dokumen (normal flow). Properti top, right, bottom, left, dan z-index tidak berpengaruh pada elemen static.

Contoh:

<style>
    .static-box {
        position: static;
        background: #3b82f6;
        color: white;
        padding: 15px;
        margin: 10px;
        /* top: 20px; tidak akan berpengaruh */
    }
</style>

<div class="static-box">
    Ini elemen dengan position: static (default). Properti top/left tidak berpengaruh.
</div>
<div class="static-box">
    Elemen static lain mengikuti aliran normal dokumen.
</div>
Ini elemen dengan position: static (default).
Elemen static lain mengikuti aliran normal, turun ke bawah.

Semua elemen block secara default adalah static, sehingga bertumpuk vertikal.

Ciri-ciri Position: Static:
  • Tidak bisa digeser dengan top/left/right/bottom.
  • Mengikuti aliran normal dokumen (normal flow).
  • Tidak mempengaruhi elemen lain secara khusus.
  • Nilai default untuk semua elemen.

2. Position: Relative

position: relative memungkinkan elemen digeser dari posisi normalnya menggunakan properti top, right, bottom, left. Elemen relative tetap mempertahankan ruang aslinya dalam aliran dokumen, sehingga elemen lain tidak akan mengisi celah yang ditinggalkan.

Sintaks Dasar:

.relative-box {
    position: relative;
    top: 20px;    /* geser ke bawah 20px dari posisi normal */
    left: 30px;   /* geser ke kanan 30px dari posisi normal */
}

Contoh:

<style>
    .normal {
        background: #3b82f6;
        color: white;
        padding: 15px;
        margin: 10px;
    }
    .relative {
        position: relative;
        background: #ef4444;
        color: white;
        padding: 15px;
        margin: 10px;
        top: 20px;
        left: 30px;
    }
</style>

<div class="normal">Kotak normal (static)</div>
<div class="relative">Kotak relative (digeser top:20px, left:30px)</div>
<div class="normal">Kotak normal lain (tidak terpengaruh posisi relative)</div>
Kotak normal (static)
Kotak relative (digeser top:20px, left:30px)
Kotak normal lain (tidak terpengaruh, ruang asli kotak relative tetap ada)

Perhatikan bahwa ruang kosong tempat kotak relative seharusnya berada masih ada (kotak normal tidak naik ke atas).

Menggunakan Properti Top, Right, Bottom, Left

Keempat properti ini digunakan untuk menggeser elemen relative dari posisi normalnya:

  • top: 20px; → menggeser elemen ke BAWAH sejauh 20px.
  • bottom: 20px; → menggeser elemen ke ATAS sejauh 20px (jika top dan bottom digunakan bersamaan, top didahulukan).
  • left: 30px; → menggeser elemen ke KANAN sejauh 30px.
  • right: 30px; → menggeser elemen ke KIRI sejauh 30px.

Contoh Pergeseran Berbagai Arah:

<style>
    .box {
        display: inline-block;
        width: 120px;
        padding: 20px;
        margin: 10px;
        background: #3b82f6;
        color: white;
        text-align: center;
    }
    .move-down { position: relative; top: 20px; }
    .move-up { position: relative; bottom: 20px; }
    .move-right { position: relative; left: 30px; }
    .move-left { position: relative; right: 30px; }
</style>

<div class="box">Normal</div>
<div class="box move-down">Geser Bawah</div>
<div class="box move-up">Geser Atas</div>
<div class="box move-right">Geser Kanan</div>
<div class="box move-left">Geser Kiri</div>
Normal
Geser
Bawah
Geser
Atas
Geser
Kanan
Geser
Kiri

Perhatikan bahwa setiap kotak digeser, tetapi ruang asli mereka tetap ada (kotak lain tidak menempati posisi yang digeser).

Kegunaan Position: Relative:
  • Menggeser elemen sedikit dari posisi normal (misal untuk efek hover atau penyesuaian visual).
  • Sebagai anchor container untuk elemen dengan position: absolute (akan dijelaskan di artikel berikutnya).
  • Membuat efek layering (tumpukan) dengan z-index.

Perbedaan Static vs Relative

Aspek Static Relative
Posisi default Ya (semua elemen) Tidak (harus ditentukan)
Dapat digeser (top/left/dll) Tidak Ya
Ruang asli dalam aliran dokumen Ya (selalu) Ya (tetap dipertahankan)
Mempengaruhi posisi elemen lain Ya (normal flow) Tidak (karena ruang asli tetap)
Sebagai anchor untuk absolute child Tidak Ya

Contoh Proyek: Galeri dengan Efek Geser Relative

<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Position Static & Relative - Demo Galeri</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f0f4f8;
            padding: 40px 20px;
        }
        
        .container {
            max-width: 1000px;
            margin: 0 auto;
            background: white;
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 4px 10px rgba(0,0,0,0.05);
        }
        
        h1 {
            text-align: center;
            margin-bottom: 10px;
        }
        
        /* DEMO 1: Static vs Relative */
        .demo-section {
            margin: 30px 0;
            padding: 20px;
            background: #f8fafc;
            border-radius: 16px;
        }
        
        .static-demo {
            background: #3b82f6;
            color: white;
            padding: 15px;
            margin: 10px;
            border-radius: 8px;
        }
        
        .relative-demo {
            position: relative;
            background: #ef4444;
            color: white;
            padding: 15px;
            margin: 10px;
            border-radius: 8px;
            top: 20px;
            left: 30px;
        }
        
        /* DEMO 2: Card dengan efek hover geser */
        .card-grid {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin: 20px 0;
        }
        
        .card {
            background: white;
            border-radius: 16px;
            padding: 20px;
            flex: 1 1 250px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.05);
            transition: all 0.3s;
            position: relative;
            top: 0;
            left: 0;
        }
        
        .card:hover {
            position: relative;
            top: -8px;
            box-shadow: 0 12px 20px rgba(0,0,0,0.1);
        }
        
        /* DEMO 3: Tombol dengan efek geser saat diklik */
        .action-buttons {
            display: flex;
            gap: 15px;
            margin: 20px 0;
            flex-wrap: wrap;
        }
        
        .btn {
            background: #3b82f6;
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 30px;
            cursor: pointer;
            transition: all 0.2s;
            position: relative;
        }
        
        .btn:active {
            top: 2px;
        }
        
        .btn-pressed {
            background: #22c55e;
        }
        
        /* Info box */
        .info-box {
            background: #eef2ff;
            padding: 20px;
            border-radius: 12px;
            margin-top: 30px;
        }
        
        .info-box code {
            background: #e2e8f0;
            padding: 2px 6px;
            border-radius: 4px;
            font-family: monospace;
        }
        
        hr {
            margin: 20px 0;
            border: none;
            border-top: 1px solid #e2e8f0;
        }
    </style>
</head>
<body>

    <div class="container">
        <h1>Position Static vs Relative</h1>
        
        <!-- DEMO 1: Perbandingan -->
        <div class="demo-section">
            <h2>1. Static (default) vs Relative (digeser)</h2>
            <div class="static-demo">Position: static (default) - tidak bisa digeser</div>
            <div class="relative-demo">Position: relative (digeser dengan top:20px, left:30px)</div>
            <div class="static-demo">Kotak static lain - perhatikan bahwa ruang kotak relative masih ada (ada celah)</div>
        </div>
        
        <!-- DEMO 2: Card dengan hover geser -->
        <div class="demo-section">
            <h2>2. Efek Hover: Card Terangkat (relative top: -8px)</h2>
            <div class="card-grid">
                <div class="card">
                    <h3>Card 1</h3>
                    <p>Hover untuk melihat efek angkat menggunakan position: relative.</p>
                </div>
                <div class="card">
                    <h3>Card 2</h3>
                    <p>Saat hover, top: -8px membuat card terangkat ke atas.</p>
                </div>
                <div class="card">
                    <h3>Card 3</h3>
                    <p>Ruang asli card tetap ada sehingga card lain tidak bergerak.</p>
                </div>
            </div>
        </div>
        
        <!-- DEMO 3: Tombol dengan efek tekan -->
        <div class="demo-section">
            <h2>3. Efek Tombol Tekan (relative top: 2px saat aktif)</h2>
            <div class="action-buttons">
                <button class="btn" id="demoBtn1">Klik Saya</button>
                <button class="btn" id="demoBtn2">Tekan dan Lepas</button>
            </div>
            <p style="margin-top: 10px; font-size: 14px;">Saat tombol diklik (active), ia bergeser ke bawah 2px memberikan efek "tekan".</p>
        </div>
        
        <div class="info-box">
            <h3>Ringkasan Position Static & Relative</h3>
            <ul>
                <li><code>position: static</code> adalah nilai default semua elemen. Properti top/left tidak berpengaruh.</li>
                <li><code>position: relative</code> memungkinkan pergeseran dengan top, right, bottom, left.</li>
                <li>Elemen relative tetap mempertahankan ruang aslinya dalam aliran dokumen (elemen lain tidak akan mengisi celah).</li>
                <li>Relative sering digunakan untuk efek hover (angkat card), efek tekan tombol, atau sebagai anchor untuk absolute positioning.</li>
                <li>Nilai positif top menggeser ke BAWAH, nilai positif left menggeser ke KANAN.</li>
                <li>Nilai negatif top menggeser ke ATAS, nilai negatif left menggeser ke KIRI.</li>
            </ul>
        </div>
    </div>

    <script>
        // Efek tambahan pada tombol: saat diklik, beri efek visual
        const btn1 = document.getElementById('demoBtn1');
        const btn2 = document.getElementById('demoBtn2');
        
        if (btn1) {
            btn1.addEventListener('mousedown', function() {
                this.style.top = '2px';
            });
            btn1.addEventListener('mouseup', function() {
                this.style.top = '0';
            });
            btn1.addEventListener('mouseleave', function() {
                this.style.top = '0';
            });
        }
        
        if (btn2) {
            btn2.addEventListener('mousedown', function() {
                this.style.top = '2px';
            });
            btn2.addEventListener('mouseup', function() {
                this.style.top = '0';
            });
            btn2.addEventListener('mouseleave', function() {
                this.style.top = '0';
            });
        }
    </script>

</body>
</html>

Hasil visual halaman demo:

Static vs Relative

Static - posisi normal
Relative - digeser top:15px, left:20px
Static lain (ada celah dari relative)
Ringkasan: Static adalah default, relative dapat digeser dan ruang aslinya tetap.

Kesalahan Umum Pemula

  • Mengira relative akan menghilangkan ruang asli → Tidak, relative tetap mempertahankan ruang asli (seperti elemen static).
  • Menggunakan top/left pada elemen static → Tidak berpengaruh, harus ubah ke relative/fixed/absolute dulu.
  • Tertukar arah gesertop: 20px menggeser ke BAWAH, bottom: 20px menggeser ke ATAS.
  • Lupa bahwa relative dapat digunakan sebagai anchor untuk absolute → Ini sangat penting untuk layout kompleks.
  • Mengira relative dapat mempengaruhi posisi elemen lain → Tidak, karena ruang asli tetap, elemen lain tidak berubah posisi.
Debugging Tips:
  • Buka Developer Tools (F12) → inspect elemen → lihat tab Computed → cek nilai position dan top/left.
  • Untuk melihat ruang asli elemen relative, perhatikan area yang tersisa (bisa dilihat dengan outline).

Latihan Singkat

  1. Buat 3 div dengan background berbeda. Beri div kedua position: relative; top: 20px; left: 20px;. Amati perubahannya.
  2. Buat tombol dengan efek tekan (saat diklik, top: 2px) menggunakan position: relative.
  3. Buat kartu yang saat hover terangkat (top: -5px) dengan transisi halus.
  4. Buat elemen teks yang digeser ke kanan 30px menggunakan position: relative dan left.
  5. Coba gunakan nilai negatif (top: -20px) dan lihat efeknya.

Intisari Hari Ini

  • position: static → default, tidak bisa digeser, mengikuti normal flow.
  • position: relative → dapat digeser dengan top/right/bottom/left, ruang asli tetap dipertahankan.
  • Properti top/left/bottom/right hanya berpengaruh jika elemen memiliki position selain static (relative, absolute, fixed, sticky).
  • Nilai positif top menggeser ke bawah, negatif ke atas. Positif left menggeser ke kanan, negatif ke kiri.
  • Relative sering digunakan untuk efek hover (mengangkat elemen) atau sebagai anchor container untuk absolute positioning.
Tantangan: Buat sebuah Halaman Portofolio dengan Kartu Proyek yang memiliki efek hover menggunakan position: relative! Persyaratan:
  • Minimal 4 kartu proyek dalam grid.
  • Setiap kartu saat hover: terangkat (top: -8px), bayangan membesar, dan border berubah warna.
  • Di dalam kartu, judul proyek dan deskripsi singkat.
  • Tambahkan tombol "Lihat Detail" yang saat diklik memiliki efek tekan (top: 2px).
  • Di bagian bawah halaman, buat perbandingan visual antara posisi normal dan saat digeser menggunakan relative.
  • Tambahkan kotak penjelasan tentang perbedaan static dan relative.

Selamat mencoba!

Artikel Sebelumnya: CSS Dasar #18 - Overflow: visible, hidden, scroll, auto
Artikel Selanjutnya: CSS Dasar #20 - Position Absolute

Lebih baru Lebih lama

نموذج الاتصال