The CSS Podcast - 015: Pseudo-classes
Misalnya, Anda memiliki formulir pendaftaran email, dan Anda ingin kolom formulir email memiliki batas merah jika berisi alamat email yang tidak valid.
Bagaimana Anda melakukannya?
Anda dapat menggunakan pseudo-class CSS :invalid
,
yang merupakan salah satu dari banyak pseudo-class yang disediakan browser.
Pseudo-class memungkinkan Anda menerapkan gaya berdasarkan perubahan status dan faktor eksternal. Artinya, desain Anda dapat bereaksi terhadap input pengguna seperti alamat email yang tidak valid. Hal ini dibahas dalam modul pemilih, dan modul ini akan membahasnya secara lebih mendetail.
Tidak seperti elemen semu, yang dapat Anda pelajari lebih lanjut di modul sebelumnya, class semu terhubung ke status tertentu yang mungkin dimiliki elemen, bukan menata gaya bagian elemen tersebut secara umum.
Status interaktif
Pseudo-class berikut berlaku karena interaksi pengguna dengan halaman Anda.
:hover
Jika pengguna memiliki perangkat penunjuk seperti mouse atau trackpad, dan mereka meletakkannya di atas elemen, Anda dapat mengaitkan status tersebut dengan :hover
untuk menerapkan gaya.
Cara ini berguna untuk memberi petunjuk bahwa suatu elemen dapat diajak berinteraksi.
:active
Status ini dipicu saat elemen berinteraksi secara aktif— seperti klik—sebelum klik dilepaskan. Jika perangkat penunjuk seperti mouse digunakan, status ini adalah saat klik dimulai dan belum dilepaskan.
:focus
, :focus-within
, dan :focus-visible
Jika elemen dapat menerima fokus—seperti <button>
—
Anda dapat bereaksi terhadap status tersebut dengan
pseudo-class :focus
.
Anda juga dapat bereaksi jika elemen turunan dari elemen Anda menerima fokus dengan
:focus-within
.
Elemen yang dapat difokuskan, seperti tombol, akan menampilkan ring fokus saat difokuskan—bahkan saat diklik. Dalam situasi seperti ini, developer akan menerapkan CSS berikut:
button:focus {
outline: none;
}
CSS ini menghapus ring fokus browser default saat elemen menerima fokus,
yang menimbulkan masalah aksesibilitas bagi pengguna yang menavigasi halaman web dengan keyboard.
Jika tidak ada gaya fokus, pengguna tidak akan dapat melacak lokasi fokus saat ini saat menggunakan tombol tab.
Dengan :focus-visible
, Anda dapat menampilkan gaya fokus saat elemen menerima fokus menggunakan keyboard, sekaligus menggunakan aturan outline: none
untuk mencegahnya saat perangkat penunjuk berinteraksi dengannya.
button:focus {
outline: none;
}
button:focus-visible {
outline: 1px solid black;
}
:target
Pseudo-class :target
memilih elemen yang memiliki id
yang cocok dengan fragmen URL.
Misalkan Anda memiliki HTML berikut:
<article id="content">
<!-- ... -->
</article>
Anda dapat melampirkan gaya ke elemen tersebut saat URL berisi #content
.
#content:target {
background: yellow;
}
Hal ini berguna untuk menyoroti area yang mungkin telah ditautkan secara khusus, seperti konten utama di situs, menggunakan link lompat.
Negara bagian bersejarah
:link
Pseudo-class :link
dapat diterapkan ke elemen <a>
mana pun yang memiliki nilai href
yang belum dikunjungi.
:visited
Anda dapat menata gaya link yang sudah dikunjungi oleh pengguna menggunakan
pseudo-class :visited
.
Ini adalah kondisi yang berlawanan dengan :link
, tetapi Anda memiliki lebih sedikit properti CSS untuk digunakan karena alasan keamanan.
Anda hanya dapat mengatur gaya color
, background-color
,
border-color
, outline-color
, dan warna SVG fill
dan stroke
.
Pentingnya urutan
Jika Anda menentukan gaya :visited
,
gaya tersebut dapat diganti oleh pseudo-class link dengan spesifisitas yang setidaknya sama.
Oleh karena itu, sebaiknya Anda menggunakan aturan LVHA untuk menata link dengan pseudo-class dalam urutan tertentu:
:link
, :visited
, :hover
, :active
.
a:link {}
a:visited {}
a:hover {}
a:active {}
Status formulir
Pseudo-class berikut dapat memilih elemen formulir, dalam berbagai status yang mungkin dimiliki elemen ini selama interaksi dengannya.
:disabled
dan :enabled
Jika elemen formulir, seperti <button>
dinonaktifkan oleh browser, Anda dapat mengaitkan status tersebut dengan pseudo-class :disabled
.
Pseudo-class :enabled
tersedia untuk status yang berlawanan,
meskipun elemen formulir juga :enabled
secara default,
sehingga Anda mungkin tidak perlu menggunakan pseudo-class ini.
:checked
dan :indeterminate
Pseudo-class :checked
tersedia saat elemen formulir pendukung, seperti kotak centang atau tombol pilihan, dalam status dicentang.
Status :checked
adalah status biner (benar atau salah),
tetapi kotak centang memiliki status di antara saat tidak dicentang atau dicentang.
Hal ini dikenal sebagai status
:indeterminate
.
Contoh status ini adalah saat Anda memiliki kontrol "pilih semua" yang mencentang semua kotak centang dalam grup. Jika pengguna kemudian menghapus centang pada salah satu kotak centang ini, kotak centang root tidak lagi merepresentasikan "semua" dicentang, sehingga harus dimasukkan ke dalam status tidak ditentukan.
Elemen <progress>
juga memiliki status tidak ditentukan yang dapat diberi gaya.
Kasus penggunaan umum adalah memberikan tampilan bergaris untuk menunjukkan bahwa tidak diketahui berapa banyak lagi yang diperlukan.
:placeholder-shown
Jika kolom formulir memiliki atribut placeholder
dan tidak memiliki nilai,
pseudo-class :placeholder-shown
dapat digunakan untuk melampirkan gaya ke status tersebut.
Segera setelah ada konten di kolom, baik memiliki placeholder
atau tidak, status ini tidak akan berlaku lagi.
Status validasi
Anda dapat merespons validasi formulir HTML dengan pseudo-class seperti
:valid
,
:invalid
dan
:in-range
.
Pseudo-class :valid
dan :invalid
berguna untuk konteks
seperti kolom email yang memiliki pattern
yang harus dicocokkan,
agar menjadi kolom yang valid.
Status nilai yang valid ini dapat ditampilkan kepada pengguna,
membantu mereka memahami bahwa mereka dapat beralih ke kolom berikutnya dengan aman.
Pseudo-class :in-range
tersedia jika input memiliki min
dan max
, seperti input numerik dan nilai berada dalam batas tersebut.
Dengan formulir HTML,
Anda dapat menentukan bahwa kolom wajib diisi dengan atribut required
.
Pseudo-class :required
akan tersedia untuk kolom wajib diisi.
Kolom yang tidak wajib diisi dapat dipilih dengan
pseudo-class :optional
.
Memilih elemen menurut indeks, urutan, dan kemunculannya
Ada sekelompok pseudo-class yang memilih item berdasarkan lokasinya dalam dokumen.
:first-child
dan :last-child
Jika ingin menemukan item pertama atau terakhir, Anda dapat menggunakan :first-child
dan :last-child
.
Pseudo-class ini akan menampilkan elemen pertama atau terakhir dalam grup elemen saudara.
:only-child
Anda juga dapat memilih elemen yang tidak memiliki elemen turunan,
dengan pseudo-class
:only-child
.
:first-of-type
dan :last-of-type
Anda dapat memilih
:first-of-type
dan
:last-of-type
yang pada awalnya,
tampak melakukan hal yang sama seperti :first-child
dan :last-child
, tetapi perhatikan HTML ini:
<div class="my-parent">
<p>A paragraph</p>
<div>A div</div>
<div>Another div</div>
</div>
Dan CSS ini:
.my-parent div:first-child {
color: red;
}
Tidak ada elemen yang berwarna merah karena elemen turunan pertama adalah paragraf, bukan div.
Pseudo-class :first-of-type
berguna dalam konteks ini.
.my-parent div:first-of-type {
color: red;
}
Meskipun <div>
pertama adalah turunan kedua,
elemen ini tetap merupakan elemen pertama dalam jenis di dalam elemen .my-parent
,
jadi dengan aturan ini, elemen tersebut akan berwarna merah.
:nth-child
dan :nth-of-type
Anda juga tidak terbatas pada turunan pertama dan terakhir serta jenisnya.
Pseudo-class :nth-child
dan
:nth-of-type
memungkinkan Anda menentukan elemen yang berada pada indeks tertentu.
Pengindeksan dalam pemilih CSS dimulai dari 1.
Pseudo-class :nth-last-child()
dan :nth-last-of-type()
dihitung dari akhir, bukan dari awal.
Anda juga dapat meneruskan lebih dari satu indeks ke dalam pseudo-class ini.
Jika ingin memilih semua elemen genap, Anda dapat menggunakan :nth-child(even)
.
Anda juga dapat membuat pemilih yang lebih kompleks yang menemukan item pada interval spasi reguler, menggunakan mikrosintaksis An+B.
li:nth-child(3n+3) {
background: yellow;
}
Pemilih ini memilih setiap item ketiga,
dimulai dari item 3.
n
dalam ekspresi ini adalah indeks,
yang dimulai dari nol, dan 3 (3n
) adalah jumlah indeks yang dikalikan.
Misalnya, Anda memiliki 7 item <li>
.
Item pertama yang dipilih adalah 3 karena 3n+3
diterjemahkan menjadi (3 * 0) + 3
.
Iterasi berikutnya akan memilih item 6 karena n
kini telah bertambah menjadi 1
,
jadi (3 * 1) + 3)
.
Ekspresi ini berfungsi untuk :nth-child
dan :nth-of-type
.
:nth-child()
dan :nth-last-child()
juga mendukung sintaksis "of S" yang memungkinkan Anda memfilter kecocokan dengan pemilih, mirip dengan :nth-of-type()
. li:nth-of-type(even)
setara dengan :nth-child(even of li)
. Meskipun :nth-of-type
hanya memungkinkan Anda memfilter berdasarkan jenis elemen (seperti li
atau p
), sintaksis "of S" memungkinkan Anda memfilter pada pemilih apa pun.
Jika memiliki tabel, Anda dapat menambahkan garis ke setiap baris. Meskipun Anda dapat menargetkan setiap baris lainnya dengantr:nth-child(even)
, hal ini tidak berfungsi jika Anda memfilter beberapa baris. Jika menerapkan pemfilteran dengan menerapkan atribut hidden
, Anda dapat menambahkan of :not([hidden])
ke pemilih untuk memfilter item tersembunyi terlebih dahulu sebelum memilih baris genap.
tr:nth-child(even of :not([hidden])){
background: lightgrey;
}
Anda dapat bereksperimen dengan pemilih semacam ini di penguji nth-child ini atau alat pemilih kuantitas ini.
:only-of-type
Terakhir, Anda dapat menemukan satu-satunya elemen dari jenis tertentu dalam grup elemen selevel dengan
:only-of-type
.
Hal ini berguna jika Anda ingin memilih daftar yang hanya memiliki satu item,
atau jika Anda ingin menemukan satu-satunya elemen tebal dalam paragraf.
Menemukan elemen kosong
Terkadang, mengidentifikasi elemen yang benar-benar kosong dapat berguna, dan ada juga pseudo-class untuk itu.
:empty
Jika suatu elemen tidak memiliki turunan, maka pseudo-class
:empty
berlaku untuk elemen tersebut.
Namun, elemen turunan bukan hanya elemen HTML atau node teks: elemen turunan juga dapat berupa ruang kosong,
yang dapat membingungkan saat Anda men-debug HTML berikut dan bertanya-tanya mengapa tidak berfungsi dengan :empty
:
<div>
</div>
Alasannya adalah karena ada beberapa spasi antara <div>
pembuka dan penutup,
sehingga :empty
tidak akan berfungsi.
Pseudo-class :empty
dapat berguna jika Anda memiliki sedikit kontrol atas HTML dan ingin menyembunyikan elemen kosong,
seperti editor konten WYSIWYG.
Di sini, editor telah menambahkan paragraf kosong yang tidak diperlukan.
<article class="post">
<p>Donec ullamcorper nulla non metus auctor fringilla.</p>
<p></p>
<p>Curabitur blandit tempus porttitor.</p>
</article>
Dengan :empty
, Anda dapat menemukan dan menyembunyikannya.
.post :empty {
display: none;
}
Menemukan dan mengecualikan beberapa elemen
Beberapa pseudo-class membantu Anda menulis CSS yang lebih ringkas.
:is()
Jika Anda ingin menemukan semua elemen turunan h2
, li
, dan img
dalam elemen .post
,
Anda mungkin berpikir untuk menulis daftar pemilih seperti ini:
.post h2,
.post li,
.post img {
…
}
Dengan class semu :is()
, Anda dapat menulis versi yang lebih ringkas:
.post :is(h2, li, img) {
/* ... */
}
Pseudokelas :is
tidak hanya lebih ringkas daripada daftar pemilih, tetapi juga lebih toleran.
Dalam sebagian besar kasus,
jika ada error atau pemilih yang tidak didukung dalam daftar pemilih,
seluruh daftar pemilih tidak akan berfungsi lagi.
Jika ada error pada pemilih yang diteruskan dalam class pseudo :is
,
pemilih yang tidak valid akan diabaikan, tetapi pemilih yang valid akan digunakan.
:not()
Anda juga dapat mengecualikan item dengan
:not()
pseudo-class.
Misalnya, Anda dapat menggunakannya untuk menata semua link yang tidak memiliki atribut class
.
a:not([class]) {
color: blue;
}
Pseudokelas :not
juga dapat membantu Anda meningkatkan aksesibilitas.
Misalnya, <img>
harus memiliki alt
, meskipun berupa nilai kosong,
sehingga Anda dapat menulis aturan CSS yang menambahkan garis merah tebal ke gambar yang tidak valid:
img:not([alt]) {
outline: 10px red;
}
:has()
Bagaimana jika Anda ingin menata elemen berdasarkan apa yang ada di dalamnya? Anda dapat menggunakan class semu :has()
untuk melakukannya. Misalnya, Anda mungkin ingin menerapkan gaya ke tombol yang menyertakan ikon.
button:has(svg) {
/* ... */
}
Dalam konfigurasi paling dasarnya, seperti pada contoh sebelumnya, Anda dapat menganggap :has()
sebagai pemilih induk. Anda juga dapat menggunakan pemilih induk yang cocok yang digabungkan dengan pemilih lain untuk menargetkan elemen lain.
form:has(input:valid) label {
font-weight: bold;
}
form:has(input:valid) label::after {
content: "✅";
}
Dalam contoh ini, kita menerapkan gaya ke elemen label dan elemen semu label::after
saat input formulir memiliki class semu valid
.
Pseudo-class :has()
tidak dapat disarangkan di dalam :has()
lain, tetapi dapat digabungkan dengan pseudo-class lain.
:is(h1, h2, h3):has(a) {
/* ... */
}
Daftar pemilih tidak dapat ditoleransi, jadi jika ada pemilih yang tidak valid dalam daftar, semua aturan gaya akan diabaikan.
.my-element:has(img, ::before) {
/* any styles here will be discarded since pseudo elements can't be included in the :has() selector list */
}
Periksa pemahaman Anda
Uji pengetahuan Anda tentang pseudo-class
Pseudo-class bertindak seolah-olah class telah diterapkan secara dinamis ke elemen, sementara pseudo-element bertindak pada elemen itu sendiri.
:
tunggal atau ganda sebagai karakter pembeda utama dalam pemilihManakah dari berikut ini yang merupakan pseudo-class functional?
:is()
:target
()
setelahnya, untuk menunjukkan bahwa pseudo-class tersebut menerima parameter.:empty
()
setelahnya, untuk menunjukkan bahwa pseudo-class tersebut menerima parameter.:not()
Pseudo-class mana saja berikut ini yang disebabkan oleh interaksi pengguna?
:hover
:press
:squeeze
:target
:focus-within
Manakah dari berikut ini yang merupakan class semu status <form>
?
:enabled
:fresh
:indeterminate
:checked
:in-range
:loading
:valid