Temui :has , Pemilih Induk CSS Asli (Dan Lainnya)

Pemilih induk telah ada di daftar keinginan pengembang selama lebih dari 10 tahun dan telah menjadi salah satu fitur CSS yang paling banyak diminta di samping kueri penampung sejak saat itu. Alasan utama fitur ini tidak diterapkan selama ini tampaknya karena masalah kinerja . Hal yang sama dikatakan tentang kueri penampung dan saat ini sedang ditambahkan ke versi beta browser, sehingga kinerja tersebut tampaknya tidak lagi menjadi masalah.

Mesin render browser telah meningkat sedikit sejak saat itu. Proses rendering telah dioptimalkan hingga browser dapat secara efektif menentukan apa yang perlu dirender atau diperbarui dan apa yang tidak, membuka jalan bagi serangkaian fitur baru dan menarik.

Brian Kandell baru-baru ini mengumumkan bahwa timnya di Igalia saat ini sedang membuat prototipe :has pemilih yang akan berfungsi sebagai pemilih induk, tetapi dapat memiliki cakupan kasus penggunaan yang jauh lebih luas di luar itu. Komunitas pengembang menyebutnya sebagai "pemilih induk" dan beberapa pengembang telah menunjukkan bahwa nama tersebut tidak terlalu akurat. Nama yang lebih cocok adalah pemilih relasional atau kelas semu relasional sesuai spesifikasi , jadi saya akan mengacu pada :has seperti itu mulai sekarang di artikel.

Tim di Igalia telah mengerjakan beberapa fitur mesin web yang terkenal seperti grid CSS dan kueri kontainer , jadi ada peluang bagi :has selector untuk melihat cahaya hari, tetapi jalan masih panjang.

Apa yang menjadikan pemilih relasional salah satu fitur yang paling banyak diminta dalam beberapa tahun terakhir dan bagaimana para pengembang mengatasi pemilih yang hilang? Dalam artikel ini, kita akan menjawab pertanyaan tersebut dan memeriksa spesifikasi awal dari :has selector dan melihat bagaimana seharusnya meningkatkan alur kerja penataan setelah dirilis.

Kasus Penggunaan Potensial

Pemilih relasional akan berguna untuk menerapkan gaya secara kondisional ke komponen UI berdasarkan konten atau status turunannya atau elemen penerusnya di pohon DOM. Prototipe pemilih relasional yang akan datang dapat memperluas jangkauan dan kasus penggunaan untuk pemilih yang ada, meningkatkan kualitas dan ketahanan CSS dan mengurangi kebutuhan untuk menggunakan JavaScript untuk menerapkan gaya dan kelas CSS untuk kasus penggunaan tersebut.

Mari kita lihat beberapa contoh spesifik untuk membantu kita mengilustrasikan berbagai kasus penggunaan potensial.

Variasi Berbasis Konten

Beberapa elemen UI dapat memiliki beberapa variasi berdasarkan berbagai aspek — konten, lokasi di halaman, status turunan, dll. Dalam kasus tersebut, kami biasanya membuat beberapa kelas CSS untuk mencakup semua kemungkinan variasi dan menerapkannya secara manual atau dengan JavaScript, tergantung pada pendekatan dan tumpukan teknologi.

Bahkan saat menggunakan metodologi penamaan CSS seperti BEM , pengembang perlu melacak berbagai kelas CSS dan memastikan untuk menerapkannya dengan benar ke elemen induk dan, secara opsional, ke elemen turunan yang terpengaruh. Bergantung pada jumlah variasi, gaya komponen dapat menjadi tidak terkendali dengan cepat dan menjadi sulit untuk dikelola dan dipelihara yang mengarah ke bug, sehingga pengembang perlu mendokumentasikan semua variasi dan kasus penggunaan dengan menggunakan alat seperti Storybook .

Dengan pemilih CSS relasional, pengembang akan dapat menulis pemeriksaan konten secara langsung di CSS dan gaya akan diterapkan secara otomatis. Ini akan mengurangi jumlah variasi kelas CSS, mengurangi kemungkinan bug yang disebabkan oleh kesalahan manusia, dan penyeleksi akan didokumentasikan sendiri dengan pemeriksaan kondisi.

Gaya Berbasis Validasi

CSS mendukung input pseudo-class seperti :valid dan :invalid untuk menargetkan elemen yang berhasil divalidasi dan elemen yang tidak berhasil divalidasi, dengan hormat. Dikombinasikan dengan atribut input HTML seperti pattern dan required , ini memungkinkan validasi formulir asli tanpa perlu bergantung pada JavaScript.

Namun, elemen penargetan dengan :valid dan :invalid terbatas pada penargetan elemen itu sendiri atau elemen yang berdekatan. Bergantung pada desain dan struktur HTML, elemen wadah masukan atau elemen sebelumnya seperti label juga memerlukan beberapa gaya untuk diterapkan.

Pemilih relasional akan memperluas kasus penggunaan untuk kelas semu status input seperti :valid dan :invalid dengan mengizinkan elemen induk atau elemen sebelumnya ditata berdasarkan validitas input.

Ini tidak hanya berlaku untuk kelas semu itu. Saat bekerja dengan API eksternal yang mengembalikan pesan kesalahan yang ditambahkan dalam wadah masukan, tidak perlu juga menerapkan kelas CSS yang sesuai ke wadah. Dengan menulis pemilih relasional dengan kondisi yang memeriksa apakah wadah pesan anak kosong, gaya yang sesuai dapat diterapkan ke wadah.

Negara Elemen Anak-anak

Terkadang elemen induk atau gaya elemen sebelumnya bergantung pada status elemen target. Kasus ini berbeda dengan status validasi karena status tidak terkait erat dengan validitas input.

Sama seperti pada contoh sebelumnya, :checked pseudo-class untuk kotak centang dan elemen input radio dibatasi untuk menargetkan elemen itu sendiri atau elemen yang berdekatan. Ini tidak terbatas pada kelas semu seperti :checked , :disabled , :hover , :visited , dll. tetapi untuk hal lain yang dapat ditargetkan oleh pemilih CSS seperti ketersediaan elemen tertentu, atribut, kelas CSS, id, dll.

Selektor relasi akan memperluas jangkauan dan kasus penggunaan pemilih CSS di luar elemen yang terpengaruh atau elemen yang berdekatan.

Memilih Saudara Sebelumnya

Pemilih CSS dibatasi oleh arah pemilihan — turunan anak atau elemen berikut dapat dipilih, tetapi bukan elemen induk atau elemen sebelumnya.

Sebuah pemilih relasional juga dapat digunakan sebagai pemilih saudara sebelumnya .

Lanjutan :empty Pemilih kosong

Saat bekerja dengan elemen yang dimuat secara dinamis dan menggunakan pemuat kerangka, adalah umum untuk mengaktifkan kelas CSS pemuatan pada elemen induk dengan JavaScript setelah data diambil dan komponen diisi dengan data.

Pemilih relasional dapat menghilangkan kebutuhan untuk fungsi sakelar kelas JavaScript CSS dengan memperluas jangkauan dan fungsionalitas kelas semu :empty Dengan pemilih relasional, kondisi yang diperlukan untuk menampilkan elemen dapat ditentukan dalam CSS dengan menargetkan elemen HTML data yang diperlukan dan memeriksa apakah elemen tersebut diisi dengan data. Pendekatan ini harus bekerja dengan elemen yang sangat bersarang dan kompleks.

CSS :has Spesifikasi Kelas Pseudo

Perlu diingat bahwa :has tidak didukung di browser apa pun sehingga cuplikan kode yang terkait dengan kelas semu yang akan datang tidak akan berfungsi. Kelas semu relasional didefinisikan dalam spesifikasi selektor level 4 yang telah diperbarui sejak rilis awal tahun 2011, sehingga spesifikasinya sudah terdefinisi dengan baik dan siap untuk pembuatan prototipe dan pengembangan.

Karena itu, mari selami :has pseudo-class. Gagasan di balik kelas semu adalah untuk menerapkan gaya ke pemilih jika kondisinya (didefinisikan sebagai pemilih CSS biasa) telah terpenuhi.

 /* Select figure elements that have a figcaption as a child element */ figure:has(figcaption) { /* ... */ } / Select button elements that have an element with .icon class as a child */ button:has(.icon) { /* ... */ } / Select article elements that have a h2 element followed by a paragraph element */ article:has(h2 + p) { /* ... */ }

Mirip dengan kelas semu lainnya seperti :not , pemilih semu relasional terdiri dari bagian-bagian berikut.

 <target_element>:has(<selector>) { /* ... */ }
  • <target_element>
    Selektor untuk elemen yang akan ditargetkan jika kondisi diteruskan sebagai argumen ke :has pseudo-class telah terpenuhi. Pemilih kondisi dicakup untuk elemen ini.
  • <selector>
    Kondisi yang ditentukan dengan pemilih CSS yang harus dipenuhi agar gaya diterapkan ke pemilih.

Seperti kebanyakan kelas semu, penyeleksi dapat dirantai untuk menargetkan elemen anak dari elemen target atau elemen yang berdekatan.

 /* Select image element that is a child of a figure element if figure element has a figcaption as a child */ figure:has(figcaption) img { /* ... */ } /* Select a button element that is a child of a form element if a child checkbox input element is checked */ form:has(input[type="checkbox"]:checked) button { /* ... */ }

Dari beberapa contoh ini, jelas betapa serbaguna, kuat, dan bergunanya pseudo-class :has Ia bahkan dapat digabungkan dengan kelas semu lainnya seperti :not untuk membuat penyeleksi relasional yang kompleks.

 /* Select card elements that do not have empty elements */ .card:not(:has(*:empty)) { /* ... */ } /* Select form element that where at least one checkbox input is not checked */ form:has(input[type="checkbox"]:not(:checked)) { /* ... */ }

Pemilih relasional tidak terbatas pada konten dan status turunan elemen target, tetapi juga dapat menargetkan elemen yang berdekatan di pohon DOM, yang secara efektif menjadikannya “pemilih saudara sebelumnya”.

 /* Select paragraph elements which is followed by an image element */ p:has(+img) { /* ... */ } /* Select image elements which is followed by figcaption element that doesn't have a "hidden" class applied */ img:has(~figcaption:not(.hidden)) { /* ... */ } /* Select label elements which are followed by an input element that is not in focus */ label:has(~input:not(:focus)) { /* ... */ }

Singkatnya, pemilih relasional mengaitkan pemilihan CSS ke elemen dengan :has kelas semu dan mencegah seleksi berpindah ke elemen yang diteruskan sebagai argumen ke kelas semu.

 .card .title .icon -> .icon element is selected .card:has(.title .icon) -> .card element is selected .image + .caption -> .caption element is selected .image:has(+.caption) -> .image element is selected

Pendekatan dan Solusi Saat Ini

Pengembang saat ini harus menggunakan berbagai solusi untuk mengkompensasi pemilih relasional yang hilang. Terlepas dari solusinya dan seperti yang dibahas dalam artikel ini, terbukti betapa berdampak dan mengubah permainan pemilih relasional setelah dirilis.

Dalam artikel ini, kita akan membahas dua pendekatan yang paling sering digunakan saat menangani kasus penggunaan di mana pemilih relasional ideal:

  • kelas variasi CSS.
  • Solusi JavaScript dan implementasi jQuery dari :has pseudo-class.

Kelas Variasi CSS Untuk Elemen Statis

Dengan kelas variasi CSS ( kelas pengubah di BEM), pengembang dapat secara manual menetapkan kelas CSS yang sesuai ke elemen berdasarkan konten elemen. Pendekatan ini berfungsi untuk elemen statis yang konten atau statusnya tidak akan berubah setelah render awal.

Mari kita lihat contoh komponen kartu berikut yang memiliki beberapa variasi tergantung isinya. Beberapa kartu tidak memiliki gambar, yang lain tidak memiliki deskripsi dan satu kartu memiliki keterangan pada gambar.

Lihat variasi Pen Card oleh Adrian Bece .

Agar kartu ini memiliki tata letak yang benar, pengembang perlu menerapkan kelas CSS pengubah yang benar secara manual. Berdasarkan desain, elemen dapat memiliki beberapa variasi yang menghasilkan sejumlah besar kelas pengubah yang terkadang mengarah ke solusi HTML kreatif untuk mengelompokkan semua kelas tersebut dalam markup. Pengembang perlu melacak kelas CSS, memelihara dokumentasi, dan memastikan untuk menerapkan kelas yang sesuai.

 .card { /* ... */} .card--news { /* ... */ } .card--text { /* ... */ } .card--featured { /* ... */ } .card__title { /* ... */ } .card__title--news { /* ... */ } .card__title--text { /* ... */ } /* ... */

Solusi JavaScript

Untuk kasus yang lebih kompleks, ketika gaya elemen induk yang diterapkan bergantung pada status anak atau konten elemen yang berubah secara dinamis, pengembang menggunakan JavaScript untuk menerapkan gaya yang diperlukan ke elemen induk bergantung pada perubahan konten atau status. Ini biasanya ditangani dengan menulis solusi khusus berdasarkan kasus per kasus.

Lihat status tombol Filter Pena oleh Adrian Bece .

Pemilih Relasional Di jQuery

Implementasi relasional :has selector telah ada di library JavaScript populer jQuery sejak 2007 dan mengikuti spesifikasi CSS. Tentu saja, batasan utama dari implementasi ini adalah bahwa baris jQuery harus dilampirkan secara manual yang dipanggil di dalam event listener, sedangkan implementasi CSS asli akan menjadi bagian dari proses render browser dan secara otomatis merespons status halaman dan perubahan konten.

Kelemahan dari pendekatan JavaScript dan jQuery, tentu saja, ketergantungan pada JavaScript dan ketergantungan perpustakaan jQuery yang dapat meningkatkan ukuran halaman keseluruhan dan waktu penguraian JavaScript. Selain itu, pengguna yang menjelajahi Web dengan JavaScript dimatikan akan mengalami bug visual jika fallback tidak diterapkan.

 // This runs only on initial render $("button:has(+.filters input:checked)").addClass("button--active"); // This runs each time input is clicked $("input").click(function() { $("button").removeClass("highlight"); $("button:has(+.filters input:checked)").addClass("highlight"); })

Lihat input Pen Email — valid / tidak valid oleh Adrian Bece .

Kesimpulan

Mirip dengan kueri kontainer, :has pseudo-class akan menjadi pengubah permainan utama saat diimplementasikan di browser. Selektor relasional akan memungkinkan pengembang untuk menulis pemilih yang kuat dan serbaguna yang saat ini tidak mungkin dilakukan dengan CSS.

Saat ini, pengembang berurusan dengan fungsionalitas pemilih induk yang hilang dengan menulis beberapa kelas CSS pengubah yang perlu diterapkan secara manual atau dengan JavaScript, jika pemilih bergantung pada status elemen anak. Pemilih relasional harus mengurangi jumlah kelas CSS pengubah dengan mengizinkan pengembang menulis penyeleksi kuat yang didokumentasikan sendiri, dan harus mengurangi kebutuhan JavaScript untuk menerapkan gaya dinamis.

Bisakah Anda memikirkan lebih banyak contoh di mana pemilih induk atau pemilih saudara sebelumnya akan berguna? Apakah Anda menggunakan solusi berbeda untuk menangani pemilih relasional yang hilang? Bagikan pemikiran Anda dengan kami di komentar.

Referensi

June 9, 2021

codeorayo

Ampuh! Ini rahasia mengembangkan aplikasi secara instan, tinggal download dan kembangkan. Gabung sekarang juga! Premium Membership [PRIVATE] https://premium.codeorayo.com

Leave a Reply

Your email address will not be published. Required fields are marked *