Sampai sini, setiap selector yang kamu tulis selalu mengincar elemen yang nyata — sebuah <p>, sebuah <div>, pokoknya sesuatu yang memang ada di HTML kamu. Nah, pseudo-element mendobrak aturan itu dengan cara yang berguna: dia membiarkan kamu menata sebagian dari elemen, bahkan membuat konten visual baru, tanpa menambah satu tag pun di markup.
Mau menambah ikon hiasan sebelum sebuah judul? Tanda kutip khusus di sekitar blockquote? Menata huruf pertama paragraf biar terlihat seperti buku jadul? Menempelkan tanda bintang “wajib diisi” setelah label form? Semua itu pekerjaan pseudo-element. Dia salah satu fitur yang, begitu kamu paham cara kerjanya, bakal kamu pakai terus-menerus. Yuk kita bedah satu per satu.
Apa itu pseudo-element sebenarnya
Pseudo-element mengincar bagian tertentu dari sebuah elemen, bukan keseluruhan elemennya. Browser memperlakukan bagian itu seolah-olah dia elemen kecil tersendiri yang bisa kamu tata — padahal sebenarnya bagian itu tidak ada di HTML kamu.
Cara menulisnya pakai titik dua ganda (::), dan inilah yang secara visual membedakannya dari pseudo-class (yang cuma pakai satu titik dua, seperti :hover):
p::first-line {
font-weight: bold;
}
Aturan itu menebalkan baris pertama saja dari setiap paragraf — sepenggal teks yang tidak punya tag sendiri. Tidak ada cara lain untuk memilihnya.
Titik dua ganda vs satu titik dua
Pseudo-element pakai dua titik dua (::before), sementara pseudo-class cukup satu (:hover). Titik dua ganda diperkenalkan di CSS3 justru untuk memisahkan keduanya. Kamu mungkin masih akan menjumpai kode lama yang menulis pseudo-element dengan satu titik dua (:before) — browser memang masih menerimanya demi kompatibilitas — tapi di setiap kode baru yang kamu tulis, pakailah titik dua ganda. Maksudnya jadi jelas: “ini mengincar bagian elemen yang dibuatkan otomatis.”
Kalau kamu masih perlu pemanasan soal cara kerja selector secara umum, ada baiknya mampir dulu ke selector CSS — pseudo-element berdiri langsung di atas fondasi itu.
Dua bintang utama: ::before dan ::after
Sejauh ini, pseudo-element yang paling sering dipakai adalah ::before dan ::after. Keduanya membiarkan kamu menyisipkan konten buatan sebelum atau sesudah konten asli sebuah elemen. Bayangkan keduanya sebagai dua mini-elemen tak terlihat yang menempel di dalam elemenmu, satu di paling awal dan satu di paling akhir.
Tapi ada satu jebakan yang bikin banyak orang tersandung di awal: supaya ::before dan ::after bisa muncul sama sekali, kamu wajib memberinya property content. Tanpa itu, tidak ada apa pun yang tampil.
.note::before {
content: "💡 ";
}
<p class="note">Sering-sering simpan pekerjaanmu.</p>
Hasilnya ditampilkan sebagai 💡 Sering-sering simpan pekerjaanmu. — bohlam itu tidak pernah ada di HTML; CSS yang memunculkannya. Nilai content bisa berupa teks biasa, emoji, string kosong, atau bahkan tanpa teks sama sekali alias cuma bentuk (kita bahas sebentar lagi).
Tanpa content, tidak ada pseudo-element
Inilah kesalahan pemula nomor satu. Kalau kamu menulis content: ""; kamu mendapat kotak yang kosong tapi tetap ada, yang bisa kamu beri ukuran dan gaya. Tapi kalau kamu sama sekali tidak menulis content, pseudo-element-nya tidak dibuatkan sama sekali — background, border, dan width kamu jadi sia-sia karena tidak ada kotak untuk ditempeli. Jadi selalu sertakan content, walaupun cuma content: "";.
Konten buatan itu konten “sungguhan”
Apa pun yang kamu taruh di content muncul di halaman layaknya teks biasa. Artinya, content: "→" benar-benar menaruh karakter panah yang terlihat, di sebagian kasus bisa diseleksi, dan bisa ditata dengan color, font-size, dan property lainnya.
.external::after {
content: " ↗";
color: #00B8E6;
}
<a href="https://example.com" class="external">Kunjungi ACY Partner Indonesia</a>
Sekarang setiap tautan dengan class external mendapat panah kecil berwarna cyan setelah teksnya, sebagai isyarat bahwa tautan itu membuka halaman lain — sentuhan UI yang rapi tanpa markup tambahan sedikit pun.
Membuat bentuk hiasan dengan content kosong
Di sinilah ::before dan ::after jadi benar-benar bertenaga. Atur content: ""; (kosong), lalu beri pseudo-element itu width, height, background, atau border — jadilah sebuah hiasan murni: garis pemisah, titik, garis bawah khusus, atau badge kecil.
.title::after {
content: "";
display: block;
width: 60px;
height: 4px;
background: #00B8E6;
margin-top: 8px;
}
<h2 class="title">Layanan Kami</h2>
Itu menggambar batang aksen pendek tepat di bawah judul. Pseudo-element-nya tidak memuat teks sama sekali — seluruh tugasnya cuma jadi kotak yang ditata. Pola ini muncul di mana-mana: garis bawah section, pita di kartu, tanda centang, bullet kustom, sampai ekor balon percakapan.
Pseudo-element bawaannya inline
::before atau ::after yang baru dibuat berperilaku seperti elemen inline, jadi width dan height diabaikan sampai kamu mengubahnya. Tambahkan display: block (atau inline-block) supaya dia mau menuruti ukuran. Itulah sebabnya contoh di atas memasang display: block dulu sebelum memberi width dan height. Kalau kotak hiasanmu “nggak mau berubah ukuran,” hampir selalu inilah penyebabnya. Akan membantu juga kalau kamu paham bagaimana property display mengubah perilaku kotak sebuah elemen.
Contoh praktis: bullet daftar kustom
Bullet daftar bawaan itu terbatas dan susah ditata. Dengan ::before, kamu bisa menggantinya dengan apa pun — panah, tanda centang, atau titik berwarna dengan ukuran persis seperti yang kamu mau:
.checklist {
list-style: none; /* hapus bullet bawaan */
padding-left: 0;
}
.checklist li::before {
content: "✓ ";
color: #16a34a;
font-weight: bold;
}
<ul class="checklist">
<li>Ramah perangkat mobile</li>
<li>Cepat dimuat</li>
<li>Dioptimasi untuk SEO</li>
</ul>
Kamu copot bullet bawaan dengan list-style: none, lalu menambahkan tanda centang hijau buatanmu sendiri lewat ::before. Sekarang kamu mengendalikan persis simbol, warna, dan jaraknya — sesuatu yang tidak pernah diizinkan oleh bullet bawaan.
Pseudo-element untuk tipografi
Ada beberapa pseudo-element yang khusus mengincar teks. Yang ini tidak butuh property content — teks yang ditatanya memang sudah ada.
::first-letter dan ::first-line
::first-letter menata huruf pembuka saja dari sebuah blok — pas banget untuk “drop cap” klasik yang sering kamu lihat di awal artikel majalah. Sementara ::first-line menata seluruh baris pertama, sepanjang apa pun baris itu kebetulan jadinya.
.article p::first-letter {
font-size: 3em;
font-weight: bold;
float: left;
line-height: 1;
margin-right: 6px;
color: #00B8E6;
}
Huruf pertama setiap paragraf membesar jadi drop cap yang mengambang, sementara teks selebihnya membungkus rapi di sekelilingnya. Karena ::first-line mengalir bersama teks, batasnya bergeser saat jendela diubah ukuran — browser menghitung ulang mana “baris pertama” secara langsung.
::selection
::selection menata bagian halaman yang sedang disorot pengguna dengan kursor. Ini detail kecil yang membuat sebuah situs terasa rapi dan sesuai identitas merek:
::selection {
background: #00B8E6;
color: #ffffff;
}
Sekarang setiap kali seseorang menyeret untuk menyorot teks, sorotannya memakai cyan khas merekmu, bukan warna bawaan browser. Cuma sedikit property yang berfungsi di sini (color, background, text-decoration, dan beberapa lainnya), tapi itu sudah lebih dari cukup untuk sorotan yang bersih.
::placeholder
::placeholder menata teks petunjuk samar di dalam <input> atau <textarea> yang masih kosong. Secara bawaan warnanya abu-abu datar; pseudo-element ini membiarkan kamu menyelaraskannya dengan desainmu:
input::placeholder {
color: #94a3b8;
font-style: italic;
}
<input type="email" placeholder="kamu@example.com">
Sentuhan kecil memang, tapi gaya placeholder yang konsisten termasuk salah satu hal yang diam-diam membedakan antarmuka yang digarap rapi dari yang asal jadi.
Memosisikan pseudo-element dengan presisi
Untuk hiasan yang lebih canggih — tooltip, badge, pita, bendera di sudut — kamu sering ingin menaruh pseudo-element di titik yang persis. Resep standarnya adalah membuat induknya position: relative dan pseudo-element-nya position: absolute:
.badge {
position: relative;
}
.badge::after {
content: "BARU";
position: absolute;
top: -10px;
right: -10px;
background: #ef4444;
color: #fff;
font-size: 12px;
padding: 2px 6px;
border-radius: 4px;
}
<button class="badge">Harga</button>
Itu menyematkan label merah kecil “BARU” ke sudut kanan atas tombol, mengambang pas di luar tepinya. position: relative pada induk memberi pseudo-element yang berposisi absolute sesuatu untuk dijadikan jangkar. Kalau urusan posisi masih terasa goyah, penyegaran singkat soal positioning CSS bakal membuat pola ini jauh lebih jelas.
Beberapa jebakan yang perlu kamu tahu
Ada segelintir aturan yang akan menghemat waktumu saat debugging:
- Mereka cuma bekerja pada elemen yang punya konten. Kamu tidak bisa menambahkan
::before/::afterke elemen “kosong” seperti<img>,<input>,<br>, atau<hr>. Elemen-elemen ini tidak punya area konten untuk ditempati pseudo-element, jadi pseudo-element-nya simpel saja: tidak akan muncul. - Konten buatan tidak bisa diseleksi seperti teks biasa di banyak browser, dan pembaca layar (screen reader) belum tentu membacakannya. Jadi jangan menaruh informasi penting — teks yang benar-benar perlu dibaca pengguna — di dalam
content. Pakai dia untuk hiasan saja. - Tiap elemen cuma bisa punya satu
::beforedan satu::after, bukan beberapa sekaligus. Dua hiasan adalah batas maksimal per elemen; kalau butuh lebih, kamu harus menambah elemen tambahan. contentbisa menarik nilai sebuah atribut memakaiattr(), yang sebetulnya cukup berguna:
a::after {
content: " (" attr(href) ")";
color: #64748b;
}
Itu menambahkan URL setiap tautan di dalam tanda kurung tepat setelah teks tautannya — berguna untuk stylesheet cetak, di mana pembaca tidak bisa mengeklik.
Jangan menyembunyikan konten penting di pseudo-element
Karena konten buatan bisa dilewati oleh teknologi bantu dan bukan bagian dari dokumen yang sebenarnya, jangan pernah memakai ::before/::after untuk konten yang wajib terbaca — label, harga, pesan error, atau teks tombol. Pakai keduanya hanya untuk hiasan dan sentuhan visual. Kalau informasinya penting, taruh di HTML kamu, tempat semua orang — termasuk pembaca layar dan mesin pencari — bisa menjangkaunya.
Penutup
Pseudo-element membiarkan kamu menata bahkan menciptakan bagian elemen yang sebenarnya bukan tag nyata — cara yang bersih untuk menambah hiasan tanpa membuat HTML-mu jadi berantakan. Berikut intinya untuk kamu bawa:
- Pseudo-element pakai titik dua ganda (
::before), berbeda dari satu titik dua milik pseudo-class (:hover). ::beforedan::aftermenyisipkan konten buatan dan selalu butuh propertycontent— bahkancontent: ""sekalipun untuk kotak hiasan murni.- Pasang
display: blockpada::before/::aftersupayawidthdanheightberfungsi untuk bentuk seperti garis bawah dan pemisah. ::first-letter,::first-line,::selection, dan::placeholdermenata bagian-bagian teks tanpa perlucontent.- Padukan
position: relativepada induk denganposition: absolutepada pseudo-element untuk menaruh badge dan pita dengan presisi. - Jaga konten buatan tetap bersifat hiasan — jangan pernah menyembunyikan informasi penting yang wajib terbaca di dalamnya.
Kuasai ::before dan ::after, dan kamu akan menemukan puluhan tempat di mana keduanya menyederhanakan markup-mu. Pseudo-element ini berpasangan sangat baik dengan gaya-gaya yang sudah kamu pelajari sejauh ini — dan begitu kamu mulai memadukannya dengan transition dan transform, kamu sudah punya semua yang dibutuhkan untuk membangun detail UI yang halus dan beranimasi hanya dari CSS saja.