Satu elemen dapat menerima beberapa deklarasi berbeda untuk properti yang sama, sedangkan tampilan akhir hanya boleh memuat satu nilai. Mekanisme pemilihan nilai pemenang itu bernama cascade, dan namanya menjadi asal sebutan CSS, yaitu Cascading Style Sheets. Topik ini menjelaskan asal istilah tersebut, asal gaya yang bersaing, urutan penyelesaian konflik, serta kedudukan style inline dan !important di dalamnya.
Asal istilah cascade#
Dokumen web jarang menerima gaya dari satu tempat saja. Browser membawa gaya bawaan untuk setiap elemen, situs memuat satu atau beberapa stylesheet penulis, dan pengguna dapat menetapkan preferensi tertentu, misalnya ukuran huruf minimal. Seluruh deklarasi dari sumber-sumber itu masuk ke satu proses penilaian, dan untuk setiap properti pada setiap elemen hanya ada satu nilai akhir.
Istilah cascade menggambarkan aliran bertingkat tersebut. Deklarasi dari berbagai asal bertumpuk, lalu diurutkan menurut kekuatan asalnya, sehingga deklarasi yang lebih kuat menggantikan yang lebih lemah lapis demi lapis. Kata cascading pada Cascading Style Sheets menunjuk mekanisme yang sama, yaitu banyak lapisan gaya yang menyatu menjadi satu hasil tampilan. Tanpa mekanisme ini, setiap tambahan berkas gaya akan memunculkan konflik yang tidak pernah selesai.
Penyelesaian konflik diperiksa berjenjang. Browser memilah deklarasi menurut asal dan kepentingannya, kemudian menurut bobot selector, lalu menurut urutan kemunculannya. Jenjang berikutnya hanya digunakan apabila jenjang sebelumnya berakhir seri. Urutan pemeriksaan yang tetap inilah yang membuat hasil akhir dapat diprediksi.
Asal gaya dan urutannya#
Cascade mengenal tiga asal gaya, yaitu gaya bawaan browser (user-agent), gaya penulis (author), dan gaya pembaca (user). Gaya bawaan berasal dari browser itu sendiri, misalnya judul yang tampil besar dan tautan yang bergaris bawah. Gaya penulis berasal dari stylesheet yang ditulis pengembang (developer) situs, sedangkan gaya pembaca berasal dari preferensi pengguna yang ditetapkan pada pengaturan browser.
Untuk deklarasi normal, urutan kekuatannya tetap. Gaya penulis mengalahkan gaya pembaca, dan gaya pembaca mengalahkan gaya bawaan browser. Karena itu, satu deklarasi color pada stylesheet penulis langsung menggantikan warna bawaan browser tanpa usaha apa pun. Dalam praktik sehari-hari, gaya pembaca jarang hadir karena browser modern menerapkan preferensi pengguna melalui mekanisme tersendiri, sehingga konflik yang ditemui hampir selalu antara gaya penulis dan gaya bawaan browser.
Hubungan ketiga asal ini menjelaskan mengapa halaman tanpa CSS tetap terbaca. Judul tetap besar, daftar tetap berbutir, dan teks tetap berjarak, karena gaya bawaan browser bekerja sebagai lapisan dasarnya. Stylesheet penulis tidak memulai dari kertas kosong, melainkan menggantikan sebagian keputusan dari lapisan yang sudah ada.
Urutan sumber ketika bobot sama#
Apabila dua deklarasi berasal dari asal yang sama dan memiliki bobot selector yang sama, deklarasi yang muncul lebih akhir menjadi pemenang. Aturan ini berlaku di dalam satu berkas CSS, antara beberapa elemen style, maupun antara beberapa elemen link yang diurutkan pada head. Karena itu, urutan pelekatan stylesheet merupakan bagian dari rancangan, bukan kebetulan.
Demo berikut memuat dua kelompok konflik. Kelompok pertama menggunakan selector yang sama dua kali, sehingga aturan terakhir yang terlihat. Kelompok kedua menggunakan dua selector dengan bobot berbeda, dan pemenangnya ditentukan bobot, bukan urutan. Amati warna teks pada kedua paragraf, lalu bandingkan dengan urutan aturan pada kode sumbernya.
Kode sumber demo
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Demo cascade</title>
<style>
.kotak {
border: 1px solid #cbd5e1;
border-radius: 6px;
padding: 10px 14px;
margin-bottom: 12px;
}
/* Konflik dengan selector sama: aturan yang lebih akhir menang */
.teks {
color: #b91c1c;
}
.teks {
color: #1d4ed8;
}
/* Konflik dengan specificity berbeda: bobot menentukan, bukan urutan */
p.sorot {
color: #15803d;
}
.sorot {
color: #7c3aed;
}
</style>
</head>
<body>
<p class="kotak teks">
Paragraf ini terkena dua aturan <code>.teks</code> yang sama bobotnya.
Warna yang tampil adalah biru dari aturan kedua.
</p>
<p class="kotak sorot">
Paragraf ini terkena aturan <code>p.sorot</code> dan aturan <code>.sorot</code>.
Warna hijau menang meskipun ditulis lebih dulu.
</p>
</body>
</html>Pada paragraf pertama, kedua aturan .teks sama bobotnya, sehingga warna biru dari aturan kedua yang tampil. Pada paragraf kedua, selector p.sorot berbobot lebih tinggi daripada .sorot, sehingga warna hijau menang meskipun aturannya ditulis lebih dulu. Apabila urutan kedua aturan .teks ditukar, tampilan ikut berubah, sedangkan pertukaran urutan aturan pada paragraf kedua tidak mengubah apa pun.
Style inline dan !important#
Deklarasi pada atribut style menempati tingkat tersendiri di dalam gaya penulis. Deklarasi semacam itu menang atas deklarasi stylesheet biasa tanpa memandang bobot selector, karena gaya inline dinilai lebih spesifik daripada aturan apa pun yang ditulis pada berkas. Deklarasi inline tetap dapat digantikan dari stylesheet dengan !important, yaitu penanda pada akhir sebuah deklarasi. Cara itu bekerja asalkan deklarasi inline-nya sendiri tidak ikut diberi !important.
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- style.css memuat: p { color: #1e40af; } -->
<p style="color: #b91c1c;">Warna merah yang diterapkan</p>
</body>Kekuatan semacam itu menjadikan !important mudah disalahgunakan. Satu !important yang digunakan untuk menutup konflik menuntut !important kedua pada aturan penggantinya. Pengganti itu kemudian menuntut !important ketiga, dan pertikaian tidak pernah berakhir. Gunakan penanda ini hanya pada situasi terbatas, misalnya menimpa gaya pustaka pihak ketiga yang tidak dapat disunting. Konflik lainnya selesaikan dengan memperbaiki bobot selector dan urutan sumber.
Kesalahan umum#
Kesalahan pertama adalah mengharapkan urutan menang atas bobot. Urutan hanya menjadi penentu apabila bobot kedua deklarasi sama, sehingga memindahkan aturan ke bagian akhir berkas tidak menolong ketika selector lawannya lebih kuat. Perbaikannya adalah menyesuaikan bobot selector, bukan memindahkan letak aturan.
Kesalahan kedua adalah menumpuk gaya inline untuk memaksa hasil. Setiap deklarasi inline yang ditambahkan mengurangi kemampuan mengubah gaya dari stylesheet, dan penumpukan ini biasanya dimulai dari satu percobaan yang tidak pernah dibersihkan. Deklarasi tersebut dipindahkan ke stylesheet, lalu elemennya diberi atribut class agar dapat diatur bersama elemen sejenis.
Kesalahan ketiga adalah menyalahkan error ketika gaya tidak berlaku. Sebagian besar kasus bukan error, melainkan kekalahan dalam cascade. Panel Styles pada DevTools menampilkan deklarasi yang kalah dengan coretan, sehingga pemenang dan penyebabnya dapat dilihat tanpa menebak.
Ringkasan#
- Cascade adalah mekanisme pemilihan satu nilai pemenang ketika beberapa deklarasi bersaing pada properti dan elemen yang sama.
- Untuk deklarasi normal, urutan asal gaya dari lemah ke kuat adalah gaya bawaan browser, gaya pembaca, lalu gaya penulis.
- Apabila bobot selector sama, deklarasi yang muncul lebih akhir menang, dan gaya inline menang atas stylesheet biasa.
- Penanda
!importantmengalahkan deklarasi normal apa pun dan sebaiknya digunakan seminimal mungkin.
Referensi#
- Introduction to the CSS cascade — MDN — Penjelasan resmi asal istilah cascade, asal gaya, dan urutan penyelesaian konflik.
- important — MDN
— Dokumentasi resmi penanda
!importantbeserta peringatan penggunaannya. - CSS Cascading and Inheritance Level 5 — W3C CSS Working Group — Spesifikasi resmi yang menetapkan urutan asal gaya dan seluruh aturan cascade.