Kombinasi Pemilih & @-rule

Permasalahan

Kita sering kali perlu menggabungkan kriteria pemfilteran dari berbagai jenis, misalnya pemilih + kueri media, kueri media + kueri penampung, dan sebagainya.

Misalnya, menggabungkan (prefers-color-scheme: dark) dengan pemilih yang menargetkan penggantian skema warna (misalnya, :root:has(> head > meta[name="color-scheme"][content="dark"]) atau :root.dark) untuk menerapkan gaya tertentu dalam mode terang/gelap, terlepas dari cara skema warna ditetapkan.

Pendekatan sederhana akan menghasilkan kode duplikat:

/* Light mode styles */
.card.featured {
  font-weight: 400;
}

#logo-dark {
  display: none;
}

@media (prefers-color-scheme: dark) {
  /* Dark mode styles */
  :root:not(.light) {
    .card.featured {
      font-weight: 300;
    }

    #logo-dark {
      display: inline;
    }

    #logo {
      display: none;
    }
  }
}

/* Dark mode styles, again */
:root.dark {
  .card.featured {
    font-weight: 300;
  }

  #logo-dark {
    display: inline;
  }

  #logo {
    display: none;
  }
}

Yang harus dilakukan

Simpan hasil filter gabungan di properti kustom, lalu gunakan kueri gaya penampung untuk menetapkan aturan berdasarkan properti tersebut.

PENTING: Karena cara kerja kueri penampung, teknik ini hanya berfungsi jika kita dapat menetapkan properti kustom pada ancestor aturan apa pun yang harus dicocokkan.

1. Memisahkan logika pemilihan dari aturan yang diterapkan

:root {
  --color-scheme: light;

  @media (prefers-color-scheme: dark) {
    --color-scheme: dark;
  }

  &:has(> head > meta[name="color-scheme"][content="dark"]) {
    --color-scheme: dark;
  }

  &:has(> head > meta[name="color-scheme"][content="light"]) {
    --color-scheme: light;
  }
}

2. Kunci di properti kustom untuk aturan yang diterapkan

@container not style(--color-scheme: dark) {
  .card.featured {
    font-weight: 400;
  }

  #logo-dark {
    display: none;
  }
}

@container style(--color-scheme: dark) {
  .card.featured {
    font-weight: 300;
  }

  #logo {
    display: none;
  }
}

3. OPSIONAL: Class utilitas untuk mengalihkan visibilitas

Kasus yang sangat umum adalah mengalihkan visibilitas berdasarkan apakah kriteria cocok. Class utilitas harus lebih diutamakan daripada gaya komponen arbitrer (oleh karena itu !important) dan display yang ditampilkan tidak diketahui, sehingga tidak dapat menggunakan penggantian — batasi dengan not style(...):

@container not style(--color-scheme: dark) {
  .if-dark {
    display: none !important;
  }
}

@container not style(--color-scheme: light) {
  .if-light {
    display: none !important;
  }
}

Pengganti

Ada dua jenis penggantian, bergantung pada seberapa penting percabangan dan apa yang merupakan penggantian yang dapat diterima.

  1. Untuk percabangan penting, di mana semua status harus berfungsi dengan benar meskipun kueri gaya tidak didukung, Anda tidak dapat menggunakan kueri gaya. Sebagai gantinya, gunakan pendekatan sederhana di atas, dengan menduplikasi aturan untuk setiap negara bagian. Class utilitas masih dapat digunakan, asalkan juga ditentukan dengan cara tersebut.
  2. Untuk percabangan non-kritis, yang status default-nya dapat diterima, Anda dapat menentukan gaya dasar di luar aturan @container, dan hanya menggunakan kueri gaya sebagai pengganti. Hal ini mempertahankan sebagian besar semangat pendekatan ini, dengan kelemahan utamanya adalah penggabungan nilai yang diperkenalkan oleh penggantian.
#logo-dark {
  display: none;
}

@container style(--color-scheme: dark) {
  #logo-dark {
    display: inline; /* override */
  }

  #logo {
    display: none;
  }
}