CSS Dasar #7 - Pseudo-class (hover, focus, active, visited, first-child, last-child, nth-child)

Setelah kita mempelajari berbagai jenis selektor, sekarang saatnya mengenal pseudo-class. Pseudo-class adalah kata kunci yang ditambahkan ke selektor untuk memilih elemen dalam keadaan atau posisi tertentu. Pseudo-class memungkinkan kita membuat efek interaktif tanpa JavaScript!


Apa Itu Pseudo-class?

Pseudo-class adalah kata kunci yang ditambahkan ke selektor dengan tanda titik dua (:) untuk memilih elemen berdasarkan keadaan atau posisi tertentu. Contoh: elemen yang sedang di-hover, elemen pertama dalam container, elemen yang sedang focus, dll.

Sintaks Pseudo-class:
selektor:pseudo-class {
    properti: nilai;
}

/* Contoh: mengubah warna link saat di-hover */
a:hover {
    color: red;
}
    

Jenis-jenis Pseudo-class

Ada banyak sekali pseudo-class. Berikut yang paling sering digunakan:

Pseudo-class Fungsi Contoh
:hover Saat mouse berada di atas elemen button:hover { background: blue; }
:focus Saat elemen menerima fokus (klik atau tab) input:focus { border: 2px solid blue; }
:active Saat elemen sedang diklik (aktif) button:active { transform: scale(0.95); }
:visited Link yang sudah pernah dikunjungi a:visited { color: purple; }
:first-child Elemen anak pertama dari parentnya li:first-child { font-weight: bold; }
:last-child Elemen anak terakhir dari parentnya li:last-child { border-bottom: none; }
:nth-child(n) Elemen anak ke-n dari parentnya li:nth-child(2) { background: yellow; }
:not(selector) Semua elemen kecuali yang ditentukan p:not(.special) { color: gray; }

1. Pseudo-class :hover

:hover digunakan untuk mengubah gaya elemen saat mouse berada di atasnya. Sangat umum digunakan untuk tombol, link, dan kartu.

Contoh:

<style>
    .btn {
        background-color: #3b82f6;
        color: white;
        padding: 10px 20px;
        border: none;
        border-radius: 8px;
        cursor: pointer;
        transition: all 0.3s;
    }
    
    .btn:hover {
        background-color: #2563eb;
        transform: translateY(-2px);
        box-shadow: 0 4px 8px rgba(0,0,0,0.2);
    }
    
    .card {
        background: white;
        padding: 20px;
        border-radius: 12px;
        transition: transform 0.3s, box-shadow 0.3s;
    }
    
    .card:hover {
        transform: translateY(-5px);
        box-shadow: 0 10px 20px rgba(0,0,0,0.1);
    }
    
    a {
        color: #3b82f6;
        text-decoration: none;
        transition: color 0.3s;
    }
    
    a:hover {
        color: #2563eb;
        text-decoration: underline;
    }
</style>

<button class="btn">Hover Saya</button>
<div class="card">Kartu dengan efek hover</div>
<a href="#">Link dengan efek hover</a>

Hasilnya:

Kartu dengan efek hover
Link dengan efek hover
Tips :hover:
  • Tambahkan transition untuk efek yang halus
  • Hover bisa digunakan di hampir semua elemen, bukan hanya link
  • Di perangkat sentuh (HP), hover biasanya tidak berfungsi atau bermasalah

2. Pseudo-class :focus

:focus digunakan saat elemen menerima fokus (diklik atau di-tab menggunakan keyboard). Sangat penting untuk aksesibilitas.

Contoh:

<style>
    input, textarea, select {
        padding: 10px;
        border: 2px solid #cbd5e1;
        border-radius: 8px;
        transition: all 0.3s;
        width: 100%;
        margin-bottom: 10px;
    }
    
    input:focus, textarea:focus, select:focus {
        outline: none;
        border-color: #3b82f6;
        box-shadow: 0 0 0 3px rgba(59,130,246,0.2);
    }
    
    button:focus {
        outline: 2px solid #3b82f6;
        outline-offset: 2px;
    }
    
    a:focus {
        outline: 2px solid #3b82f6;
        outline-offset: 2px;
        border-radius: 4px;
    }
</style>

<input type="text" placeholder="Klik atau tab ke sini">
<textarea rows="2" placeholder="Textarea dengan focus effect"></textarea>
<button>Tombol dengan focus</button>

Hasilnya:

Penting untuk Aksesibilitas:
  • :focus membantu pengguna yang hanya menggunakan keyboard (tanpa mouse)
  • Jangan pernah menghapus outline tanpa memberikan alternatif visual
  • Gunakan outline atau box-shadow untuk indikator fokus yang jelas

3. Pseudo-class :active

:active digunakan saat elemen sedang diklik (saat mouse ditekan, belum dilepaskan).

Contoh:

<style>
    .press-btn {
        background-color: #3b82f6;
        color: white;
        padding: 12px 24px;
        border: none;
        border-radius: 8px;
        cursor: pointer;
        transition: all 0.05s;
    }
    
    .press-btn:active {
        transform: scale(0.97);
        background-color: #1e40af;
    }
    
    .scale-card {
        background: white;
        padding: 20px;
        border-radius: 12px;
        transition: transform 0.05s;
        cursor: pointer;
    }
    
    .scale-card:active {
        transform: scale(0.98);
    }
</style>

<button class="press-btn">Klik dan tahan</button>
<div class="scale-card">Klik pada kartu ini</div>

Hasilnya:

Klik pada kartu ini

4. Pseudo-class :visited

:visited digunakan untuk link yang sudah pernah dikunjungi oleh pengguna.

Contoh:

<style>
    a {
        color: #3b82f6;
        text-decoration: none;
        padding: 5px;
        display: inline-block;
    }
    
    a:visited {
        color: #8b5cf6;
    }
    
    a:hover {
        text-decoration: underline;
    }
</style>

<a href="https://www.google.com" target="_blank">Google (belum dikunjungi - biru)</a>
<a href="https://www.example.com" target="_blank">Example (coba klik, lalu kembali)</a>
Link 1 (klik dulu) Link 2 (klik dulu)

Klik link di atas, lalu kembali ke halaman ini. Warna link akan berubah menjadi ungu.

Batasan :visited:
  • Karena alasan privasi, hanya properti tertentu yang bisa diubah (color, background-color, border-color)
  • Properti seperti display, width, height tidak bisa diubah pada :visited

5. Pseudo-class :first-child, :last-child, :nth-child(n)

Pseudo-class ini digunakan untuk memilih elemen berdasarkan posisinya di antara saudara-saudaranya.

Contoh :first-child dan :last-child:

<style>
    /* Item pertama dalam list */
    li:first-child {
        background-color: #dcfce7;
        font-weight: bold;
    }
    
    /* Item terakhir dalam list */
    li:last-child {
        background-color: #fee2e2;
        border-bottom: none;
    }
    
    /* Paragraf pertama dalam artikel */
    article p:first-child {
        font-size: 18px;
        font-weight: bold;
        color: #3b82f6;
    }
    
    /* Paragraf terakhir dalam artikel */
    article p:last-child {
        margin-bottom: 0;
    }
</style>

<ul>
    <li>Item pertama (first-child)</li>
    <li>Item tengah</li>
    <li>Item terakhir (last-child)</li>
</ul>

<article>
    <p>Paragraf pertama dalam article (first-child)</p>
    <p>Paragraf tengah</p>
    <p>Paragraf terakhir dalam article (last-child)</p>
</article>

Hasilnya:

  • Item pertama (first-child)
  • Item tengah
  • Item terakhir (last-child)

Contoh :nth-child(n):

<style>
    /* Item ke-2 */
    li:nth-child(2) {
        background-color: #fef9c3;
    }
    
    /* Item genap (2,4,6,8...) */
    tr:nth-child(even) {
        background-color: #f0f4f8;
    }
    
    /* Item ganjil (1,3,5,7...) */
    tr:nth-child(odd) {
        background-color: white;
    }
    
    /* Setiap 3 item (3,6,9...) */
    .product:nth-child(3n) {
        border-right: none;
    }
    
    /* 3 item pertama */
    .item:nth-child(-n+3) {
        font-weight: bold;
    }
    
    /* Mulai dari item ke-4 */
    .item:nth-child(n+4) {
        color: #64748b;
    }
</style>

<ul>
    <li>Item 1</li>
    <li>Item 2 (nth-child(2))</li>
    <li>Item 3</li>
    <li>Item 4</li>
</ul>

<table>
    <tr><td>Baris 1 (ganjil)</td></tr>
    <tr><td>Baris 2 (genap)</td></tr>
    <tr><td>Baris 3 (ganjil)</td></tr>
    <tr><td>Baris 4 (genap)</td></tr>
</table>

Hasilnya:

  • Item 1
  • Item 2 (nth-child(2))
  • Item 3
  • Item 4
Baris 1 (ganjil)
Baris 2 (genap)
Baris 3 (ganjil)
Baris 4 (genap)
Rumus :nth-child yang Berguna:
  • :nth-child(odd) → item ganjil (1,3,5,7...)
  • :nth-child(even) → item genap (2,4,6,8...)
  • :nth-child(3n) → setiap 3 item (3,6,9...)
  • :nth-child(3n+1) → item ke-1,4,7,10...
  • :nth-child(-n+3) → 3 item pertama
  • :nth-child(n+4) → mulai dari item ke-4

Contoh Proyek: Tabel Data dengan Zebra Striping

<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pseudo-class - Tabel Data</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: 900px;
            margin: 0 auto;
            background: white;
            border-radius: 16px;
            padding: 25px;
            box-shadow: 0 4px 10px rgba(0,0,0,0.05);
        }
        
        h1 {
            color: #1e293b;
            margin-bottom: 5px;
        }
        
        .subtitle {
            color: #64748b;
            margin-bottom: 25px;
            border-bottom: 2px solid #e2e8f0;
            padding-bottom: 15px;
        }
        
        /* ========== STYLING TABEL ========== */
        table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 30px;
        }
        
        th {
            background-color: #3b82f6;
            color: white;
            padding: 12px;
            text-align: left;
        }
        
        td {
            padding: 10px 12px;
            border-bottom: 1px solid #e2e8f0;
        }
        
        /* Zebra striping - baris genap */
        tbody tr:nth-child(even) {
            background-color: #f8fafc;
        }
        
        /* Hover effect pada baris */
        tbody tr:hover {
            background-color: #eef2ff;
            cursor: pointer;
        }
        
        /* Baris pertama (header) sudah di-th, tidak perlu */
        
        /* ========== STYLING BUTTON ========== */
        .btn {
            background-color: #3b82f6;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 8px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.2s;
            margin-right: 10px;
        }
        
        .btn:hover {
            background-color: #2563eb;
            transform: translateY(-2px);
        }
        
        .btn:active {
            transform: translateY(0);
        }
        
        .btn-secondary {
            background-color: #64748b;
        }
        
        .btn-secondary:hover {
            background-color: #475569;
        }
        
        /* ========== STYLING FORM ========== */
        .form-group {
            margin-bottom: 15px;
        }
        
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: 500;
            color: #1e293b;
        }
        
        input, select {
            width: 100%;
            padding: 10px;
            border: 2px solid #cbd5e1;
            border-radius: 8px;
            transition: all 0.2s;
        }
        
        input:focus, select:focus {
            outline: none;
            border-color: #3b82f6;
            box-shadow: 0 0 0 3px rgba(59,130,246,0.2);
        }
        
        /* ========== STYLING CARD GRID ========== */
        .card-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
            gap: 20px;
            margin: 25px 0;
        }
        
        .card {
            background: #f8fafc;
            padding: 20px;
            border-radius: 12px;
            transition: all 0.3s;
        }
        
        .card:hover {
            transform: translateY(-4px);
            box-shadow: 0 8px 20px rgba(0,0,0,0.1);
        }
        
        /* Kartu pertama dalam grid */
        .card:first-child {
            border: 2px solid #3b82f6;
        }
        
        /* Kartu terakhir dalam grid */
        .card:last-child {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        
        .info-box {
            background: #eef2ff;
            padding: 20px;
            border-radius: 12px;
            margin-top: 25px;
        }
        
        .info-box code {
            background: #e2e8f0;
            padding: 2px 6px;
            border-radius: 4px;
            font-family: monospace;
        }
        
        .info-box pre {
            background: #1e1e2e;
            color: #fff;
            padding: 12px;
            border-radius: 8px;
            overflow-x: auto;
            margin: 10px 0;
            font-size: 13px;
        }
    </style>
</head>
<body>

    <div class="container">
        <h1>Pseudo-class dalam CSS</h1>
        <p class="subtitle">hover, focus, active, visited, first-child, last-child, nth-child</p>
        
        <h2>Tabel Data dengan Zebra Striping</h2>
        
No Nama Email Status
1Andi Saputraandi@email.comAktif
2Budi Santosobudi@email.comAktif
3Citra Lestaricitra@email.comNonaktif
4Dewi Anggrainidewi@email.comAktif
5Eko Prasetyoeko@email.comAktif
<h2>Demo Tombol</h2> <button class="btn">Simpan</button> <button class="btn btn-secondary">Batal</button> <h2 style="margin-top: 25px;">Demo Form Input</h2> <div class="form-group"> <label>Nama Lengkap</label> <input type="text" placeholder="Masukkan nama lengkap"> </div> <div class="form-group"> <label>Kategori</label> <select> <option>Pilih kategori</option> <option>HTML</option> <option>CSS</option> <option>JavaScript</option> </select> </div> <h2>Card Grid dengan Pseudo-class</h2> <div class="card-grid"> <div class="card"> <h3>Card Pertama</h3> <p>Memiliki border biru karena :first-child</p> </div> <div class="card"> <h3>Card Kedua</h3> <p>Memiliki efek hover</p> </div> <div class="card"> <h3>Card Terakhir</h3> <p>Background gradien karena :last-child</p> </div> </div> <div class="info-box"> <h3>Pseudo-class yang Digunakan di Halaman Ini:</h3> <ul> <li><code>tbody tr:nth-child(even)</code> → zebra striping pada tabel</li> <li><code>tbody tr:hover</code> → efek hover pada baris tabel</li> <li><code>.btn:hover</code> → efek hover pada tombol</li> <li><code>.btn:active</code> → efek klik pada tombol</li> <li><code>input:focus, select:focus</code> → efek fokus pada form</li> <li><code>.card:first-child</code> → styling kartu pertama</li> <li><code>.card:last-child</code> → styling kartu terakhir</li> <li><code>.card:hover</code> → efek hover pada kartu</li> </ul> </div> </div> </body> </html>

Hasil visual halaman demo:

Pseudo-class dalam CSS

hover, focus, active, visited, first-child, last-child, nth-child

Tabel Data dengan Zebra Striping

NoNama
1Andi
2Budi
3Citra
Pseudo-class yang Digunakan: nth-child(even), hover, focus, active, first-child, last-child

Tabel Ringkasan Pseudo-class

Pseudo-class Kapan Terjadi? Contoh Penggunaan
:hover Mouse berada di atas elemen Efek pada tombol, kartu, link
:focus Elemen menerima fokus (klik/tab) Styling input saat aktif, aksesibilitas keyboard
:active Elemen sedang diklik Efek tekan pada tombol
:visited Link yang sudah dikunjungi Membedakan link yang sudah/belum diklik
:first-child Elemen anak pertama Styling item pertama dalam list
:last-child Elemen anak terakhir Menghapus border item terakhir
:nth-child(n) Elemen anak ke-n Zebra striping, styling setiap 3 item

Kesalahan Umum Pemula

  • Lupa titik dua (:) sebelum pseudo-classhover (salah) vs :hover (benar).
  • Mengira :first-child memilih elemen pertama dengan class tertentu → :first-child memilih anak pertama DARI PARENTNYA, bukan elemen pertama dengan class tertentu.
  • Menggunakan :nth-child dengan rumus yang salah → Perhatikan bahwa hitungan dimulai dari 1, bukan 0.
  • Menghapus outline tanpa memberikan alternatif → Buruk untuk aksesibilitas keyboard.
  • Mengira :visited bisa mengubah semua properti → Karena alasan privasi, hanya properti tertentu yang bisa diubah.
Debugging Tips:
  • Buka Developer Tools (F12) → inspect elemen → lihat pseudo-class yang aktif di panel Styles (biasanya ada ikon :hov)
  • Gunakan tab "Force element state" di DevTools untuk mensimulasikan hover, focus, active
  • Untuk :nth-child, gunakan console untuk menghitung posisi elemen

Latihan Singkat

  1. Buat file HTML dengan beberapa tombol, terapkan efek :hover (ubah warna, scale)
  2. Buat form input dengan :focus effect (border biru, shadow)
  3. Buat list dengan 5 item, styling item pertama dan terakhir berbeda
  4. Buat tabel dengan zebra striping menggunakan :nth-child(even)
  5. Buat card grid dengan 4 kartu, styling kartu ke-3 dengan warna berbeda

Intisari Hari Ini

  • Pseudo-class adalah kata kunci untuk memilih elemen dalam keadaan atau posisi tertentu
  • :hover → saat mouse di atas elemen (efek interaktif)
  • :focus → saat elemen menerima fokus (penting untuk aksesibilitas)
  • :active → saat elemen sedang diklik
  • :visited → link yang sudah dikunjungi
  • :first-child, :last-child → elemen anak pertama/terakhir
  • :nth-child(n) → elemen anak ke-n (bisa dengan rumus seperti odd, even, 3n, -n+3, dll)
Tantangan: Buat sebuah Halaman Galeri Foto dengan efek interaktif menggunakan pseudo-class! Persyaratan:
  • Galeri dengan minimal 9 foto (grid 3x3)
  • Efek hover pada foto: zoom (scale), shadow, dan overlay teks
  • Foto pertama memiliki border khusus menggunakan :first-child
  • Foto terakhir memiliki efek berbeda menggunakan :last-child
  • Setiap foto ke-3 memiliki margin-right: 0 (menghilangkan margin di ujung) menggunakan :nth-child(3n)
  • Tombol navigasi dengan efek :hover dan :active
  • Form pencarian dengan efek :focus
  • Tambahkan kotak penjelasan yang menunjukkan semua pseudo-class yang digunakan

Selamat mencoba!

Artikel Sebelumnya: CSS Dasar #6 - Selektor Sibling (Adjacent & General Sibling Selector)
Artikel Selanjutnya: CSS Dasar #8 - Pseudo-element (before, after, first-line, first-letter, selection)

Lebih baru Lebih lama

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