Konflik specificity adalah penyakit yang tumbuh perlahan: seseorang menulis selector lebih kuat untuk memenangkan satu kasus, orang berikutnya membalas dengan selector yang lebih kuat lagi, dan begitu pula seterusnya hingga stylesheet penuh rantai class dan !important yang tidak bisa dibongkar. Formula specificity dan urutan cascade telah kita bedah pada Chapter Specificity dan Cascade Layers ; chapter ini bergerak di tingkat arsitektur — keputusan apa yang kita tetapkan sejak awal agar konflik itu tidak sempat terjadi. Empat stratejinya: selector satu class, pemisahan prioritas dengan @layer, disiplin tanpa !important, dan urutan import yang terkunci.

Satu Class, Satu Tingkat #

Strategi paling efektif adalah menjaga seluruh selector komponen pada tingkat yang sama — satu class, specificity 0,1,0. Rantai seperti .sidebar .kartu__judul atau selector ber-ID seperti #hero .tombol memenangkan konflik hari ini, tetapi menjadi penghalang besok: satu-satunya cara menimpanya adalah selector yang lebih kuat, dan lomba lari itu tidak berujung:

css
/* Berbahaya: specificity 0,2,0 menutup pintu penimpaan wajar */
#hero .tombol { background-color: rgb(2, 132, 199); }

/* Sehat: 0,1,0 — semua pihak setara, urutan file yang memutuskan */
.tombol-utama { background-color: rgb(2, 132, 199); }

Bila butuh konteks, masukkan konteks ke dalam nama (.tombol-utama) atau gunakan modifier, bukan ke dalam selector. Fungsi :where() membantu bila kita terpaksa menulis selector kompleks: specificity seluruh argumennya dihitung nol, sehingga aturan tetap mudah ditimpa.

Memisahkan Prioritas dengan @layer #

Urutan file menyelesaikan sebagian konflik, tetapi ada kebutuhan yang lebih tinggi: memastikan kategori gaya selalu berurutan — utilities menang atas components, components menang atas base — tanpa memikirkan file mana yang diimpor belakangan. @layer (Baseline sejak 2022) menyediakannya: prioritas ditentukan urutan deklarasi layer, terlepas dari urutan penulisan aturan di dalamnya:

@layer base, components, utilities;

@layer components {
  .tombol {
    background-color: rgb(2, 132, 199);
    color: rgb(255, 255, 255);
    padding: 10px 16px;
    border-radius: 8px;
    font-size: 14px;
  }
}
@layer utilities {
  .bg-putih  { background-color: rgb(255, 255, 255); }
  .teks-gelap { color: rgb(15, 23, 42); }
  .mt-4      { margin-top: 16px; }
}

Pernyataan @layer base, components, utilities; di baris pertama mengunci urutan prioritas untuk seluruh stylesheet: bila .bg-putih dan .tombol sama-sama menunjuk elemen dengan specificity 0,1,0, utilities menang — bukan karena urutan kebetulan, melainkan karena kontrak layer. Kerangka lengkapnya dengan reset dan gaya unlayered kita rinci pada Chapter Cascade Layers di section modern CSS.

Hasil di Browser:

text
Tombol bawaan tampil biru rgb(2, 132, 199) dengan teks putih.
Tombol + .bg-putih tampil putih: utility layer menang atas
components layer pada specificity yang sama, tanpa !important.
Tombol + .teks-gelap berwarna gelap rgb(15, 23, 42).
Panel + .mt-4 memiliki margin-top 16px, mengalahkan margin 8px
milik komponen panel.

Mari kita telaah hasilnya:

  1. .tombol bawaan: hanya layer components yang menyetel warna, sehingga biru murni diterapkan.
  2. .tombol.bg-putih: dua class, specificity tetap per aturan 0,1,0; pemenang diputuskan oleh urutan layer (utilities paling belakangan), bukan oleh kekuatan selector.
  3. .panel.mt-4: margin komponen 8px kalah atas utilitas 16px dengan pola yang persis sama — utilitas menjadi “escape hatch” yang terprediksi.

Urutan Import Tetap Disiplin #

Layer mengatur prioritas antar-kategori, tetapi di dalam satu layer urutan file tetap berlaku seperti pada Chapter Mengorganisasi File CSS . Jadi kita menjalankan keduanya: deklarasi @layer di paling atas titik masuk utama, lalu import file dalam urutan yang tetap — dan keduanya tidak boleh diubah tanpa review.

Dengan empat strategi ini, pemenang setiap konflik dapat dibaca dari struktur stylesheet, bukan ditebak dari kebiasaan penulis sebelumnya. Bab penutup section ini merangkum semuanya menjadi kebiasaan perawatan jangka panjang.

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

contoh-layer.css

Unduh berkas
css
@layer base, components, utilities;

@layer components {
  .tombol {
    background-color: rgb(2, 132, 199);
    color: rgb(255, 255, 255);
    padding: 10px 16px;
    border-radius: 8px;
    font-size: 14px;
  }
  .panel {
    margin-top: 8px;
    background-color: rgb(255, 255, 255);
    border: 1px solid rgb(226, 232, 240);
    border-radius: 12px;
    padding: 16px;
  }
}
@layer utilities {
  .bg-putih   { background-color: rgb(255, 255, 255); }
  .teks-gelap { color: rgb(15, 23, 42); }
  .mt-4       { margin-top: 16px; }
}