CSS Dasar #21 - Position Fixed dan Sticky

Setelah mempelajari position static, relative, dan absolute, sekarang saatnya memahami position: fixed dan position: sticky. Kedua nilai ini sangat berguna untuk membuat elemen yang tetap terlihat saat halaman di-scroll (fixed) atau menempel setelah melewati posisi tertentu (sticky).


1. Position Fixed

position: fixed membuat elemen tetap pada posisinya relatif terhadap viewport (layar browser). Elemen fixed keluar dari aliran normal dokumen dan tidak ikut scroll. Sangat cocok untuk navbar, tombol back-to-top, atau chat widget.

Ciri-ciri Position Fixed:
  • Elemen tetap di posisi yang sama saat di-scroll.
  • Posisi relatif terhadap viewport (bukan terhadap parent).
  • Keluar dari normal flow (ruang asli hilang).
  • Biasanya digunakan untuk navbar sticky, tombol floating, modal overlay, cookie consent.

Contoh Fixed Navbar:

<style>
    .fixed-navbar {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        background: #1e293b;
        color: white;
        padding: 15px;
        text-align: center;
        z-index: 100;
    }
    .content {
        margin-top: 60px;
        padding: 20px;
    }
</style>

<div class="fixed-navbar">Navbar Fixed (tetap di atas saat scroll)</div>
<div class="content">
    <p>Konten halaman... (scroll untuk melihat navbar tetap)</p>
</div>
Navbar Fixed (tetap di atas saat scroll area ini)

Baris 1: Scroll area ini untuk demo fixed.

Baris 2: Navbar di atas tetap terlihat.

Baris 3: Coba scroll ke bawah.

Baris 4: Navbar tidak ikut scroll.

Baris 5: Ini adalah contoh position: sticky pada elemen nav (bukan fixed sebenarnya, tapi efek mirip).

Baris 6: Untuk fixed terhadap viewport, tidak bisa didemo dalam kotak terbatas.

Perbedaan Fixed vs Absolute:
- Fixed: relatif terhadap viewport (tidak peduli parent). Saat scroll, tetap di tempat.
- Absolute: relatif terhadap ancestor non-static terdekat. Saat scroll, ikut scroll.

2. Position Sticky

position: sticky adalah kombinasi antara relative dan fixed. Elemen sticky berperilaku seperti relative selama berada dalam viewport, tetapi akan menjadi fixed saat melewati batas tertentu (misal jarak dari atas). Sangat cocok untuk header tabel, sidebar, atau tombol yang ingin menempel saat di-scroll.

Ciri-ciri Position Sticky:
  • Berperilaku relative sebelum mencapai posisi sticky.
  • Berperilaku fixed setelah melewati posisi tertentu (ditentukan dengan top, left, dll).
  • Tetap dalam aliran normal dokumen (ruang asli dipertahankan).
  • Berguna untuk header kolom tabel, sidebar, menu kategori, navbar yang muncul setelah scroll.

Contoh Sticky Header:

<style>
    .sticky-header {
        position: sticky;
        top: 0;
        background: #3b82f6;
        color: white;
        padding: 10px;
        text-align: center;
    }
    .content {
        height: 400px;
        background: #f0f4f8;
        padding: 20px;
    }
</style>

<div class="sticky-header">Header Sticky (menempel di atas saat scroll)</div>
<div class="content">Scroll ke bawah untuk melihat header menempel</div>
Header Sticky (menempel di atas area scroll ini)

Baris 1: Scroll area ini.

Baris 2: Header akan menempel di atas.

Baris 3: Saat scroll ke bawah, header tetap terlihat.

Baris 4: Ini efek dari position: sticky.

Baris 5: Header tidak ikut scroll.

Baris 6: Karena top: 0, dia menempel di tepi atas container scroll.

Contoh Sticky Sidebar:

<style>
    .container {
        display: flex;
        gap: 20px;
    }
    .sidebar {
        position: sticky;
        top: 20px;
        background: #22c55e;
        color: white;
        padding: 15px;
        width: 200px;
        height: 200px;
    }
    .content {
        flex: 1;
        background: #f0f4f8;
        padding: 15px;
        height: 600px;
    }
</style>

<div class="container">
    <div class="sidebar">Sidebar Sticky (menempel setelah scroll)</div>
    <div class="content">Konten panjang... scroll untuk melihat sidebar tetap terlihat.</div>
</div>
Sidebar Sticky (menempel di area scroll)

Scroll area ini untuk melihat sticky sidebar.

Sidebar akan tetap terlihat saat scroll ke bawah.

Baris 1

Baris 2

Baris 3

Baris 4

Baris 5

Sidebar sticky menempel saat container discroll.

Catatan Penting Sticky:
  • Sticky hanya berfungsi jika parent-nya memiliki tinggi yang cukup untuk di-scroll.
  • Nilai top, right, bottom, atau left wajib ditentukan agar sticky aktif.
  • Elemen sticky tidak akan keluar dari parent-nya (batas parent adalah batas akhir efek sticky).
  • Beberapa browser lama mungkin tidak mendukung sticky.

Contoh Proyek: Navbar Fixed + Sidebar Sticky + Tombol Back to Top

<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Position Fixed & Sticky - Demo Lengkap</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f0f4f8;
        }
        
        /* Navbar Fixed */
        .navbar {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            background: #1e293b;
            color: white;
            padding: 15px 30px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            z-index: 1000;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        
        .logo {
            font-size: 20px;
            font-weight: bold;
        }
        
        .nav-links a {
            color: white;
            text-decoration: none;
            margin-left: 25px;
        }
        
        /* Container utama dengan padding-top untuk navbar fixed */
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 80px 20px 40px;
        }
        
        /* Layout flex untuk konten + sidebar */
        .content-wrapper {
            display: flex;
            gap: 30px;
        }
        
        /* Sidebar Sticky */
        .sidebar {
            position: sticky;
            top: 80px;
            width: 280px;
            background: white;
            border-radius: 16px;
            padding: 20px;
            box-shadow: 0 4px 10px rgba(0,0,0,0.05);
            height: fit-content;
        }
        
        .sidebar h3 {
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 2px solid #3b82f6;
        }
        
        .sidebar ul {
            list-style: none;
        }
        
        .sidebar li {
            margin-bottom: 10px;
        }
        
        .sidebar a {
            text-decoration: none;
            color: #475569;
            transition: color 0.2s;
        }
        
        .sidebar a:hover {
            color: #3b82f6;
        }
        
        /* Main Content */
        .main-content {
            flex: 1;
            background: white;
            border-radius: 16px;
            padding: 30px;
            box-shadow: 0 4px 10px rgba(0,0,0,0.05);
        }
        
        .main-content h2 {
            margin-bottom: 20px;
            color: #1e293b;
        }
        
        .main-content p {
            margin-bottom: 15px;
            line-height: 1.6;
            color: #475569;
        }
        
        /* Sticky Header dalam artikel (untuk efek) */
        .sticky-subheader {
            position: sticky;
            top: 80px;
            background: #eef2ff;
            padding: 12px;
            border-radius: 8px;
            margin: 20px 0;
            font-weight: bold;
            color: #3b82f6;
        }
        
        /* Tombol Back to Top (Fixed) */
        .back-to-top {
            position: fixed;
            bottom: 30px;
            right: 30px;
            background: #3b82f6;
            color: white;
            width: 50px;
            height: 50px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            text-decoration: none;
            font-size: 24px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            transition: all 0.2s;
            z-index: 100;
        }
        
        .back-to-top:hover {
            background: #2563eb;
            transform: scale(1.05);
        }
        
        /* Footer */
        footer {
            background: #1e293b;
            color: #94a3b8;
            text-align: center;
            padding: 30px;
            margin-top: 40px;
        }
        
        .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;
        }
        
        @media (max-width: 768px) {
            .content-wrapper {
                flex-direction: column;
            }
            .sidebar {
                width: 100%;
                position: static;
            }
            .sticky-subheader {
                top: 70px;
            }
        }
    </style>
</head>
<body>

    <nav class="navbar">
        <div class="logo">MyWebsite</div>
        <div class="nav-links">
            <a href="#">Home</a>
            <a href="#">About</a>
            <a href="#">Services</a>
            <a href="#">Contact</a>
        </div>
    </nav>

    <div class="container">
        <div class="content-wrapper">
            <aside class="sidebar">
                <h3>Kategori</h3>
                <ul>
                    <li><a href="#">HTML Dasar</a></li>
                    <li><a href="#">CSS Dasar</a></li>
                    <li><a href="#">JavaScript Dasar</a></li>
                    <li><a href="#">ReactJS</a></li>
                    <li><a href="#">Node.js</a></li>
                </ul>
            </aside>

            <main class="main-content">
                <h1>Position Fixed & Sticky</h1>
                <p>Halaman ini mendemonstrasikan penggunaan position: fixed pada navbar dan tombol back-to-top, serta position: sticky pada sidebar.</p>
                
                <div class="sticky-subheader">
                    🖊️ Subheader Sticky - Menempel saat scroll
                </div>
                
                <h2>Apa Itu Position Fixed?</h2>
                <p>Position fixed membuat elemen tetap pada posisinya relatif terhadap viewport. Elemen fixed tidak ikut scroll. Contoh: navbar di atas dan tombol back-to-top di kanan bawah.</p>
                
                <h2>Apa Itu Position Sticky?</h2>
                <p>Position sticky adalah kombinasi antara relative dan fixed. Elemen akan berperilaku seperti relative selama berada dalam viewport, tetapi akan menjadi fixed saat melewati batas yang ditentukan. Contoh: sidebar di kiri dan subheader di atas.</p>
                
                <h2>Keuntungan Menggunakan Fixed & Sticky</h2>
                <p>1. Meningkatkan navigasi (navbar selalu terlihat).</p>
                <p>2. Memudahkan akses ke elemen penting (tombol back-to-top).</p>
                <p>3. Memberikan konteks yang terus terlihat (sidebar kategori).</p>
                <p>4. Meningkatkan pengalaman pengguna pada halaman panjang.</p>
                
                <div class="sticky-subheader" style="margin-top: 30px;">
                    📌 Sticky Header Lainnya (Contoh)
                </div>
                
                <h2>Tips Penggunaan</h2>
                <p>Untuk fixed: beri padding-top pada body atau container agar konten tidak tertutup navbar. Untuk sticky: pastikan parent memiliki tinggi yang cukup dan tentukan nilai top/left.</p>
                <p>Scroll terus ke bawah untuk melihat sidebar sticky dan tombol back-to-top. Sidebar akan menempel saat discroll, tombol back-to-top selalu di pojok kanan bawah.</p>
            </main>
        </div>
        
        <div class="info-box">
            <h3>Ringkasan Position Fixed & Sticky</h3>
            <ul>
                <li><code>position: fixed</code> → tetap relatif terhadap viewport (tidak ikut scroll).</li>
                <li><code>position: sticky</code> → relative sampai batas tertentu, lalu fixed.</li>
                <li>Fixed dan sticky keduanya keluar dari normal flow? Fixed: ya; Sticky: tidak (ruang asli tetap).</li>
                <li>Fixed sering untuk navbar, tombol floating, modal overlay.</li>
                <li>Sticky sering untuk header tabel, sidebar, menu kategori.</li>
                <li>Sticky WAJIB memiliki nilai top/right/bottom/left agar berfungsi.</li>
            </ul>
        </div>
    </div>

    <a href="#" class="back-to-top" id="backToTop">↑</a>

    <footer>
        <p>© 2024 - Belajar Position Fixed & Sticky | Scroll untuk melihat efek fixed dan sticky</p>
    </footer>

    <script>
        // Smooth scroll untuk back to top
        const backBtn = document.getElementById('backToTop');
        if (backBtn) {
            backBtn.addEventListener('click', (e) => {
                e.preventDefault();
                window.scrollTo({ top: 0, behavior: 'smooth' });
            });
        }
    </script>

</body>
</html>

Hasil visual halaman demo:

MyWebsite Home About Services Contact
Kategori

HTML Dasar

CSS Dasar

Position Fixed & Sticky

Halaman ini mendemonstrasikan penggunaan position: fixed pada navbar dan position: sticky pada sidebar.

Ringkasan: Fixed tetap di viewport, sticky menempel setelah melewati batas.

Perbandingan Fixed vs Sticky

Aspek Fixed Sticky
Acuan posisi Viewport (selalu) Parent (relatif terhadap container scroll)
Keluar dari normal flow Ya (ruang hilang) Tidak (ruang asli tetap)
Wajib nilai top/left Tidak wajib, tapi biasanya digunakan WAJIB (top, right, bottom, atau left)
Terbatas oleh parent Tidak (bisa keluar dari parent) Ya (tidak bisa keluar dari parent)
Contoh penggunaan Navbar, tombol floating, modal Header tabel, sidebar, menu kategori

Kesalahan Umum Pemula

  • Lupa memberi nilai top/left untuk sticky → Sticky tidak akan berfungsi tanpa nilai top, right, bottom, atau left.
  • Mengira fixed relatif terhadap parent → Fixed selalu relatif terhadap viewport.
  • Lupa memberi padding-top pada body saat menggunakan fixed navbar → Konten bisa tertutup navbar.
  • Sticky tidak berfungsi karena parent tidak memiliki cukup tinggi → Sticky membutuhkan ruang scroll di dalam parent.
  • Mengira sticky bisa digunakan pada elemen dengan overflow: hidden pada parent → Overflow: hidden dapat mematahkan sticky.
Debugging Tips:
  • Untuk fixed, cek apakah elemen lain memiliki z-index yang lebih tinggi (bisa menutupi).
  • Untuk sticky, pastikan parent memiliki tinggi yang cukup dan tidak ada overflow: hidden.
  • Gunakan Developer Tools untuk melihat apakah sticky aktif (biasanya ada indikator di panel Styles).

Latihan Singkat

  1. Buat navbar fixed di atas halaman dengan padding-top pada body.
  2. Buat tombol back-to-top fixed di pojok kanan bawah.
  3. Buat sidebar sticky yang menempel saat discroll (top: 100px).
  4. Buat header tabel sticky (thead) agar tetap terlihat saat scroll tabel panjang.
  5. Coba kombinasi fixed navbar dan sticky sidebar dalam satu halaman.

Intisari Hari Ini

  • position: fixed → tetap terhadap viewport, keluar dari normal flow.
  • position: sticky → relative sampai batas tertentu, lalu fixed (tetap dalam flow).
  • Fixed sering untuk navbar, tombol floating, modal overlay.
  • Sticky sering untuk header tabel, sidebar, menu kategori.
  • Sticky wajib memiliki nilai top/right/bottom/left agar berfungsi.
  • Untuk fixed navbar, beri padding-top pada body agar konten tidak tertutup.
Tantangan: Buat sebuah Halaman Dokumentasi dengan Sidebar Sticky dan Header Fixed! Persyaratan:
  • Navbar fixed di atas.
  • Sidebar kiri dengan daftar menu (position: sticky, top: 80px).
  • Konten utama di kanan dengan beberapa section (setiap section memiliki heading).
  • Heading section juga sticky (top: 80px) saat discroll.
  • Tombol back-to-top fixed di pojok kanan bawah.
  • Pada layar mobile (<768px), sidebar berubah menjadi tidak sticky (static) dan responsif.
  • Tambahkan kotak penjelasan yang menunjukkan elemen mana yang menggunakan fixed dan mana yang sticky.

Selamat mencoba!

Artikel Sebelumnya: CSS Dasar #20 - Position Absolute
Artikel Selanjutnya: CSS Dasar #22 - Z-Index: Mengatur Tumpukan Elemen

Lebih baru Lebih lama

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