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.
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:
- Tambahkan
transitionuntuk 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:
:focusmembantu pengguna yang hanya menggunakan keyboard (tanpa mouse)- Jangan pernah menghapus
outlinetanpa memberikan alternatif visual - Gunakan
outlineataubox-shadowuntuk 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:
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>
Klik link di atas, lalu kembali ke halaman ini. Warna link akan berubah menjadi ungu.
- Karena alasan privasi, hanya properti tertentu yang bisa diubah (color, background-color, border-color)
- Properti seperti
display,width,heighttidak 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) |
: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 | Status | |
|---|---|---|---|
| 1 | Andi Saputra | andi@email.com | Aktif |
| 2 | Budi Santoso | budi@email.com | Aktif |
| 3 | Citra Lestari | citra@email.com | Nonaktif |
| 4 | Dewi Anggraini | dewi@email.com | Aktif |
| 5 | Eko Prasetyo | eko@email.com | Aktif |
Hasil visual halaman demo:
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-class →
hover(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.
- 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
- Buat file HTML dengan beberapa tombol, terapkan efek :hover (ubah warna, scale)
- Buat form input dengan :focus effect (border biru, shadow)
- Buat list dengan 5 item, styling item pertama dan terakhir berbeda
- Buat tabel dengan zebra striping menggunakan :nth-child(even)
- 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)
- 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)
