Diselesaikan dengan CSS: rentang kue

Bayangkan Anda memiliki komponen web yang dapat menampilkan banyak konten berbeda. Mungkin memang demikian slot Di tempat di mana komponen lain bisa disuntikkan. Komponen induk juga memiliki gayanya sendiri yang tidak ada hubungannya dengan gaya komponen konten yang dikandungnya.

Hal ini membuat situasi menjadi sulit: Bagaimana kita dapat mencegah bocornya pola komponen asli?

-Advertisement-.


Ini bukan masalah baru – Nicole Sullivan menjelaskannya pada tahun 2011! Masalah utamanya adalah penulisan CSSnya agar tidak mempengaruhi konten, dan saya telah membuatnya dengan hati-hati Kisaran donat.

“Kita memerlukan cara untuk mengetahui, tidak hanya di mana kisaran tersebut dimulai, namun juga di mana kisaran tersebut berakhir.”

Diagram yang memperlihatkan salmon persegi panjang di dalam persegi panjang merah tua lainnya. Persegi panjang yang lebih besar adalah donat dan persegi panjang yang lebih kecil adalah lubangnya.

Meskipun pelingkupan donat adalah masalah kuno di era web, jika Anda melakukan penelusuran cepat untuk “CSS Donut Scope” di mesin pencari pilihan Anda, Anda mungkin melihat dua hal:

  1. Kebanyakan dari mereka membicarakan hal-hal yang masih terkini @scope Di pangkalan.
  2. Hampir semua hasil berasal dari tahun 2021 dan seterusnya.

Kami mendapatkan hasil serupa bahkan dengan 'CSS Donut Scope' yang pintar –@scope“Menanyakan, bergerak maju dari tahun ke tahun sepertinya tidak membawa sesuatu yang baru <>Kisaran donat meja. Cakupan donat tampaknya masih ada di benak kita sebagai hal yang memusingkan bahkan untuk cakupan CSS global @scope.

Dan (spoiler!) Sementara itu @scope Aturan ini memberikan cara yang lebih mudah untuk menjangkau donat, dan saya rasa pasti ada lebih banyak solusi yang dicoba selama bertahun-tahun. Kami akan meninjaunya satu per satu, dan berhenti untuk selamanya ketika harinya tiba. @scope. Ini latihan yang bagus dalam sejarah CSS!

Ambil contoh layar permainan berikut. Kita punya .parent Item dengan grup tab dan .content slot, di mana .inventory Komponennya disuntikkan. Jika kita berubah .parent Warna, begitu juga dengan warna pada interiornya .content.

Sertakan Cadangan CodePen

Bagaimana kita dapat mencegah hal ini terjadi? Saya ingin memblokir teks di dalamnya .content Dari warisan .parentwarnanya.

Abaikan saja!

Solusi pertama bukanlah solusi sama sekali! Ini mungkin pendekatan yang paling umum digunakan karena sebagian besar pengembang dapat menjalani hidup mereka tanpa kesenangan dalam melakukan pelingkupan donat (itu gila, bukan?). Mari kita lebih konkrit di sini, ini bukan hanya tentang mengabaikan hal ini secara terang-terangan, namun menerima cakupan global CSS dan gaya penulisan dengan mempertimbangkan hal tersebut. Kembali ke contoh pertama, kami berasumsi bahwa kami tidak dapat menghentikan pola induk agar tidak bocor ke dalam komponen konten, jadi kami menulis pola induk dengan kurang spesifik, sehingga pola tersebut dapat ditimpa oleh pola konten.

body {
  color: blue;
}

.parent {
  color: orange; /* Initial background */
}

.content {
  color: blue; /* Overrides parent's background */
}
Sertakan Cadangan CodePen

Meskipun pendekatan ini sudah cukup untuk saat ini, mengelola metode hanya berdasarkan kekhususannya seiring dengan berkembangnya proyek menjadi lebih besar akan menjadi membosankan, paling banter, dan paling buruk berantakan. Komponen mungkin berperilaku berbeda tergantung di mana komponen tersebut dimasukkan, dan mengubah CSS atau HTML dapat merusak gaya lain dengan cara yang tidak terduga.

Ada dua properti CSS yang masuk ke dalam bar. Menjatuhkan kursi bar ke bar yang sama sekali berbeda.

Thomas Rubah

Anda dapat melihat bagaimana dalam contoh kecil ini kita harus mengganti gaya dua kali:

Alat pengembangan menunjukkan bahwa gaya tubuh telah disilangkan dua kali

Kisaran muffin dangkal dengan :not()

Tujuan kami hanyalah ruang lingkup saja .parentmengabaikan apa yang bisa dimasukkan ke dalamnya .content celah. Jadi tidak .content Tapi sisanya .parent…dan tidak.content… <>:not()! Kita bisa menggunakan :not() Ditentukan untuk membatasi cakupan hanya pada keturunan langsung dari .parent Ini tidak benar .content.

body {
  color: blue;
}

.parent > :not(.content) {
  color: orange;
}

seperti itu .content Gaya tidak akan diganggu oleh gaya yang ditentukan dalam filenya .parent:

Sertakan Cadangan CodePen

Anda dapat melihat perbedaan besar saat kami membuka alat pengembangan untuk setiap contoh:

Alat pengembangan yang membandingkan penggantian privasi dan domain donat

Sejauh menyangkut perbaikan, contoh terakhir ini cakupannya dangkal. Jadi, jika ada lubang lain yang bersarang lebih dalam, kita tidak akan bisa mengaksesnya kecuali kita tahu terlebih dahulu di mana lubang itu akan ditempatkan.

Sertakan Cadangan CodePen

Ini karena kita menggunakan penentu keturunan langsung (>), tetapi saya tidak dapat menemukan cara untuk membuatnya berfungsi tanpanya. Bahkan menggunakan sekumpulan penyeleksi kompleks di dalamnya :not() Tampaknya tidak membawa manfaat apa pun. Misalnya, pada tahun 2021, Dr. Leah Ferro melaporkan penggunaan donat :not() Menggunakan koktail pilihan berikut:

.container:not(.content *) {
  /* Donut Scoped styles (?) */
}

Namun, cuplikan ini sepertinya cocok .container/.parent Sebuah kelas, bukan turunannya, dan perhatikan bahwa ia masih memiliki cakupan donat yang dangkal:

Tentukan cakupan donat menggunakan @scope

Jadi langkah terakhir kita untuk menyelesaikan cakupan donat adalah kemampuan untuk melampaui satu lapisan DOM. Untungnya, tahun lalu kami mendapatkannya @scope Di bagian bawah (Anda dapat membaca lebih lanjut tentangnya di entri kalendernya). Singkatnya, ini memungkinkan kita untuk menentukan subpohon di DOM tempat gaya kita akan dicakup, sehingga tidak ada lagi cakupan global!

@scope (.parent) {
 /* Styles written here will only affect .parent */
}

Yang lebih baik lagi adalah kita dapat meninggalkan slot di dalam subpohon pilihan kita (biasanya disebut akar cakupan). Dalam hal ini, kami ingin mendesain polanya .parent Sebuah elemen tanpa menentukan cakupannya .content:

@scope (.parent) to (.content) {
  /* Styles written here will only affect .parent but skip .content*/
}

Lebih baik lagi, ia menemukan segalanya .content elemen di dalamnya .parenttidak peduli seberapa saling terkaitnya mereka. Jadi kita tidak perlu khawatir di mana kita menulis slot kita. Pada contoh terakhir, kita bisa mengetikkan gaya berikut untuk mengubah warna teks elemen di dalamnya .parent Tanpa menyentuh .content:

body {
  color: blue;
}

@scope (.parent) to (.content) {
  h2,
  p,
  span,
  a {
    color: orange;
  }
}

Meskipun tampaknya sulit untuk mencantumkan semua elemen yang akan kita ubah, kita tidak dapat menggunakan sesuatu seperti pemilih global (*) karena dapat merusak rentang slot yang tumpang tindih. Dalam contoh ini, ia akan meninggalkan sarangnya .content Di luar cakupan, tapi bukan wadahnya. sejak color Properti mewarisi, bersarang .content Warnanya akan berubah!

Dan ini dia! keduanya .content Ada lubang di dalam lubang donat jangkauan kami:

Sertakan Cadangan CodePen

Pemilihan rentang dangkal masih dimungkinkan menggunakan metode ini, kita hanya perlu menulis ulang pemilih aperture sehingga hanya perutean langsung yang dilakukan .content Keturunan .parent dikecualikan dari cakupan. Namun, kita harus menggunakannya :scope Pembatas, yang menunjukkan akar rentang, atau .parent Dalam hal ini:

@scope (.parent) to (:scope > .content) {
  * {
    color: orange;
  }
}

Kita dapat menggunakan penentu global dalam kasus ini karena cakupannya dangkal.

Termasuk cadangan CodePen

kesimpulan

Donut Scope, sebuah fitur yang diciptakan pada tahun 2011, akhirnya dihidupkan kembali pada tahun 2024. Masih membingungkan bagaimana fitur tersebut masih ada di benak kita hingga saat ini, hanya sebagai konsekuensi lain dari CSS Global Scope, padahal sebenarnya fitur tersebut ada. dari keunikan itu sendiri. Namun, tidak adil untuk mengatakan bahwa masalah ini tidak diketahui semua orang karena CSSWG (orang-orang di belakang penulisan spesifikasi untuk fitur-fitur CSS baru) mempunyai niat yang jelas untuk mengatasinya ketika menulis spesifikasi untuk @scope Di pangkalan.

Apapun masalahnya, saya bersyukur bahwa kita dapat memiliki cakupan nyata untuk donat di CSS kita. Sampai batas tertentu, kami masih harus menunggu Firefox mendukungnya. 😉

Data dukungan browser ini berasal dari Caniuse, yang berisi rincian lebih lanjut. Angka tersebut menunjukkan bahwa browser mendukung fitur tersebut pada versi ini dan yang lebih baru.

Desktop

krom Firefox setiap tepian Safari
118 TIDAK TIDAK 118 17.4

Ponsel/tablet

Android Chrome Android Firefox Android Safari iOS
131 TIDAK 131 17.4

Dipecahkan oleh CSS: Donuts Scopes awalnya diterbitkan di CSS-Tricks, yang merupakan bagian dari keluarga DigitalOcean. Anda harus mendapatkan buletin.



Sumber

-Advertisement-.

IDJ