Tutorial CSS / Menata CSS dengan Nilai Bersama, Nesting, dan Cascade Layers

CSS yang dapat dipelihara memisahkan nilai bersama, gaya dasar, komponen, dan penyesuaian bersyarat sesuai peran mereka. Nesting bawaan browser menempatkan selektor terkait di bawah aturan induknya, sementara lapisan cascade secara eksplisit mengurutkan grup aturan dan memperkenalkan aturan prioritas mereka sendiri.

Kurangi duplikasi dan tetapkan tanggung jawab file

Pertama, cari duplikat dengan warna dan jarak yang sama, selector yang tidak digunakan lagi, dan aturan tombol yang hampir identik. Nilai dengan peran yang sama dikelompokkan ke dalam variabel, dan tombol yang berbeda membagi aturan umum dan perbedaan yang diperlukan. Mungkin lebih baik mempertahankan dua komponen independen daripada membuat kondisi kompleks untuk menghilangkan semua duplikasi. Saat mengelompokkan nilai umum, periksa ruang lingkup dan kondisi pewarisan variabel di CSS Variabel: var(), Ruang Lingkup, Pewarisan, dan Cadangan.

/* Before cleanup: Same value repeated in multiple places */
.lesson-button { padding: .65rem 1rem; color: #166b92; }
.notice-button { padding: .65rem 1rem; color: #166b92; }

/* After organizing: sharing common shapes and roles */
.button { padding: .65rem 1rem; color: var(--accent); }
.button.text-alert { color: #9d2632; }

Perbandingan di atas adalah kode parsial yang menjelaskan arah pembersihan. Kelas tombol umum juga harus dilampirkan ke HTML yang sebenarnya, dan jika Anda hanya mengganti nama CSS dan membiarkan HTML seperti semula, tampilannya mungkin hilang. Seluruh latihan di bawah ini menjalankan konfigurasi ini yang dibagi menjadi file dan lapisan.

file tanggung jawab Penilaian saat merevisi
tokens.css Warna dan jarak umum Apakah ini nilai bersamakan oleh beberapa komponen?
base.css Font, margin default, tampilan fokus Apakah ini perilaku default untuk seluruh dokumen?
layout.css Area konten dan tata letak Apakah ini hubungan posisi dari komponen-komponen?
components.css Bentuk dan status kartu serta tombol Apakah ini terkait dengan satu komponen?
utilities.css Kelas bantu kecil dan eksplisit Apakah ini pengecualian yang hanya akan berlaku di beberapa tempat?

Untuk dokumen kecil, satu file dengan bagian-bagian yang dipisahkan komentar dapat mencukupi. Pertimbangkan untuk memisahkan file ketika banyak orang mengubah komponen yang berbeda atau ketika ruang lingkup penggunaan ulang meningkat. Nama file adalah pemisah untuk navigasi, dan hanya membagi file tidak menghilangkan konflik selektor. Jalur koneksi HTML dan kaskade juga harus dikelola.

Bedakan antara induk dan elemen turunan dalam penulisan bersarang

Nesting CSS bawaan diinterpretasikan langsung oleh browser. Ini berbeda dengan cara preprocessor seperti Sass menghasilkan CSS berbeda selama fase build. Kode di bawah menempatkan judul dari .card dekat dengan status dari kartu itu sendiri.

.card {
  & h2 { color: var(--accent); }
  &:hover { border-color: var(--accent); }
}

& h2 mewakili h2 di dalam kartu, dan &:hover mewakili efek hover dari kartu itu sendiri. Jika Anda menyisipkan spasi seperti & :hover, hasilnya akan berbeda karena memilih elemen turunan yang sedang di-hover. Juga bedakan antara &.warning, yang memilih kelas tambahan dari elemen yang sama, dan & .warning, yang memilih elemen turunan.

/* The simple overlap above is expanded */
.card h2 { color: var(--accent); }
.card:hover { border-color: var(--accent); }

Dengan selector induk tunggal ini, nesting dapat dibandingkan langsung dengan aturan yang diperluas. Daftar induk yang dipisahkan dengan koma bisa membuat spesifisitas selector bersarang bergantung pada selector yang paling spesifik dalam daftar itu. Oleh karena itu, nesting kompleks bukanlah sekadar penggabungan string. Hindari kedalaman yang tidak perlu yang mengikat CSS ke hierarki HTML yang kaku. Untuk detail lebih lanjut, lihat panduan penggunaan nesting MDN, penjelasan nesting dan prioritas MDN: nesting dan spesifisitas.

Periksa dukungan nesting di browser yang perlu Anda dukung, dan jika Anda membutuhkan lingkungan yang tidak mendukungnya, pilih CSS yang diperluas seperti di atas atau alat build yang sesuai. Hanya karena Anda menggunakan sintaks baru, jangan menganggapnya berlaku untuk semua pengunjung Anda.

Bandingkan lapisan cascade sebelum spesifisitas

Untuk deklarasi reguler dengan gaya penulis yang sama, deklarasi di luar lapisan memiliki prioritas dibandingkan dengan deklarasi di dalam lapisan. Di dalam lapisan, lapisan yang berada lebih akhir dalam urutan terdaftar memiliki prioritas dibandingkan lapisan sebelumnya dalam urutan yang telah ditentukan. Jadi aturan kelas di lapisan belakang dapat mengalahkan aturan ID di lapisan depan. Jika kondisi perbandingan lain seperti lapisan yang sama dan kepentingan sama, kondisi seperti Pewarisan CSS, Spesifisitas, dan Kaskade , kedekatan lingkup, dan urutan deklarasi kemudian dinilai.

@layer tokens, base, layout, components, utilities;
@layer base { #layer-target { color: #183044; } }
@layer utilities { .text-alert { color: #9d2632; } }

Tombol contoh cocok dengan kedua selektor. Untuk deklarasi biasa, layer utilities berada setelah base, jadi warna merah diterapkan. Memprediksi hasil hanya karena sebuah tombol memiliki prioritas ID tinggi bisa salah. Urutan lapisan ditentukan oleh urutan di mana nama mereka pertama kali didaftarkan, dan bahkan jika Anda membuka lapisan yang sama lagi nanti, lapisan itu tidak akan dipindahkan ke belakang.

Deklarasi !important memiliki prioritas lebih tinggi dibandingkan deklarasi umum, dan urutan lapisan untuk deklarasi penting dibalik. Deklarasi !important pada lapisan lebih awal memiliki prioritas lebih tinggi dibandingkan deklarasi !important pada lapisan lebih akhir, dan deklarasi !important di dalam lapisan memiliki prioritas lebih tinggi dibandingkan deklarasi !important di luar lapisan. Contoh ini dibatasi untuk membandingkan lapisan CSS dari penulis yang sama dan properti mereka. Ini tidak diperluas ke kondisi lain dari cascade, seperti gaya pengguna/browser, deklarasi inline, dan transisi yang berjalan, dengan mengatakan, “Anda hanya perlu melihat lapisan-lapisan tersebut.” Anda dapat memeriksa kondisi lengkapnya di dokumen lapisan MDN.

Buat file HTML dan lima file CSS

Buat struktur di bawah ini di folder kosong. Semua file disimpan sebagai UTF-8. Karena index.html menggunakan jalur relatif styles/..., file CSS harus berada di subfolder styles. Anda dapat membuka index.html dengan browser tanpa server terpisah atau pustaka eksternal. Jika Anda tidak dapat membaca file, bandingkan lokasi file dan alamat koneksi dengan Terapkan CSS dengan Gaya Inline, Internal, dan Eksternal.

stylesheet-project/
  index.html
  styles/
    tokens.css
    base.css
    layout.css
    components.css
    utilities.css

index.html berisi tag link dan kelas yang sebenarnya. Tombol perbandingan bukanlah tombol untuk menjalankan tindakan, tetapi untuk tujuan latihan untuk memeriksa warna teks yang diterapkan dan fokus.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>CSS files and layers by responsibility</title>
  <link rel="stylesheet" href="styles/tokens.css">
  <link rel="stylesheet" href="styles/base.css">
  <link rel="stylesheet" href="styles/layout.css">
  <link rel="stylesheet" href="styles/components.css">
  <link rel="stylesheet" href="styles/utilities.css">
</head>
<body>
  <main class="demo">
    <h1>Organizing a small stylesheet</h1>
    <article class="card">
      <h2>Scope nested rules to the card</h2>
      <p>The card heading uses the accent color. Compare it with the heading outside the card.</p>
      <button class="button" type="button">Regular button</button>
    </article>
    <section><h2>Heading outside the card</h2><p>Use the default font color.</p></section>
    <button id="layer-target" class="button text-alert" type="button">Layer comparison button</button>
  </main>
</body>
</html>

styles/tokens.css mendaftarkan urutan lapisan terlebih dahulu dan mendeklarasikan nilai umum. File lain membuka lapisan dengan nama yang sama untuk menambahkan aturan kepadanya.

@layer tokens, base, layout, components, utilities;
@layer tokens {
  :root { --ink: #183044; --accent: #166b92; --space-card: 1.25rem; }
}

styles/base.css menetapkan tampilan dokumen default dan indikator fokus. Aturan ID sengaja ditambahkan untuk membandingkan dampak lapisan terhadap prioritas.

@layer base {
  *, *::before, *::after { box-sizing: border-box; }
  body { margin: 0; padding: 1rem; color: var(--ink); font-family: sans-serif; line-height: 1.6; }
  h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
  button { font: inherit; cursor: pointer; }
  :focus-visible { outline: 3px solid #164f73; outline-offset: 3px; }
  #layer-target { color: #183044; }
}

styles/layout.css mengelola jarak antara area konten dan bagian.

@layer layout {
  .demo { display: grid; gap: 1rem; max-width: 44rem; margin-inline: auto; }
  .demo > h1 { margin-block: 0 .5rem; }
  .demo > button { justify-self: start; }
}

styles/components.css mengelola kartu dan tombol. Warna judul hanya berlaku di dalam kartu, dan border berubah ketika Anda mengarahkan kursor ke kartu atau memfokuskan tombol di dalamnya.

@layer components {
  .card {
    padding: var(--space-card); border: 2px solid #90a4b2; border-radius: .5rem;
    & h2 { margin-top: 0; color: var(--accent); }
    &:hover, &:focus-within { border-color: var(--accent); }
  }
  .button {
    padding: .65rem 1rem; color: var(--accent); background: #eaf4fa;
    border: 1px solid #166b92; border-radius: .3rem;
  }
}

styles/utilities.css mengelola kelas tambahan untuk tombol perbandingan. Deklarasi umum dalam file ini memiliki prioritas lebih tinggi daripada aturan ID/tombol di lapisan sebelumnya.

@layer utilities {
  .text-alert { color: #9d2632; }
}

Uji file, nesting, dan layer secara terpisah

  1. Di layar utama, pastikan judul kartu dan tombol umum berwarna biru, judul di luar kartu berwarna default, dan tombol perbandingan berwarna merah. Gunakan tombol Tab untuk melihat apakah tombol memiliki indikator fokus.
  2. Komentari hanya aturan & h2 di dalam kartu pada components.css. Judul kartu juga kembali ke warna default mereka. Setelah konfirmasi, batalkan komentar.
  3. Mari lampirkan kelas text-alert pada kedua tombol di HTML. Tombol di dalam kartu juga akan berwarna merah. Kembalikan hanya kelas tambahan tombol dalam dengan menghapusnya.
  4. Di akhir components.css, tambahkan hanya .button { color: #28633b; } di luar blok @layer. Kedua tombol akan berubah menjadi hijau. Deklarasi biasa di luar layer mengalahkan deklarasi biasa di dalam layer, sebelum spesifisitas dibandingkan. Setelah dikonfirmasi, hapus aturan baru tersebut.
  5. Tambahkan !important hanya pada deklarasi warna ID di base.css. Tombol perbandingan berubah ke warna default. Dalam keadaan itu, jika Anda menambahkan !important pada warna utilities.css, warna dasar dari lapisan sebelumnya akan dipertahankan. Setelah membandingkan, kita hapus kedua !important tersebut.
  6. Hanya sementara hapus tautan components.css dari HTML. Bentuk komponen dari kartu dan tombol menghilang. Sambungkan kembali jalurnya ke kondisi semula dan refresh untuk mengembalikannya.

Diagnosa gaya yang hilang

Periksa masalah pemisahan file dan konflik selektor secara terpisah. Pertama lihat di Network atau Sources di alat pengembang browser Anda untuk melihat apakah file benar-benar dimuat, lalu pilih elemen untuk melihat apakah aturan cocok di Styles dan apakah ada deklarasi yang telah ditimpa. Jika Anda tidak melihat file, periksa jalur relatif, nama file, dan ekstensi, dan jika Anda tidak melihat aturannya, periksa kelas dan dukungan sintaks.

Bahkan jika ada aturan yang cocok, jika terjadi coretan, bandingkan layer, !important, selektor, lingkup, dan urutan. Jika variabel umum tidak seperti yang diharapkan, juga periksa cakupan deklarasi variabel. Setelah pemisahan, sangat membantu untuk pemeliharaan dengan memeriksa ulang layar utama dan fokus/hover, serta memperbaiki pembagian tanggung jawab dan selector yang menyebabkan konflik daripada terus menambahkan deklarasi !important yang tidak perlu.